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

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

More logging options.

  • Property svn:eol-style set to native
File size: 60.8 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 ERROR_NOT_ENOUGH_MEMORY %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 log("NdpCreateConnection open pipe\n");
754 rc = openpipe(pRes, &pConn->pipe);
755 if (rc)
756 {
757 pConn->pipe = 0;
758 break;
759 }
760
761 log("NdpCreateConnection send INIT\n");
762 req.request = SMBREQ_INIT;
763 req.param = (char *)0xFFFFFFFF;
764 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
765 if (rc || action < sizeof(resp) || resp.rc)
766 {
767 return rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
768 }
769 pConn->clientpid = resp.value & 0xFFFF;
770
771 rc = DosAllocSharedMem((PPVOID)&pConn->mem, NULL, pRes->memlen, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE | pRes->objany);
772 if (rc)
773 {
774 break;
775 }
776 rc = DosGiveSharedMem(pConn->mem, pConn->clientpid, PAG_READ | PAG_WRITE);
777 if (rc)
778 {
779 break;
780 }
781
782 log("NdpCreateConnection send CONNECT\n");
783 MemCpy(pConn->mem, &pRes->srv, sizeof(pRes->srv));
784 req.request = SMBREQ_CONNECT;
785 req.param = pConn->mem;
786 req.paramlen = sizeof(pConn->srv);
787 req.length = req.paramlen;
788
789 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
790 if (rc || action < sizeof(resp) || resp.rc)
791 {
792 rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
793 }
794 else
795 {
796 MemCpy(&pConn->srv, pConn->mem, sizeof(pConn->srv));
797 }
798 } while (0);
799 if (rc)
800 {
801 if (pConn->mem)
802 {
803 DosFreeMem(pConn->mem);
804 }
805 if (pConn->pipe)
806 {
807 DosClose(pConn->pipe);
808 }
809 MemSet(pConn, 0, sizeof(*pConn));
810 DosFreeMem(pConn);
811 pConn = NULL;
812 }
813
814 *pconn = (HCONNECTION)pConn;
815 log("NdpCreateConnection %d %d\n", rc, resp.rc);
816 return rc;
817}
818
819
820int APIENTRY NdpFreeConnection (HCONNECTION conn)
821{
822 Connection *pConn = (Connection *)conn;
823 Resource *pRes = pConn->pRes;
824
825 log("NdpFreeConnection in\n");
826 if (pConn->mem)
827 {
828 smb_request req = {0};
829 smb_response resp = {0};
830 unsigned long action;
831 if (pConn->file.fd >= 0)
832 {
833 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
834 req.request = SMBREQ_CLOSE;
835 req.param = pConn->mem;
836 req.length = sizeof(pConn->file);
837 req.paramlen = sizeof(pConn->file);
838
839 DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
840 pConn->file.fd = -1;
841 }
842
843 req.request = SMBREQ_DISCONNECT;
844 req.param = pConn->mem;
845 req.length = 0;
846 req.paramlen = 0;
847
848 DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
849
850 DosFreeMem(pConn->mem);
851 DosClose(pConn->pipe);
852 MemSet(pConn, 0, sizeof(*pConn));
853 }
854
855 DosFreeMem(pConn);
856 log("NdpFreeConnection %d\n", NO_ERROR);
857 return NO_ERROR;
858}
859
860int APIENTRY NdpRsrcCompare (HRESOURCE resource, HRESOURCE resource2)
861{
862 Resource *pRes = (Resource *)resource;
863 Resource *pRes2 = (Resource *)resource2;
864 int rc = ND_RSRC_DIFFERENT;
865
866 log("NdpRsrcCompare in\n");
867
868 if (ph->fsphStrICmp(pRes->srv.server_name, pRes2->srv.server_name) == 0
869 && ph->fsphStrICmp(pRes->srv.share_name, pRes2->srv.share_name) == 0
870 && ph->fsphStrICmp(pRes->srv.username, pRes2->srv.username) == 0
871 && ph->fsphStrICmp(pRes->srv.workgroup, pRes2->srv.workgroup) == 0)
872 {
873 // resources are equal
874 rc = ND_RSRC_EQUAL;
875 }
876
877 log("NdpRsrcCompare %d\n", rc);
878
879 return rc;
880}
881
882int APIENTRY NdpRsrcUpdate (HRESOURCE resource, HRESOURCE resource2)
883{
884 // do nothing
885 log("NdpRsrcUpdate %d\n", NO_ERROR);
886 return NO_ERROR;
887}
888
889int APIENTRY NdpRsrcQueryInfo (HRESOURCE resource, ULONG *pulFlags, void *pdata, ULONG insize, ULONG *poutlen)
890{
891 Resource *pRes = (Resource *)resource;
892 int rc = NO_ERROR;
893 char s[4096];
894
895 log("NdpRsrcQueryInfo in\n");
896
897 switch (pRes->rootlevel)
898 {
899 case 0:
900 {
901 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s \\\\@%s", ifL ? "64" : "32", pRes->srv.username);
902 } break;
903 case 1:
904 {
905 ph->fsph_snprintf(s, sizeof(s) - 1, "SMBFS%s %s: \\\\@%s", ifL ? "64" : "32", pRes->srv.workgroup, pRes->srv.username);
906 } break;
907 case 2:
908 {
909 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);
910 } break;
911 default:
912 {
913 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);
914 } break;
915 }
916 *poutlen = StrLen(s) + 1;
917 if (*poutlen > insize)
918 {
919 rc = ERROR_BUFFER_OVERFLOW;
920 }
921 else
922 {
923 MemCpy(pdata, s, *poutlen);
924 }
925
926 log("NdpRsrcQueryInfo %d\n", rc);
927
928 return rc;
929}
930
931int APIENTRY NdpRsrcQueryFSAttach (HRESOURCE resource, void *pdata, ULONG insize, ULONG *poutlen)
932{
933 ULONG ulDummy = 0;
934 /* just return the resource info string */
935 return NdpRsrcQueryInfo (resource, &ulDummy, pdata, insize, poutlen);
936}
937
938int APIENTRY NdpRsrcQueryFSAllocate (HRESOURCE resource, NDFSALLOCATE *pfsa)
939{
940 int rc = NO_ERROR, rc1;
941
942 Connection *pConn = 0;
943 smb_request req = {0};
944 smb_response resp = {0};
945 unsigned long action = 0;
946
947 log("NdpRsrcQueryFSAllocate %08x\n", pfsa);
948
949 if (!pfsa)
950 {
951 return NO_ERROR;
952 }
953
954
955 rc = NdpCreateConnection (resource, (HCONNECTION *)&pConn);
956 if (rc)
957 {
958 log("NdpCreateConnection failed rc=%d\n", rc);
959 pfsa->cSectorUnit = 1;
960 pfsa->cUnit = 123456;
961 pfsa->cUnitAvail = 123456;
962 pfsa->cbSector = 2048;
963 return rc;
964 }
965
966 MemSet(pConn->mem, 0, sizeof(FSALLOCATE));
967 req.request = SMBREQ_DSKATTR;
968 req.param = pConn->mem;
969 req.paramlen = sizeof(FSALLOCATE);
970 req.length = req.paramlen;
971
972 rc = DosTransactNPipe( pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
973 if (rc || action < sizeof(resp) || resp.rc)
974 {
975 pfsa->cSectorUnit = 1;
976 pfsa->cUnit = 123456;
977 pfsa->cUnitAvail = 123456;
978 pfsa->cbSector = 2048;
979 rc = rc ? rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
980 }
981 else
982 {
983 FSALLOCATE * fsa = (FSALLOCATE *)pConn->mem;
984 pfsa->cSectorUnit = fsa->cSectorUnit;
985 pfsa->cUnit = fsa->cUnit;
986 pfsa->cUnitAvail = fsa->cUnitAvail;
987 pfsa->cbSector = fsa->cbSector;
988 }
989
990 rc1 = NdpFreeConnection((HCONNECTION)pConn);
991
992 log("NdpRsrcQueryFSAllocate %d/%d/%d (cUnit = %d/cUnitAvail = %d/cbSector = %d)\n", rc, resp.rc, rc1, pfsa->cUnit, pfsa->cUnitAvail, pfsa->cbSector);
993 return rc;
994}
995
996int APIENTRY NdpFindStart (HCONNECTION conn, void *plist, NDFILEINFOL *pfiparent, char *szPath, ULONG ulAttribute)
997{
998 Connection *pConn = (Connection *)conn;
999 Resource *pRes = pConn->pRes;
1000 int rc = NO_ERROR, count = 0;
1001 unsigned long action;
1002 smb_request req = {0};
1003 smb_response resp = {0};
1004 char *mask = "*";
1005 char dir[CCHMAXPATH+1] = {0};
1006 char path[CCHMAXPATH+1] = {0};
1007 char fullname[CCHMAXPATH+1] = {0};
1008 smbwrp_fileinfo * data;
1009 NDPATHELEMENT *pel = ph->fsphNameElem(0);
1010
1011 log("NdpFindStart in\n");
1012 do
1013 {
1014 rc = checkconnection(pConn);
1015 if (rc)
1016 {
1017 break;
1018 }
1019
1020 StrNCpy(dir, szPath, sizeof(dir) - 1);
1021 if (pel)
1022 {
1023 mask = pel->name;
1024 dir[StrLen(szPath) - pel->length] = 0;
1025 }
1026 action = StrLen(dir) - 1;
1027 if (dir[action] == '\\')
1028 {
1029 dir[action] = 0;
1030 }
1031 rc = pathparser(pRes, pConn, dir, path);
1032 if (rc)
1033 {
1034 break;
1035 }
1036 action = StrLen(path) - 1;
1037 if (path[action] != '\\')
1038 {
1039 StrNCat(path, "\\", sizeof(path) - 1);
1040 }
1041 StrCpy(dir, path);
1042 StrNCat(path, mask, sizeof(path) - 1);
1043
1044 MemCpy(pConn->mem, &pConn->srv, sizeof(pConn->srv));
1045 StrCpy(pConn->mem + sizeof(pConn->srv), path);
1046 req.request = SMBREQ_FILELIST;
1047 req.param = pConn->mem;
1048 req.paramlen = sizeof(pConn->srv) + CCHMAXPATH + 1;
1049 req.length = pRes->memlen;
1050 data = (smbwrp_fileinfo *)(pConn->mem + sizeof(pConn->srv) + CCHMAXPATH + 1);
1051
1052 do {
1053 int i;
1054 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1055 if (pConn->rc || action < sizeof(resp)
1056 || (resp.rc && resp.rc != ERROR_MORE_DATA))
1057 {
1058 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1059 break;
1060 }
1061log("NdpFindStart %d %d %d\n", pConn->rc, resp.rc, resp.length / sizeof(smbwrp_fileinfo));
1062 if (ifL)
1063 {
1064 for (i = 0; i < resp.length / sizeof(smbwrp_fileinfo); i++)
1065 {
1066 smbwrp_fileinfo * finfo = data + i;
1067log("NdpFindStart found <%s> %d\n", finfo->fname, finfo->easize);
1068 StrCpy(fullname, dir);
1069 StrCat(fullname, finfo->fname);
1070 StrCpy(finfo->fname, fullname);
1071 count += getfindinfoL(pConn, plist, finfo, ulAttribute, mask);
1072 }
1073 }
1074 else
1075 {
1076 FILEFINDBUF3 buf = {0};
1077 for (i = 0; i < resp.length / sizeof(smbwrp_fileinfo); i++)
1078 {
1079 smbwrp_fileinfo * finfo = data + i;
1080 getfindinfo(pConn, &buf, finfo);
1081
1082 if (ph->fsphAttrMatch(ulAttribute, buf.attrFile)
1083 && ph->fsphWildMatch(mask, buf.achName, ND_IGNORE_CASE))
1084 {
1085 StrCpy(fullname, dir);
1086 StrCat(fullname, finfo->fname);
1087 StrCpy(finfo->fname, fullname);
1088 ph->fsphAddFileFind32(plist, &buf, finfo, sizeof(*finfo), 0);
1089 count++;
1090 }
1091 }
1092 }
1093 } while (resp.rc == ERROR_MORE_DATA);
1094 } while (0);
1095
1096 log("NdpFindStart <%s> (%s) cnt %d %d %d\n", szPath, path, count, rc, pConn->rc);
1097 return rc;
1098}
1099
1100int APIENTRY NdpQueryPathInfo (HCONNECTION conn, void *plist, char *szPath)
1101{
1102 Connection *pConn = (Connection *)conn;
1103 Resource *pRes = pConn->pRes;
1104 int rc = 0;
1105 unsigned long action;
1106 smb_request req = {0};
1107 smb_response resp = {0};
1108 smbwrp_fileinfo * finfo = (smbwrp_fileinfo *)pConn->mem;
1109 char path[CCHMAXPATH+1] = {0};
1110
1111 log("NdpQueryInfo in <%s>\n", szPath);
1112
1113 do {
1114 if (ph->fsphStrChr(szPath, '*') || ph->fsphStrChr(szPath, '?'))
1115 {
1116 rc = ERROR_FILE_NOT_FOUND;
1117 break;
1118 }
1119
1120 rc = checkconnection(pConn);
1121 if (rc)
1122 {
1123 break;
1124 }
1125
1126 rc = pathparser(pRes, pConn, szPath, path);
1127 switch (rc)
1128 {
1129 case NO_ERROR :
1130 case ERROR_FILE_NOT_FOUND:
1131 case ERROR_PATH_NOT_FOUND:
1132 case ERROR_ACCESS_DENIED:
1133 case ERROR_INVALID_PARAMETER:
1134 {
1135 break;
1136 }
1137 default :
1138 {
1139 rc = ERROR_PATH_NOT_FOUND;
1140 }
1141 }
1142 if (rc)
1143 {
1144 break;
1145 }
1146 StrNCpy(finfo->fname, path, sizeof(finfo->fname) - 1);
1147 req.request = SMBREQ_GETINFO;
1148 req.param = pConn->mem;
1149 req.paramlen = sizeof(*finfo);
1150 req.length = req.paramlen;
1151 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1152 if (pConn->rc || action < sizeof(resp) || resp.rc)
1153 {
1154 switch (resp.rc)
1155 {
1156 case NO_ERROR :
1157 case ERROR_FILE_NOT_FOUND:
1158 case ERROR_PATH_NOT_FOUND:
1159 case ERROR_ACCESS_DENIED:
1160 case ERROR_INVALID_PARAMETER:
1161 break;
1162 default :
1163 {
1164 resp.rc = ERROR_PATH_NOT_FOUND;
1165 }
1166 }
1167 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1168 }
1169 else
1170 {
1171 finfo->easize = -1;
1172 if (ifL)
1173 {
1174 getfindinfoL(pConn, plist, finfo, 0, NULL);
1175 }
1176 else
1177 {
1178 int trc;
1179 FILEFINDBUF3 buf = {0};
1180 getfindinfo(pConn, &buf, finfo);
1181 trc = ph->fsphAddFileFind32(plist, &buf, finfo, sizeof(*finfo), 0);
1182 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);
1183 }
1184 }
1185 if (rc == ERROR_FILE_NOT_FOUND)
1186 {
1187 // now try the upper path
1188 char * p = ph->fsphStrChr(finfo->fname, '\\');
1189 if (p && p > finfo->fname)
1190 {
1191 *p = 0;
1192 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1193 if (pConn->rc || action < sizeof(resp) || resp.rc)
1194 {
1195 rc = pConn->rc ? pConn->rc : (resp.rc ? ERROR_PATH_NOT_FOUND : ERROR_INVALID_PARAMETER);
1196 }
1197 }
1198 }
1199 } while (0);
1200
1201 log("NdpQueryInfo <%s> (%s) %d %d\n", szPath, path, rc, pConn->rc);
1202 return rc;
1203}
1204
1205int APIENTRY NdpDeletePathInfo (HRESOURCE resource, NDFILEINFOL *pfi)
1206{
1207// log("NdpDeletePathInfo %d\n", 0);
1208 return NO_ERROR;
1209}
1210
1211int APIENTRY NdpRefresh (HCONNECTION conn, char *path, int tree)
1212{
1213 log("NdpRefresh <%s> %d\n", path, 0);
1214 return NO_ERROR;
1215}
1216
1217int APIENTRY NdpDiscardResourceData (HRESOURCE resource, NDDATABUF *pdatabuf)
1218{
1219 // The plugin do not have to deallocate anything
1220 // because resource data did not contain any pointers
1221 // to plugins data.
1222 // Data stored by fsphSetResourceData will be
1223 // deallocated by NetDrive.
1224
1225 log("NdpDicardresourceData %d\n", 0);
1226 return NO_ERROR;
1227}
1228
1229int APIENTRY NdpSetPathInfo (HCONNECTION conn, NDFILEINFOL *pfi, char *szPathName)
1230{
1231 Connection *pConn = (Connection *)conn;
1232 Resource *pRes = pConn->pRes;
1233 int rc = 0;
1234 unsigned long action;
1235 smb_request req = {0};
1236 smb_response resp = {0};
1237 smbwrp_fileinfo * finfo = (smbwrp_fileinfo *)pConn->mem;
1238 char path[CCHMAXPATH+1] = {0};
1239
1240 log("NdpSetPathInfo in\n");
1241 do {
1242 rc = checkconnection(pConn);
1243 if (rc)
1244 {
1245 break;
1246 }
1247
1248 rc = pathparser(pRes, pConn, szPathName, path);
1249 if (rc)
1250 {
1251 break;
1252 }
1253
1254 MemSet(finfo, 0, sizeof(*finfo));
1255
1256 StrNCpy(finfo->fname, path, sizeof(finfo->fname) - 1);
1257 ph->fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, (unsigned long *)&(finfo->mtime));
1258 if (ifL)
1259 {
1260 finfo->attr = pfi->stat.attrFile & 0x37;
1261 }
1262 else
1263 {
1264 FILESTATUS3 * stat = (FILESTATUS3 *)&(pfi->stat);
1265 finfo->attr = stat->attrFile & 0x37;
1266 }
1267 req.request = SMBREQ_SETINFO;
1268 req.param = pConn->mem;
1269 req.paramlen = sizeof(*finfo);
1270 req.length = req.paramlen;
1271 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1272 if (pConn->rc || action < sizeof(resp) || resp.rc)
1273 {
1274 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1275 }
1276 } while (0);
1277 log("NdpSetPathInfo <%s> (%s) %d %d\n", szPathName, path, rc, pConn->rc);
1278 return rc;
1279}
1280
1281int buildFEALIST(FEALIST *pFEASrc, GEALIST *pGEAList, FEALIST *pFEAList)
1282{
1283 int rc = 0;
1284 FEA * pfea;
1285 FEA * pfeadest;
1286 unsigned long size, done = sizeof(pFEAList->cbList), dsize, ddone = sizeof(pFEAList->cbList);
1287
1288 size = pFEASrc->cbList;
1289 pfea = pFEASrc->list;
1290 pfeadest = pFEAList->list;
1291 dsize = pFEAList->cbList;
1292//log("buildFEALIST in destsize %d srcsize %d pGEAList=%08x pGEAList->cbList=%d\n", dsize, ddone, size, pGEAList, pGEAList ? pGEAList->cbList : 0);
1293 while (done < size)
1294 {
1295 char * name = (char *)(pfea + 1);
1296 int insert = 1;
1297 if (pGEAList && pGEAList->cbList > sizeof(pGEAList->cbList))
1298 {
1299 GEA * pgea = pGEAList->list;
1300 unsigned long size = pGEAList->cbList - sizeof(pGEAList->cbList), done = 0;
1301 insert = 0;
1302 while (done < size)
1303 {
1304//log("comp <%s> <%s>\n", name, pgea->szName);
1305 if (!ph->fsphStrNCmp(name, pgea->szName, pgea->cbName))
1306 {
1307 insert = 1;
1308 break;
1309 }
1310 done += pgea->cbName + 2;
1311 pgea = (GEA *)((char *)pgea + pgea->cbName + 2);
1312 }
1313 }
1314 if (insert)
1315 {
1316 ddone += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1317 if (ddone <= dsize)
1318 {
1319 pfeadest->cbName = pfea->cbName;
1320 pfeadest->cbValue = pfea->cbValue;
1321 pfeadest->fEA = 0;
1322 StrCpy((char *)(pfeadest + 1), name);
1323 MemCpy((char *)(pfeadest + 1) + pfea->cbName + 1, (char *)(pfea + 1) + pfea->cbName + 1, pfea->cbValue);
1324 pfeadest = (FEA *)((char *)pFEAList + ddone);
1325 }
1326 }
1327 done += sizeof(FEA) + pfea->cbName + 1 + pfea->cbValue;
1328//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);
1329 pfea = (FEA *)((char *)pFEASrc + done);
1330 }
1331 pFEAList->cbList = ddone;
1332 if (ddone > dsize && dsize > sizeof(pFEAList->cbList))
1333 {
1334 rc = ERROR_BUFFER_OVERFLOW;
1335 }
1336 log("buildFEALIST rc=%d destsize=%d destdone=%d srcsize=%d pGEAList=%08x\n", rc, dsize, ddone, size, pGEAList);
1337 return rc;
1338}
1339
1340int APIENTRY NdpEAQuery (HCONNECTION conn, GEALIST *pGEAList, NDFILEINFOL *pfi, FEALIST *pFEAList)
1341{
1342 Connection *pConn = (Connection *)conn;
1343 Resource *pRes = pConn->pRes;
1344 int rc = 0;
1345 unsigned long action;
1346 smb_request req = {0};
1347 smb_response resp = {0};
1348 char * path = NULL;
1349 FEALIST * pFEASrc;
1350 NDDATABUF fdata = {0};
1351 smbwrp_fileinfo *finfo;
1352
1353 if (!pfi || !pfi->pszName || !pFEAList)
1354 {
1355 return ERROR_EAS_NOT_SUPPORTED;
1356 }
1357 if (!pRes->easupport)
1358 {
1359 return ERROR_EAS_NOT_SUPPORTED;
1360 }
1361
1362 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1363 if (rc || !fdata.ulSize || !fdata.pData)
1364 {
1365 log("NdpEAQuery: ph->fsphGetFileInfoData = %d/%d %08x\n", rc, fdata.ulSize, fdata.pData);
1366 return ERROR_EAS_NOT_SUPPORTED;
1367 }
1368 finfo = (smbwrp_fileinfo *)fdata.pData;
1369 path = finfo->fname;
1370
1371 log("NdpEAQuery in <%s> %08x %d\n", path, pGEAList, pGEAList ? pGEAList->cbList : 0);
1372 do {
1373 rc = checkconnection(pConn);
1374 if (rc)
1375 {
1376 break;
1377 }
1378
1379 StrNCpy(pConn->mem, path, CCHMAXPATH);
1380 req.request = SMBREQ_LISTEA;
1381 req.param = pConn->mem;
1382 req.paramlen = CCHMAXPATH + 1;
1383 req.length = pRes->memlen - req.paramlen;
1384 pFEASrc = (FEALIST *)(pConn->mem + req.paramlen);
1385 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1386 if (pConn->rc || action < sizeof(resp) || resp.rc)
1387 {
1388 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1389 switch (rc)
1390 {
1391 case ERROR_FILE_NOT_FOUND :
1392 case ERROR_PATH_NOT_FOUND :
1393 {
1394 pFEAList->cbList = sizeof(pFEAList->cbList);
1395 rc = NO_ERROR;
1396 } break;
1397 case ERROR_BUFFER_OVERFLOW :
1398 {
1399 pFEAList->cbList = pFEASrc->cbList;
1400 } break;
1401 default :
1402 {
1403 rc = ERROR_EAS_NOT_SUPPORTED;
1404 }
1405 }
1406 }
1407 else
1408 {
1409 rc = buildFEALIST(pFEASrc, pGEAList, pFEAList);
1410 }
1411 } while (0);
1412 log("NdpEAQuery <%s> %d %d %d %d %d\n", pfi->pszName, rc, pFEASrc->cbList, pFEAList->cbList, pConn->rc, resp.rc);
1413 return rc;
1414}
1415
1416int APIENTRY NdpEASet (HCONNECTION conn, FEALIST *pFEAList, NDFILEINFOL *pfi)
1417{
1418 Connection *pConn = (Connection *)conn;
1419 Resource *pRes = pConn->pRes;
1420 int rc = 0;
1421 smb_request req = {0};
1422 smb_response resp = {0};
1423 char * path;
1424 unsigned long action;
1425 NDDATABUF fdata = {0};
1426 smbwrp_fileinfo *finfo;
1427
1428 log("NdpEASet in\n");
1429
1430 if (!pfi || !pfi->pszName || !pFEAList || pFEAList->cbList <= sizeof(long))
1431 {
1432 return ERROR_EAS_NOT_SUPPORTED;
1433 }
1434 if (!pRes->easupport)
1435 {
1436 return ERROR_EAS_NOT_SUPPORTED;
1437 }
1438
1439 if (pFEAList->cbList > pRes->memlen)
1440 {
1441 return ERROR_NOT_ENOUGH_MEMORY;
1442 }
1443
1444 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1445 if (rc || !fdata.ulSize || !fdata.pData)
1446 {
1447 log("NdpEASet: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData);
1448 return ERROR_EAS_NOT_SUPPORTED;
1449 }
1450 finfo = (smbwrp_fileinfo *)fdata.pData;
1451 path = finfo->fname;
1452
1453 do {
1454 rc = checkconnection(pConn);
1455 if (rc)
1456 {
1457 break;
1458 }
1459
1460 StrNCpy(pConn->mem, path, CCHMAXPATH);
1461 MemCpy(pConn->mem + CCHMAXPATH + 1, pFEAList, pFEAList->cbList);
1462 req.request = SMBREQ_SETEA;
1463 req.param = pConn->mem;
1464 req.paramlen = pFEAList->cbList + CCHMAXPATH + 1;
1465 req.length = req.paramlen;
1466 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1467 if (pConn->rc || action < sizeof(resp) || resp.rc)
1468 {
1469 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1470 }
1471 } while (0);
1472 log("NdpEASet %d\n", rc);
1473 return rc;
1474}
1475
1476int APIENTRY NdpEASize (HCONNECTION conn, NDFILEINFOL *pfi, ULONG *pulEASize)
1477{
1478 Connection *pConn = (Connection *)conn;
1479 Resource *pRes = pConn->pRes;
1480 int rc = 0;
1481 unsigned long action;
1482 smb_request req = {0};
1483 smb_response resp = {0};
1484 char * path = NULL;
1485 FEALIST * pfealist;
1486 NDDATABUF fdata = {0};
1487 smbwrp_fileinfo *finfo;
1488 int easize;
1489
1490 if (!pfi || !pulEASize)
1491 {
1492 return ERROR_EAS_NOT_SUPPORTED;
1493 }
1494 if (!pRes->easupport)
1495 {
1496 return ERROR_EAS_NOT_SUPPORTED;
1497 }
1498
1499 rc = ph->fsphGetFileInfoData(pfi, &fdata, 0);
1500 if (rc || !fdata.ulSize || !fdata.pData)
1501 {
1502 log("NdpEASize: ph->fsphGetFileInfoData = %d/%d/%08x\n", rc, fdata.ulSize, fdata.pData);
1503 return ERROR_EAS_NOT_SUPPORTED;
1504 }
1505 finfo = (smbwrp_fileinfo *)fdata.pData;
1506 easize = finfo->easize;
1507 finfo->easize = -1;
1508 path = finfo->fname;
1509 if (easize >= 0)
1510 {
1511 *pulEASize = easize;
1512 log("NdpEASize <%s> cached %d\n", path, easize);
1513 return NO_ERROR;
1514 }
1515
1516 log("NdpEASize in <%s> \n", path);
1517 do {
1518 rc = checkconnection(pConn);
1519 if (rc)
1520 {
1521 break;
1522 }
1523
1524 StrNCpy(pConn->mem, path, CCHMAXPATH);
1525 req.request = SMBREQ_LISTEA;
1526 req.param = pConn->mem;
1527 req.paramlen = CCHMAXPATH + 1;
1528 req.length = pRes->memlen - req.paramlen;
1529 pfealist = (FEALIST *)(pConn->mem + req.paramlen);
1530 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1531 if (pConn->rc || action < sizeof(resp) || resp.rc)
1532 {
1533 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1534 switch (rc)
1535 {
1536 case ERROR_FILE_NOT_FOUND :
1537 case ERROR_PATH_NOT_FOUND :
1538 {
1539 pfealist->cbList = sizeof(pfealist->cbList);
1540 } /* Fall through */
1541 case ERROR_BUFFER_OVERFLOW :
1542 {
1543 rc = NO_ERROR;
1544 } break;
1545 default :
1546 {
1547 rc = ERROR_EAS_NOT_SUPPORTED;
1548 }
1549 }
1550 }
1551 *pulEASize = pfealist->cbList;
1552 } while (0);
1553 log("NdpEASize <%s> %d %d %d %d\n", pfi->pszName, *pulEASize, rc, pConn->rc, resp.rc);
1554 return rc;
1555}
1556
1557int APIENTRY NdpSetCurrentDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szPath)
1558{
1559 Connection *pConn = (Connection *)conn;
1560 Resource *pRes = pConn->pRes;
1561 smb_request req = {0};
1562 smb_response resp = {0};
1563 int rc = 0;
1564 unsigned long action;
1565 char path[CCHMAXPATH+1] = {0};
1566
1567 log("NdpSetCurrentDir in\n");
1568 do {
1569 rc = checkconnection(pConn);
1570 if (rc)
1571 {
1572 break;
1573 }
1574
1575 rc = pathparser(pRes, pConn, szPath, path);
1576 if (rc)
1577 {
1578 break;
1579 }
1580
1581 StrNCpy(pConn->mem, path, CCHMAXPATH);
1582 req.request = SMBREQ_CHDIR;
1583 req.param = pConn->mem;
1584 req.paramlen = CCHMAXPATH + 1;
1585 req.length = req.paramlen;
1586 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1587 if (pConn->rc || action < sizeof(resp) || resp.rc)
1588 {
1589 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1590 }
1591 } while (0);
1592 log("NdpSetCurrentDir <%s> (%s) %d %d\n", szPath, path, rc, pConn->rc);
1593 return rc;
1594}
1595
1596int APIENTRY NdpCopy (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
1597{
1598 log("NdpCopy <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
1599 return ERROR_CANNOT_COPY;
1600}
1601
1602int APIENTRY NdpCopy2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, ULONG ulOption)
1603{
1604 log("NdpCopy2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_CANNOT_COPY);
1605 return ERROR_CANNOT_COPY;
1606}
1607
1608int APIENTRY NdpForceDelete (HCONNECTION conn, NDFILEINFOL *pfi, char *szFile)
1609{
1610 Connection *pConn = (Connection *)conn;
1611 Resource *pRes = pConn->pRes;
1612 smb_request req = {0};
1613 smb_response resp = {0};
1614 int rc = 0;
1615 unsigned long action;
1616 char path[CCHMAXPATH+1] = {0};
1617
1618 log("NdpForceDelete in\n");
1619 do {
1620 rc = checkconnection(pConn);
1621 if (rc)
1622 {
1623 break;
1624 }
1625
1626 rc = pathparser(pRes, pConn, szFile, path);
1627 if (rc)
1628 {
1629 break;
1630 }
1631
1632 StrNCpy(pConn->mem, path, CCHMAXPATH);
1633 req.request = SMBREQ_UNLINK;
1634 req.param = pConn->mem;
1635 req.paramlen = CCHMAXPATH + 1;
1636 req.length = req.paramlen;
1637 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1638 if (pConn->rc || action < sizeof(resp) || resp.rc)
1639 {
1640 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1641 }
1642 } while (0);
1643 log("NdpForceDelete <%s> (%s) %d %d\n", szFile, path, rc, pConn->rc);
1644 return rc;
1645}
1646
1647int APIENTRY NdpCreateDir (HCONNECTION conn, NDFILEINFOL *pfiparent, char *szDirName, FEALIST *pFEAList)
1648{
1649 Connection *pConn = (Connection *)conn;
1650 Resource *pRes = pConn->pRes;
1651 smb_request req = {0};
1652 smb_response resp = {0};
1653 int rc = 0;
1654 unsigned long action;
1655 char path[CCHMAXPATH+1] = {0};
1656
1657 log("NdpCreateDir in\n");
1658 do {
1659 rc = checkconnection(pConn);
1660 if (rc)
1661 {
1662 break;
1663 }
1664
1665 rc = pathparser(pRes, pConn, szDirName, path);
1666 if (rc)
1667 {
1668 break;
1669 }
1670
1671 StrNCpy(pConn->mem, path, CCHMAXPATH);
1672 req.request = SMBREQ_MKDIR;
1673 req.param = pConn->mem;
1674 req.paramlen = CCHMAXPATH + 1;
1675 req.length = req.paramlen;
1676 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1677 if (pConn->rc || action < sizeof(resp) || resp.rc)
1678 {
1679 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1680 }
1681 } while (0);
1682 log("NdpCreateDir <%s> (%s) %d %d\n", szDirName, path, rc, pConn->rc);
1683 return rc;
1684}
1685
1686int APIENTRY NdpDeleteDir (HCONNECTION conn, NDFILEINFOL *pfi, char *szDir)
1687{
1688 Connection *pConn = (Connection *)conn;
1689 Resource *pRes = pConn->pRes;
1690 smb_request req = {0};
1691 smb_response resp = {0};
1692 int rc = 0;
1693 unsigned long action;
1694 char path[CCHMAXPATH+1] = {0};
1695
1696 log("NdpDeleteDir in\n");
1697 do {
1698 rc = checkconnection(pConn);
1699 if (rc)
1700 {
1701 break;
1702 }
1703
1704 rc = pathparser(pRes, pConn, szDir, path);
1705 if (rc)
1706 {
1707 break;
1708 }
1709
1710 StrNCpy(pConn->mem, path, CCHMAXPATH);
1711 req.request = SMBREQ_RMDIR;
1712 req.param = pConn->mem;
1713 req.paramlen = CCHMAXPATH + 1;
1714 req.length = req.paramlen;
1715 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1716 if (pConn->rc || action < sizeof(resp) || resp.rc)
1717 {
1718 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1719 }
1720 } while (0);
1721 log("NdpDeleteDir <%s> (%s) %d %d\n", szDir, path, rc, pConn->rc);
1722 return rc;
1723}
1724
1725int APIENTRY NdpMove (HCONNECTION conn, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
1726{
1727 Connection *pConn = (Connection *)conn;
1728 Resource *pRes = pConn->pRes;
1729 smb_request req = {0};
1730 smb_response resp = {0};
1731 int rc = 0;
1732 unsigned long action;
1733 char src[CCHMAXPATH+1] = {0};
1734 int l1, l2;
1735 char * p = szDst;
1736
1737 log("NdpMove in\n");
1738 do
1739 {
1740 rc = checkconnection(pConn);
1741 if (rc)
1742 {
1743 break;
1744 }
1745
1746 rc = pathparser(pRes, pConn, szSrc, src);
1747 if (rc)
1748 {
1749 break;
1750 }
1751 l1 = StrLen(szSrc);
1752 l2 = StrLen(src);
1753 if (l1 > l2)
1754 {
1755 if (ph->fsphStrNICmp(szSrc, szDst, l1 - l2))
1756 {
1757 // the file moved accross different shares or servers or workgroups
1758 rc = ERROR_WRITE_PROTECT;
1759 break;
1760 }
1761 p = szDst + l1 - l2 + 1;
1762 }
1763 StrNCpy(pConn->mem, src, CCHMAXPATH);
1764 pConn->mem[CCHMAXPATH + 1] = '\\';
1765 StrNCpy(pConn->mem + CCHMAXPATH + 2, p, CCHMAXPATH - 1);
1766 req.request = SMBREQ_RENAME;
1767 req.param = pConn->mem;
1768 req.paramlen = 2 * (CCHMAXPATH + 1);
1769 req.length = req.paramlen;
1770 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1771 if (pConn->rc || action < sizeof(resp) || resp.rc)
1772 {
1773 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1774 }
1775 } while (0);
1776 log("NdpMove <%s> -> <%s> (%s) %d %d\n", szSrc, szDst, src, rc, pConn->rc);
1777
1778 return rc;
1779}
1780
1781int APIENTRY NdpMove2 (HCONNECTION conn, HRESOURCE resDst, NDFILEINFOL *pfiDst, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc)
1782{
1783 log("NdpMove2 <%s> -> <%s> %d\n", szSrc, szDst, ERROR_WRITE_PROTECT);
1784 return ERROR_WRITE_PROTECT;
1785}
1786
1787
1788int APIENTRY NdpChangeCase (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
1789{
1790 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
1791}
1792
1793int APIENTRY NdpRename (HCONNECTION conn, char *szDst, NDFILEINFOL *pfiSrc, char *szSrc, char *szNewName, ULONG ulNameLen)
1794{
1795 return NdpMove (conn, pfiSrc, szDst, pfiSrc, szSrc);
1796}
1797
1798int smbopen(Connection *pConn, char *szFileName, int flags, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1799{
1800 Resource *pRes = pConn->pRes;
1801 smb_request req = {0};
1802 smb_response resp = {0};
1803 unsigned long action;
1804 int rc = 0;
1805 char path[CCHMAXPATH+1] = {0};
1806
1807 log("smbopen in %d\n", pConn->file.fd);
1808 do {
1809 if (pConn->file.fd > 0)
1810 {
1811 rc = ERROR_TOO_MANY_OPEN_FILES;
1812 break;
1813 }
1814
1815 rc = checkconnection(pConn);
1816 if (rc)
1817 {
1818 break;
1819 }
1820
1821 rc = pathparser(pRes, pConn, szFileName, path);
1822 if (rc)
1823 {
1824 break;
1825 }
1826
1827 StrNCpy(pConn->file.fullname, szFileName, sizeof(pConn->file.fullname) - 1);
1828 StrNCpy(pConn->file.fname, path, sizeof(pConn->file.fname) - 1);
1829 flags |= O_BINARY;
1830 switch (ulOpenMode & 3)
1831 {
1832 case OPEN_ACCESS_READONLY : flags |= O_RDONLY; break;
1833 case OPEN_ACCESS_WRITEONLY : flags |= O_WRONLY; break;
1834 case OPEN_ACCESS_READWRITE : flags |= O_RDWR; break;
1835 default : flags |= O_RDWR;
1836 }
1837 pConn->file.openmode = flags;
1838 pConn->file.openattr = ulAttribute & 0x37;
1839 pConn->file.denymode = (ulOpenMode & 0x70) >> 4;
1840 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
1841 req.request = SMBREQ_OPEN;
1842 req.param = pConn->mem;
1843 req.paramlen = sizeof(pConn->file);
1844 req.length = req.paramlen;
1845 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1846 if (pConn->rc || action < sizeof(resp) || resp.rc)
1847 {
1848 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1849 }
1850 else
1851 {
1852 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
1853 }
1854 } while (0);
1855 log("smbopen <%s> (%s) %08x %08x %08x %d %d. file = %d\n", szFileName, path, flags, ulOpenMode, ulAttribute, rc, pConn->rc, pConn->file.fd);
1856 if (!rc && pFEAList)
1857 {
1858 int rc1 = NdpFileEASet((HCONNECTION)pConn, (NDFILEHANDLE)0, pFEAList);
1859 log("smbopen NdpFileEASet %d. pFEAList->cbList %d\n", rc1, pFEAList->cbList);
1860 }
1861
1862 return rc;
1863}
1864
1865int APIENTRY NdpOpenReplace (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1866{
1867 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
1868}
1869
1870int APIENTRY NdpOpenReplaceL(HCONNECTION conn, NDFILEINFO *pfi, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1871{
1872 return smbopen((Connection *)conn, szFileName, O_TRUNC, ulOpenMode, ulAttribute, pFEAList);
1873}
1874
1875int APIENTRY NdpOpenCreate (HCONNECTION conn, NDFILEINFOL *pfiparent, NDFILEHANDLE *phandle, char *szFileName, ULONG ulSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1876{
1877// return smbopen((Connection *)conn, szFileName, O_CREAT, ulOpenMode, ulAttribute);
1878 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);
1879}
1880
1881int APIENTRY NdpOpenCreateL(HCONNECTION conn, NDFILEINFO *pfiparent, NDFILEHANDLE *phandle, char *szFileName, LONGLONG llSize, ULONG ulOpenMode, ULONG ulAttribute, FEALIST *pFEAList)
1882{
1883 return smbopen((Connection *)conn, szFileName, O_CREAT | O_EXCL, ulOpenMode, ulAttribute, pFEAList);
1884}
1885
1886int APIENTRY NdpOpenExisting (HCONNECTION conn, NDFILEINFOL *pfi, NDFILEHANDLE *phandle, char *szFileName, ULONG ulOpenMode, USHORT *pfNeedEA)
1887{
1888 if (pfNeedEA) *pfNeedEA = 0; // wtf is this ?
1889 return smbopen((Connection *)conn, szFileName, 0, ulOpenMode, 0, NULL);
1890}
1891
1892int APIENTRY NdpSetFileAttribute (HCONNECTION conn, NDFILEINFOL *pfi, char *szFileName, USHORT usAttr)
1893{
1894 Connection *pConn = (Connection *)conn;
1895 Resource *pRes = pConn->pRes;
1896 int rc = 0;
1897 unsigned long action;
1898 smb_request req = {0};
1899 smb_response resp = {0};
1900 smbwrp_fileinfo * finfo = (smbwrp_fileinfo *)pConn->mem;
1901 char path[CCHMAXPATH+1] = {0};
1902
1903 log("NdpSetFileAttribute in\n");
1904 do {
1905 rc = checkconnection(pConn);
1906 if (rc)
1907 {
1908 break;
1909 }
1910
1911 rc = pathparser(pRes, pConn, szFileName, path);
1912 if (rc)
1913 {
1914 break;
1915 }
1916
1917 MemSet(finfo, 0, sizeof(*finfo));
1918
1919 StrNCpy(finfo->fname, path, sizeof(finfo->fname) - 1);
1920 finfo->attr = usAttr & 0x37;
1921 req.request = SMBREQ_SETINFO;
1922 req.param = pConn->mem;
1923 req.paramlen = sizeof(*finfo);
1924 req.length = req.paramlen;
1925 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1926 if (pConn->rc || action < sizeof(resp) || resp.rc)
1927 {
1928 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1929 }
1930 } while (0);
1931 log("NdpSetFileAttribute <%s> (%s) %04x %d %d\n", szFileName, path, usAttr, rc, pConn->rc);
1932 return rc;
1933}
1934
1935int APIENTRY NdpFlush (HRESOURCE resource)
1936{
1937 log("NdpFlush %d\n", ERROR_NOT_SUPPORTED);
1938 return ERROR_NOT_SUPPORTED;
1939}
1940
1941int APIENTRY NdpIOCTL (int type, HRESOURCE resource, char *path, int function, void *in, ULONG insize, PULONG poutlen)
1942{
1943 log("NdpIOCTL <%s> %d %d\n", path, function, ERROR_NOT_SUPPORTED);
1944 return ERROR_NOT_SUPPORTED;
1945}
1946
1947int APIENTRY NdpFileQueryInfo (HCONNECTION conn, NDFILEHANDLE handle, void *plist)
1948{
1949 Connection *pConn = (Connection *)conn;
1950 Resource *pRes = pConn->pRes;
1951 int rc = 0;
1952 unsigned long action;
1953 smb_request req = {0};
1954 smb_response resp = {0};
1955 FILEFINDBUF3 buf;
1956 smbwrp_fileinfo * finfo = (smbwrp_fileinfo *)(pConn->mem + sizeof(pConn->file));
1957
1958 log("NdpFileQueryInfo in\n");
1959 do {
1960 if (pConn->file.fd < 0 || !*pConn->file.fname)
1961 {
1962 rc = ERROR_INVALID_HANDLE;
1963 break;
1964 }
1965 if (pConn->rc)
1966 {
1967 rc = ERROR_PIPE_NOT_CONNECTED;
1968 break;
1969 }
1970
1971 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
1972 StrNCpy(finfo->fname, pConn->file.fname, sizeof(finfo->fname) - 1);
1973 req.request = SMBREQ_FGETINFO;
1974 req.param = pConn->mem;
1975 req.paramlen = sizeof(pConn->file);
1976 req.length = req.paramlen + sizeof(*finfo);
1977 rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
1978 if (pConn->rc || action < sizeof(resp) || resp.rc)
1979 {
1980 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
1981 }
1982 else
1983 {
1984 finfo->easize = -1;
1985 if (ifL)
1986 {
1987 getfindinfoL(pConn, plist, finfo, 0, NULL);
1988 }
1989 else
1990 {
1991 getfindinfo(pConn, &buf, finfo);
1992 ph->fsphAddFileFind32(plist, &buf, finfo, sizeof(*finfo), 0);
1993 }
1994 }
1995 } while (0);
1996 log("NdpFileQueryInfo <%s> %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, rc, pConn->rc);
1997
1998 return rc;
1999}
2000
2001int APIENTRY NdpFileEAQuery (HCONNECTION conn, NDFILEHANDLE handle, GEALIST *pGEAList, FEALIST *pFEAList)
2002{
2003 Connection *pConn = (Connection *)conn;
2004 Resource *pRes = pConn->pRes;
2005 int rc = 0;
2006 unsigned long action;
2007 smb_request req = {0};
2008 smb_response resp = {0};
2009 FEALIST * pFEASrc;
2010
2011 if (!pFEAList)
2012 {
2013 return ERROR_EAS_NOT_SUPPORTED;
2014 }
2015 if (!pRes->easupport)
2016 {
2017 return ERROR_EAS_NOT_SUPPORTED;
2018 }
2019
2020 log("NdpFileEAQuery in <%s>/%d pGEAList=%08x\n", pConn->file.fname, pConn->file.fd, pGEAList);
2021 do {
2022 if (pConn->file.fd < 0)
2023 {
2024 rc = ERROR_INVALID_HANDLE;
2025 break;
2026 }
2027 if (pConn->rc)
2028 {
2029 rc = ERROR_PIPE_NOT_CONNECTED;
2030 break;
2031 }
2032
2033 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2034 req.request = SMBREQ_FLISTEA;
2035 req.param = pConn->mem;
2036 req.paramlen = sizeof(pConn->file);
2037 req.length = pRes->memlen - req.paramlen;
2038 pFEASrc = (FEALIST *)(pConn->mem + req.paramlen);
2039 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2040 if (pConn->rc || action < sizeof(resp) || resp.rc)
2041 {
2042 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2043 switch (rc)
2044 {
2045 case ERROR_FILE_NOT_FOUND :
2046 case ERROR_PATH_NOT_FOUND :
2047 {
2048 pFEAList->cbList = sizeof(pFEAList->cbList);
2049 rc = NO_ERROR;
2050 } break;
2051 case ERROR_BUFFER_OVERFLOW :
2052 {
2053 pFEAList->cbList = pFEASrc->cbList;
2054 } break;
2055 default :
2056 {
2057 rc = ERROR_EAS_NOT_SUPPORTED;
2058 }
2059 }
2060 }
2061 else
2062 {
2063 rc = buildFEALIST(pFEASrc, pGEAList, pFEAList);
2064 }
2065 } while (0);
2066 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);
2067 return rc;
2068}
2069
2070int APIENTRY NdpFileEASet (HCONNECTION conn, NDFILEHANDLE handle, FEALIST *pFEAList)
2071{
2072 Connection *pConn = (Connection *)conn;
2073 Resource *pRes = pConn->pRes;
2074 int rc = 0;
2075 smb_request req = {0};
2076 smb_response resp = {0};
2077 unsigned long action;
2078
2079 log("NdpFileEASet in\n");
2080
2081 if (!pFEAList || pFEAList->cbList <= sizeof(long))
2082 {
2083 return ERROR_EAS_NOT_SUPPORTED;
2084 }
2085 if (!pRes->easupport)
2086 {
2087 return ERROR_EAS_NOT_SUPPORTED;
2088 }
2089 if (pFEAList->cbList > pRes->memlen)
2090 {
2091 return ERROR_NOT_ENOUGH_MEMORY;
2092 }
2093
2094 do {
2095 if (pConn->file.fd < 0)
2096 {
2097 rc = ERROR_INVALID_HANDLE;
2098 break;
2099 }
2100 if (pConn->rc)
2101 {
2102 rc = ERROR_PIPE_NOT_CONNECTED;
2103 break;
2104 }
2105
2106 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2107 MemCpy(pConn->mem + sizeof(pConn->file), pFEAList, pFEAList->cbList);
2108 req.request = SMBREQ_FSETEA;
2109 req.param = pConn->mem;
2110 req.paramlen = pFEAList->cbList + sizeof(pConn->file);
2111 req.length = req.paramlen;
2112
2113 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2114 if (pConn->rc || action < sizeof(resp) || resp.rc)
2115 {
2116 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2117 }
2118 } while (0);
2119 log("NdpFileEASet %d\n", rc);
2120 return rc;
2121}
2122
2123int APIENTRY NdpFileEASize (HCONNECTION conn, NDFILEHANDLE handle, ULONG *pulEASize)
2124{
2125 Connection *pConn = (Connection *)conn;
2126 Resource *pRes = pConn->pRes;
2127 int rc = 0;
2128 unsigned long action;
2129 smb_request req = {0};
2130 smb_response resp = {0};
2131 char path[CCHMAXPATH+1] = {0};
2132 FEALIST * pfealist;
2133
2134 if (!pulEASize)
2135 {
2136 return ERROR_EAS_NOT_SUPPORTED;
2137 }
2138 if (!pRes->easupport)
2139 {
2140 return ERROR_EAS_NOT_SUPPORTED;
2141 }
2142
2143 log("NdpFileEASize in <%s>/%d \n", pConn->file.fname, pConn->file.fd);
2144 do {
2145 if (pConn->file.fd < 0)
2146 {
2147 rc = ERROR_INVALID_HANDLE;
2148 break;
2149 }
2150 if (pConn->rc)
2151 {
2152 rc = ERROR_PIPE_NOT_CONNECTED;
2153 break;
2154 }
2155
2156 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2157 req.request = SMBREQ_FLISTEA;
2158 req.param = pConn->mem;
2159 req.paramlen = sizeof(pConn->file);
2160 req.length = pRes->memlen - req.paramlen;
2161 pfealist = (FEALIST *)(pConn->mem + req.paramlen);
2162 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2163 if (pConn->rc || action < sizeof(resp) || resp.rc)
2164 {
2165 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2166 switch (rc)
2167 {
2168 case ERROR_FILE_NOT_FOUND :
2169 case ERROR_PATH_NOT_FOUND :
2170 {
2171 pfealist->cbList = sizeof(pfealist->cbList);
2172 } /* Fall through */
2173 case ERROR_BUFFER_OVERFLOW :
2174 {
2175 rc = NO_ERROR;
2176 } break;
2177 default :
2178 {
2179 rc = ERROR_EAS_NOT_SUPPORTED;
2180 }
2181 }
2182 }
2183 *pulEASize = pfealist->cbList;
2184 } while (0);
2185 log("NdpFileEASize %d %d %d %d\n", *pulEASize, rc, pConn->rc, resp.rc);
2186 return rc;
2187}
2188
2189int APIENTRY NdpFileSetInfo (HCONNECTION conn, NDFILEHANDLE handle, NDFILEINFOL *pfi)
2190{
2191 Connection *pConn = (Connection *)conn;
2192 Resource *pRes = pConn->pRes;
2193 int rc = 0;
2194 unsigned long action, attrFile;
2195 smb_request req = {0};
2196 smb_response resp = {0};
2197 smbwrp_fileinfo * finfo = (smbwrp_fileinfo *)pConn->mem;
2198
2199 log("NdpFileSetInfo in\n");
2200 do {
2201 if (pConn->file.fd < 0 || !*pConn->file.fname)
2202 {
2203 rc = ERROR_INVALID_HANDLE;
2204 break;
2205 }
2206 if (pConn->rc)
2207 {
2208 rc = ERROR_PIPE_NOT_CONNECTED;
2209 break;
2210 }
2211 if (ifL)
2212 {
2213 attrFile = pfi->stat.attrFile;
2214 }
2215 else
2216 {
2217 FILESTATUS3 * stat = (FILESTATUS3 *)&(pfi->stat);
2218 attrFile = stat->attrFile;
2219 }
2220 // deferred setinfo - on closing the file
2221 pConn->file.openattr = attrFile;
2222 ph->fsphDosDateToUnixTime(pfi->stat.fdateLastWrite, pfi->stat.ftimeLastWrite, (unsigned long *)&(pConn->file.mtime));
2223 } while (0);
2224 log("NdpFileSetInfo <%s> %08x %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, attrFile, rc, pConn->rc);
2225 return NO_ERROR;
2226}
2227
2228int APIENTRY NdpFileSetFilePtrL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llOffset, ULONG ulMethod, LONGLONG *pllActual)
2229{
2230 Connection *pConn = (Connection *)conn;
2231 Resource *pRes = pConn->pRes;
2232 int rc = 0;
2233 unsigned long action;
2234 smb_request req = {0};
2235 smb_response resp = {0};
2236
2237 log("NdpFileSetFilePtrl in\n");
2238 do {
2239 if (pConn->file.fd < 0)
2240 {
2241 rc = ERROR_INVALID_HANDLE;
2242 break;
2243 }
2244 if (pConn->rc)
2245 {
2246 rc = ERROR_PIPE_NOT_CONNECTED;
2247 break;
2248 }
2249
2250 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2251 *(unsigned long *)(pConn->mem + sizeof(pConn->file)) = ulMethod;
2252 *(long long *)(pConn->mem + sizeof(pConn->file) + sizeof(long)) = llOffset;
2253 req.request = SMBREQ_LSEEK;
2254 req.param = pConn->mem;
2255 req.paramlen = sizeof(pConn->file) + sizeof(long) + sizeof(long long);
2256 req.length = req.paramlen;
2257 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2258 if (pConn->rc || action < sizeof(resp) || resp.rc)
2259 {
2260 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2261 }
2262 else
2263 {
2264 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
2265 *pllActual = pConn->file.offset;
2266 }
2267 } while (0);
2268 log("NdpFileSetFilePtrL <%s> %lld %lu %lld %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llOffset, ulMethod, *pllActual, rc, pConn->rc);
2269
2270 return rc;
2271}
2272
2273int APIENTRY NdpFileSetFilePtr (HCONNECTION conn, NDFILEHANDLE handle, LONG lOffset, ULONG ulMethod, ULONG *pulActual)
2274{
2275 LONGLONG llActual;
2276 int rc = NdpFileSetFilePtrL(conn, handle, lOffset, ulMethod, &llActual);
2277 *pulActual = llActual & 0xFFFFFFFF;
2278 log("NdpFileSetFilePtr %ld %lu %ld %d\n", lOffset, ulMethod, *pulActual, rc);
2279 return rc;
2280}
2281
2282int APIENTRY NdpFileClose (HCONNECTION conn, NDFILEHANDLE handle)
2283{
2284 Connection *pConn = (Connection *)conn;
2285 Resource *pRes = pConn->pRes;
2286 int rc = 0;
2287 unsigned long action;
2288 smb_request req = {0};
2289 smb_response resp = {0};
2290
2291 log("NdpFileClose in %d <%s>\n", pConn->file.fd, pConn->file.fd < 0 ? "!null!" : pConn->file.fname);
2292
2293 do {
2294 if (pConn->file.fd < 0)
2295 {
2296 rc = ERROR_INVALID_HANDLE;
2297 break;
2298 }
2299 if (pConn->rc)
2300 {
2301 rc = ERROR_PIPE_NOT_CONNECTED;
2302 break;
2303 }
2304
2305 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2306 req.request = SMBREQ_CLOSE;
2307 req.param = pConn->mem;
2308 req.length = pRes->memlen;
2309 req.paramlen = sizeof(pConn->file);
2310 req.length = req.paramlen;
2311 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2312 if (pConn->rc || action < sizeof(resp) || resp.rc)
2313 {
2314 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2315 }
2316 else
2317 {
2318 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
2319 }
2320 } while (0);
2321 log("NdpFileClose %d %d %d\n", pConn->file.fd, rc, pConn->rc);
2322 pConn->file.fd = -1;
2323 return rc;
2324}
2325
2326int APIENTRY NdpFileCommit (HCONNECTION conn, NDFILEHANDLE handle)
2327{
2328 log("NdpFileCommit %d\n", NO_ERROR);
2329 return NO_ERROR;
2330}
2331
2332
2333int APIENTRY NdpFileNewSize (HCONNECTION conn, NDFILEHANDLE handle, ULONG ulLen)
2334{
2335 int rc = NdpFileNewSizeL(conn, handle, ulLen);
2336 log("NdpFileNewSize %ld %d\n", ulLen, rc);
2337 return rc;
2338}
2339
2340int APIENTRY NdpFileNewSizeL(HCONNECTION conn, NDFILEHANDLE handle, LONGLONG llLen)
2341{
2342 Connection *pConn = (Connection *)conn;
2343 Resource *pRes = pConn->pRes;
2344 int rc = 0;
2345 unsigned long action;
2346 smb_request req = {0};
2347 smb_response resp = {0};
2348
2349 log("NdpFileNewSizeL in\n");
2350 do {
2351 if (pConn->file.fd < 0)
2352 {
2353 rc = ERROR_INVALID_HANDLE;
2354 break;
2355 }
2356 if (pConn->rc)
2357 {
2358 rc = ERROR_PIPE_NOT_CONNECTED;
2359 break;
2360 }
2361
2362 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2363 *(long long *)(pConn->mem + sizeof(pConn->file)) = llLen;
2364
2365 req.request = SMBREQ_NEWSIZE;
2366 req.param = pConn->mem;
2367 req.paramlen = sizeof(pConn->file) + sizeof(long long);
2368 req.length = req.paramlen;
2369
2370 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2371 if (pConn->rc || action < sizeof(resp) || resp.rc)
2372 {
2373 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2374 }
2375 else
2376 {
2377 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
2378 }
2379 } while (0);
2380 log("NdpFileNewSizeL <%s> %lld %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, llLen, rc, pConn->rc);
2381 return rc;
2382}
2383
2384int APIENTRY NdpFileRead (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulRead, ULONG *pulActual)
2385{
2386 Connection *pConn = (Connection *)conn;
2387 Resource *pRes = pConn->pRes;
2388 int rc = 0;
2389 unsigned long done = 0;
2390 unsigned long onedone;
2391 unsigned long action;
2392 smb_request req = {0};
2393 smb_response resp = {0};
2394
2395 log("NdpFileRead in\n");
2396// log("NdpFileRead <%s> %lu\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulRead);
2397
2398 do {
2399 if (pConn->file.fd < 0)
2400 {
2401 rc = ERROR_INVALID_HANDLE;
2402 break;
2403 }
2404 if (pConn->rc)
2405 {
2406 rc = ERROR_PIPE_NOT_CONNECTED;
2407 break;
2408 }
2409
2410 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2411 req.request = SMBREQ_READ;
2412 req.param = pConn->mem;
2413 req.paramlen = sizeof(pConn->file);
2414
2415 while (done < ulRead)
2416 {
2417 req.length = req.paramlen + (pRes->memlen - req.paramlen < (ulRead - done) ? pRes->memlen - req.paramlen : (ulRead - done));
2418
2419 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2420 if (pConn->rc || action < sizeof(resp) || resp.rc)
2421 {
2422 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2423 break;
2424 }
2425 if (resp.value == 0)
2426 {
2427 break;
2428 }
2429 onedone = resp.value > req.length ? req.length : resp.value;
2430 MemCpy((char *)pBuffer + done, pConn->mem + sizeof(pConn->file), onedone);
2431 done += onedone;
2432 }
2433 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
2434 *pulActual = done;
2435 } while (0);
2436 log("NdpFileRead <%s> %lu %lu %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulRead, *pulActual, rc, pConn->rc);
2437
2438 return rc;
2439}
2440
2441int APIENTRY NdpFileWrite (HCONNECTION conn, NDFILEHANDLE handle, void *pBuffer, ULONG ulWrite, ULONG *pulActual)
2442{
2443 Connection *pConn = (Connection *)conn;
2444 Resource *pRes = pConn->pRes;
2445 int rc = 0;
2446 unsigned long done = 0;
2447 unsigned long onedone;
2448 unsigned long action;
2449 smb_request req = {0};
2450 smb_response resp = {0};
2451
2452 log("NdpFileWrite in\n");
2453 do {
2454 if (pConn->file.fd < 0)
2455 {
2456 rc = ERROR_INVALID_HANDLE;
2457 break;
2458 }
2459 if (pConn->rc)
2460 {
2461 rc = ERROR_PIPE_NOT_CONNECTED;
2462 break;
2463 }
2464
2465 MemCpy(pConn->mem, &pConn->file, sizeof(pConn->file));
2466 req.request = SMBREQ_WRITE;
2467 req.param = pConn->mem;
2468 req.paramlen = sizeof(pConn->file);
2469
2470 while (done < ulWrite)
2471 {
2472 req.length = pRes->memlen - req.paramlen < (ulWrite - done) ? pRes->memlen - req.paramlen : (ulWrite - done);
2473 MemCpy(pConn->mem + sizeof(pConn->file), (char *)pBuffer + done, req.length);
2474 req.length += req.paramlen;
2475
2476 pConn->rc = DosTransactNPipe(pConn->pipe, &req, sizeof(req), &resp, sizeof(resp), &action);
2477 if (pConn->rc || action < sizeof(resp) || resp.rc)
2478 {
2479 rc = pConn->rc ? pConn->rc : (resp.rc ? resp.rc : ERROR_INVALID_PARAMETER);
2480 break;
2481 }
2482 done += resp.value & 0xFFFFFFFF;
2483 if (resp.value < req.length)
2484 {
2485 break;
2486 }
2487 }
2488 MemCpy(&pConn->file, pConn->mem, sizeof(pConn->file));
2489 *pulActual = done;
2490 } while (0);
2491 log("NdpFileWrite <%s> %lu %lu %d %d\n", pConn->file.fd < 0 ? "!null!" : pConn->file.fname, ulWrite, *pulActual, rc, pConn->rc);
2492
2493 return rc;
2494}
Note: See TracBrowser for help on using the repository browser.