source: trunk/samba-3.0.25pre1/source/ndpsmb/ndpsmb.c@ 5

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

OS/2 client code, initial import.

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