ReactOS 0.4.15-dev-7788-g1ad9096
nfs41_driver.c
Go to the documentation of this file.
1/* NFSv4.1 client for Windows
2 * Copyright © 2012 The Regents of the University of Michigan
3 *
4 * Olga Kornievskaia <aglo@umich.edu>
5 * Casey Bodley <cbodley@umich.edu>
6 *
7 * This library is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation; either version 2.1 of the License, or (at
10 * your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful, but
13 * without any warranty; without even the implied warranty of merchantability
14 * or fitness for a particular purpose. See the GNU Lesser General Public
15 * License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 */
21
22#define MINIRDR__NAME "Value is ignored, only fact of definition"
23#include <rx.h>
24#include <windef.h>
25#include <winerror.h>
26
27#include <ntstrsafe.h>
28
29#ifdef __REACTOS__
30#include <pseh/pseh2.h>
31#endif
32
33#include "nfs41_driver.h"
34#include "nfs41_np.h"
35#include "nfs41_debug.h"
36
37#if defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_WIN7)
38NTSTATUS NTAPI RtlUnicodeToUTF8N(CHAR *utf8_dest, ULONG utf8_bytes_max,
39 ULONG *utf8_bytes_written,
40 const WCHAR *uni_src, ULONG uni_bytes);
41NTSTATUS NTAPI RtlUTF8ToUnicodeN(WCHAR *uni_dest, ULONG uni_bytes_max,
42 ULONG *uni_bytes_written,
43 const CHAR *utf8_src, ULONG utf8_bytes);
44#endif /* defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_WIN7) */
45
46#define USE_MOUNT_SEC_CONTEXT
47
48/* debugging printout defines */
49//#define DEBUG_FSDDISPATCH
50#define DEBUG_MARSHAL_HEADER
51#define DEBUG_MARSHAL_DETAIL
52//#define DEBUG_OPEN
53//#define DEBUG_CLOSE
54//#define DEBUG_CACHE
55#define DEBUG_INVALIDATE_CACHE
56//#define DEBUG_READ
57//#define DEBUG_WRITE
58//#define DEBUG_DIR_QUERY
59//#define DEBUG_FILE_QUERY
60//#define DEBUG_FILE_SET
61//#define DEBUG_ACL_QUERY
62//#define DEBUG_ACL_SET
63//#define DEBUG_EA_QUERY
64//#define DEBUG_EA_SET
65//#define DEBUG_LOCK
66//#define DEBUG_MISC
67#define DEBUG_TIME_BASED_COHERENCY
68#define DEBUG_MOUNT
69//#define DEBUG_VOLUME_QUERY
70
71//#define ENABLE_TIMINGS
72//#define ENABLE_INDV_TIMINGS
73#ifdef ENABLE_TIMINGS
74typedef struct __nfs41_timings {
75 LONG tops, sops;
76 LONGLONG ticks, size;
77} nfs41_timings;
78
79nfs41_timings lookup, readdir, open, close, getattr, setattr, getacl, setacl, volume,
80 read, write, lock, unlock, setexattr, getexattr;
81#endif
82DRIVER_INITIALIZE DriverEntry;
83DRIVER_UNLOAD nfs41_driver_unload;
85
88
89#define DISABLE_CACHING 0
90#define ENABLE_READ_CACHING 1
91#define ENABLE_WRITE_CACHING 2
92#define ENABLE_READWRITE_CACHING 3
93
94#define NFS41_MM_POOLTAG ('nfs4')
95#define NFS41_MM_POOLTAG_ACL ('acls')
96#define NFS41_MM_POOLTAG_MOUNT ('mnts')
97#define NFS41_MM_POOLTAG_OPEN ('open')
98#define NFS41_MM_POOLTAG_UP ('upca')
99#define NFS41_MM_POOLTAG_DOWN ('down')
100
105
108
109#define DECLARE_CONST_ANSI_STRING(_var, _string) \
110 const CHAR _var ## _buffer[] = _string; \
111 const ANSI_STRING _var = { sizeof(_string) - sizeof(CHAR), \
112 sizeof(_string), (PCH) _var ## _buffer }
113#define RELATIVE(wait) (-(wait))
114#define NANOSECONDS(nanos) (((signed __int64)(nanos)) / 100L)
115#define MICROSECONDS(micros) (((signed __int64)(micros)) * NANOSECONDS(1000L))
116#define MILLISECONDS(milli) (((signed __int64)(milli)) * MICROSECONDS(1000L))
117#define SECONDS(seconds) (((signed __int64)(seconds)) * MILLISECONDS(1000L))
118
119DECLARE_CONST_ANSI_STRING(NfsV3Attributes, "NfsV3Attributes");
120DECLARE_CONST_ANSI_STRING(NfsSymlinkTargetName, "NfsSymlinkTargetName");
121DECLARE_CONST_ANSI_STRING(NfsActOnLink, "NfsActOnLink");
122
124 IN const ANSI_STRING *lhs,
125 IN const CHAR *rhs,
126 IN const UCHAR rhs_len)
127{
128 return lhs->Length == rhs_len &&
129 RtlCompareMemory(lhs->Buffer, rhs, rhs_len) == rhs_len;
130}
131
132typedef struct _nfs3_attrs {
135 struct {
142LARGE_INTEGER unix_time_diff; //needed to convert windows time to unix
143
144enum ftype3 {
151 NF3FIFO
153
160
161#ifdef __REACTOS__
162#undef _errno
163#undef errno
164#endif
165
166typedef struct _updowncall_entry {
185 union {
186 struct {
195 struct {
200 struct {
206 struct {
210 struct {
228 struct {
233 struct {
242 struct {
245 struct {
246 DWORD mode;
248 struct {
256 struct {
260 struct {
263 struct {
266 } u;
267
269
270typedef struct _updowncall_list {
274
275typedef struct _nfs41_mount_entry {
283
284typedef struct _nfs41_mount_list {
287
288#define nfs41_AddEntry(lock,list,pEntry) \
289 ExAcquireFastMutex(&lock); \
290 InsertTailList(&(list).head, &(pEntry)->next); \
291 ExReleaseFastMutex(&lock);
292#define nfs41_RemoveFirst(lock,list,pEntry) \
293 ExAcquireFastMutex(&lock); \
294 pEntry = (IsListEmpty(&(list).head) \
295 ? NULL \
296 : RemoveHeadList(&(list).head)); \
297 ExReleaseFastMutex(&lock);
298#define nfs41_RemoveEntry(lock,pEntry) \
299 ExAcquireFastMutex(&lock); \
300 RemoveEntryList(&pEntry->next); \
301 ExReleaseFastMutex(&lock);
302#define nfs41_IsListEmpty(lock,list,flag) \
303 ExAcquireFastMutex(&lock); \
304 flag = IsListEmpty(&(list).head); \
305 ExReleaseFastMutex(&lock);
306#define nfs41_GetFirstEntry(lock,list,pEntry) \
307 ExAcquireFastMutex(&lock); \
308 pEntry = (IsListEmpty(&(list).head) \
309 ? NULL \
310 : (nfs41_updowncall_entry *) \
311 (CONTAINING_RECORD((list).head.Flink, \
312 nfs41_updowncall_entry, \
313 next))); \
314 ExReleaseFastMutex(&lock);
315#define nfs41_GetFirstMountEntry(lock,list,pEntry) \
316 ExAcquireFastMutex(&lock); \
317 pEntry = (IsListEmpty(&(list).head) \
318 ? NULL \
319 : (nfs41_mount_entry *) \
320 (CONTAINING_RECORD((list).head.Flink, \
321 nfs41_mount_entry, \
322 next))); \
323 ExReleaseFastMutex(&lock);
324
325/* In order to cooperate with other network providers,
326 * we only claim paths of the format '\\server\nfs4\path' */
327DECLARE_CONST_UNICODE_STRING(NfsPrefix, L"\\nfs4");
328DECLARE_CONST_UNICODE_STRING(AUTH_SYS_NAME, L"sys");
329DECLARE_CONST_UNICODE_STRING(AUTHGSS_KRB5_NAME, L"krb5");
330DECLARE_CONST_UNICODE_STRING(AUTHGSS_KRB5I_NAME, L"krb5i");
331DECLARE_CONST_UNICODE_STRING(AUTHGSS_KRB5P_NAME, L"krb5p");
334
335#define SERVER_NAME_BUFFER_SIZE 1024
336#define MOUNT_CONFIG_RW_SIZE_MIN 1024
337#define MOUNT_CONFIG_RW_SIZE_DEFAULT 1048576
338#define MOUNT_CONFIG_RW_SIZE_MAX 1048576
339#define MAX_SEC_FLAVOR_LEN 12
340#define UPCALL_TIMEOUT_DEFAULT 50 /* in seconds */
341
342typedef struct _NFS41_MOUNT_CONFIG {
356
365#define NFS41GetNetRootExtension(pNetRoot) \
366 (((pNetRoot) == NULL) ? NULL : \
367 (PNFS41_NETROOT_EXTENSION)((pNetRoot)->Context))
368
369/* FileSystemName as reported by FileFsAttributeInfo query */
370#define FS_NAME L"NFS"
371#define FS_NAME_LEN (sizeof(FS_NAME) - sizeof(WCHAR))
372#define FS_ATTR_LEN (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + FS_NAME_LEN)
373
374/* FileSystemName as reported by FileFsAttributeInfo query */
375#define VOL_NAME L"PnfsVolume"
376#define VOL_NAME_LEN (sizeof(VOL_NAME) - sizeof(WCHAR))
377#define VOL_ATTR_LEN (sizeof(FILE_FS_VOLUME_INFORMATION) + VOL_NAME_LEN)
378
390#define STORE_MOUNT_SEC_CONTEXT
391#ifdef STORE_MOUNT_SEC_CONTEXT
393#endif
395#define NFS41GetVNetRootExtension(pVNetRoot) \
396 (((pVNetRoot) == NULL) ? NULL : \
397 (PNFS41_V_NET_ROOT_EXTENSION)((pVNetRoot)->Context))
398
399typedef struct _NFS41_FCB {
409#define NFS41GetFcbExtension(pFcb) \
410 (((pFcb) == NULL) ? NULL : (PNFS41_FCB)((pFcb)->Context))
411
412typedef struct _NFS41_FOBX {
415
425#define NFS41GetFobxExtension(pFobx) \
426 (((pFobx) == NULL) ? NULL : (PNFS41_FOBX)((pFobx)->Context))
427
428typedef struct _NFS41_SERVER_ENTRY {
431 UNICODE_STRING Name; // the server name.
433
445
446#define NFS41GetDeviceExtension(RxContext,pExt) \
447 PNFS41_DEVICE_EXTENSION pExt = (PNFS41_DEVICE_EXTENSION) \
448 ((PBYTE)(RxContext->RxDeviceObject) + sizeof(RDBSS_DEVICE_OBJECT))
449
450typedef struct _nfs41_fcb_list_entry {
458
459typedef struct _nfs41_fcb_list {
463
467#define RxDefineNode( node, type ) \
468 node->NodeTypeCode = NTC_##type; \
469 node->NodeByteSize = sizeof(type);
470
471#define RDR_NULL_STATE 0
472#define RDR_UNLOADED 1
473#define RDR_UNLOADING 2
474#define RDR_LOADING 3
475#define RDR_LOADED 4
476#define RDR_STOPPED 5
477#define RDR_STOPPING 6
478#define RDR_STARTING 7
479#define RDR_STARTED 8
480
483
485
487 PRX_CONTEXT RxContext)
488{
489
491
492 if (IrpSp) {
493 DbgP("FileOject %p name %wZ access r=%d,w=%d,d=%d share r=%d,w=%d,d=%d\n",
494 IrpSp->FileObject, &IrpSp->FileObject->FileName,
495 IrpSp->FileObject->ReadAccess, IrpSp->FileObject->WriteAccess,
496 IrpSp->FileObject->DeleteAccess, IrpSp->FileObject->SharedRead,
497 IrpSp->FileObject->SharedWrite, IrpSp->FileObject->SharedDelete);
499 print_irps_flags(0, RxContext->CurrentIrpSp);
500 } else
501 DbgP("Couldn't print FileObject IrpSp is NULL\n");
502
503 print_fo_all(1, RxContext);
504 if (RxContext->CurrentIrp)
505 print_irp_flags(0, RxContext->CurrentIrp);
506}
507
508/* convert strings from unicode -> ansi during marshalling to
509 * save space in the upcall buffers and avoid extra copies */
512{
513 ULONG ActualCount = 0;
514 RtlUnicodeToUTF8N(NULL, 0xffff, &ActualCount, str->Buffer, str->Length);
515 return sizeof(str->MaximumLength) + ActualCount + sizeof(UNICODE_NULL);
516}
517
519 IN OUT unsigned char **pos,
521{
522 ANSI_STRING ansi;
523 ULONG ActualCount;
525
526 if (str->Length == 0) {
528 ActualCount = 0;
529 ansi.MaximumLength = 1;
530 goto out_copy;
531 }
532
533 /* query the number of bytes required for the utf8 encoding */
534 status = RtlUnicodeToUTF8N(NULL, 0xffff,
535 &ActualCount, str->Buffer, str->Length);
536 if (status) {
537 print_error("RtlUnicodeToUTF8N('%wZ') failed with 0x%08X\n",
538 str, status);
539 goto out;
540 }
541
542 /* convert the string directly into the upcall buffer */
543 ansi.Buffer = (PCHAR)*pos + sizeof(ansi.MaximumLength);
544 ansi.MaximumLength = (USHORT)ActualCount + sizeof(UNICODE_NULL);
546 &ActualCount, str->Buffer, str->Length);
547 if (status) {
548 print_error("RtlUnicodeToUTF8N(%hu, '%wZ', %hu) failed with 0x%08X\n",
549 ansi.MaximumLength, str, str->Length, status);
550 goto out;
551 }
552
553out_copy:
554 RtlCopyMemory(*pos, &ansi.MaximumLength, sizeof(ansi.MaximumLength));
555 *pos += sizeof(ansi.MaximumLength);
556 (*pos)[ActualCount] = '\0';
557 *pos += ansi.MaximumLength;
558out:
559 return status;
560}
561
564 unsigned char *buf,
565 ULONG buf_len,
566 ULONG *len)
567{
569 ULONG header_len = 0;
570 unsigned char *tmp = buf;
571
572 header_len = sizeof(entry->version) + sizeof(entry->xid) +
573 sizeof(entry->opcode) + 2 * sizeof(HANDLE);
574 if (header_len > buf_len) {
576 goto out;
577 }
578 else
579 *len = header_len;
580 RtlCopyMemory(tmp, &entry->version, sizeof(entry->version));
581 tmp += sizeof(entry->version);
582 RtlCopyMemory(tmp, &entry->xid, sizeof(entry->xid));
583 tmp += sizeof(entry->xid);
584 RtlCopyMemory(tmp, &entry->opcode, sizeof(entry->opcode));
585 tmp += sizeof(entry->opcode);
586 RtlCopyMemory(tmp, &entry->session, sizeof(HANDLE));
587 tmp += sizeof(HANDLE);
588 RtlCopyMemory(tmp, &entry->open_state, sizeof(HANDLE));
589 tmp += sizeof(HANDLE);
590
591#ifdef DEBUG_MARSHAL_HEADER
592 if (MmIsAddressValid(entry->filename))
593 DbgP("[upcall header] xid=%lld opcode=%s filename=%wZ version=%d "
594 "session=0x%x open_state=0x%x\n", entry->xid,
595 opcode2string(entry->opcode), entry->filename,
596 entry->version, entry->session, entry->open_state);
597 else
599#endif
600out:
601 return status;
602}
603
606{
607 switch(sec_flavor) {
608 case RPCSEC_AUTH_SYS: return "AUTH_SYS";
609 case RPCSEC_AUTHGSS_KRB5: return "AUTHGSS_KRB5";
610 case RPCSEC_AUTHGSS_KRB5I: return "AUTHGSS_KRB5I";
611 case RPCSEC_AUTHGSS_KRB5P: return "AUTHGSS_KRB5P";
612 }
613
614 return "UNKNOWN FLAVOR";
615}
618 unsigned char *buf,
619 ULONG buf_len,
620 ULONG *len)
621{
623 ULONG header_len = 0;
624 unsigned char *tmp = buf;
625
626 status = marshal_nfs41_header(entry, tmp, buf_len, len);
627 if (status) goto out;
628 else tmp += *len;
629
630 /* 03/25/2011: Kernel crash to nfsd not running but mount upcall cued up */
631 if (!MmIsAddressValid(entry->u.Mount.srv_name) ||
632 !MmIsAddressValid(entry->u.Mount.root)) {
634 goto out;
635 }
636 header_len = *len + length_as_utf8(entry->u.Mount.srv_name) +
637 length_as_utf8(entry->u.Mount.root) + 3 * sizeof(DWORD);
638 if (header_len > buf_len) {
640 goto out;
641 }
642 status = marshall_unicode_as_utf8(&tmp, entry->u.Mount.srv_name);
643 if (status) goto out;
644 status = marshall_unicode_as_utf8(&tmp, entry->u.Mount.root);
645 if (status) goto out;
646 RtlCopyMemory(tmp, &entry->u.Mount.sec_flavor, sizeof(DWORD));
647 tmp += sizeof(DWORD);
648 RtlCopyMemory(tmp, &entry->u.Mount.rsize, sizeof(DWORD));
649 tmp += sizeof(DWORD);
650 RtlCopyMemory(tmp, &entry->u.Mount.wsize, sizeof(DWORD));
651
652 *len = header_len;
653
654#ifdef DEBUG_MARSHAL_DETAIL
655 DbgP("marshal_nfs41_mount: server name=%wZ mount point=%wZ sec_flavor=%s "
656 "rsize=%d wsize=%d\n", entry->u.Mount.srv_name, entry->u.Mount.root,
657 secflavorop2name(entry->u.Mount.sec_flavor), entry->u.Mount.rsize,
658 entry->u.Mount.wsize);
659#endif
660out:
661 return status;
662}
663
666 unsigned char *buf,
667 ULONG buf_len,
668 ULONG *len)
669{
670 return marshal_nfs41_header(entry, buf, buf_len, len);
671}
672
675 unsigned char *buf,
676 ULONG buf_len,
677 ULONG *len)
678{
680 ULONG header_len = 0;
681 unsigned char *tmp = buf;
682
683 status = marshal_nfs41_header(entry, tmp, buf_len, len);
684 if (status) goto out;
685 else tmp += *len;
686
687 header_len = *len + length_as_utf8(entry->filename) +
688 7 * sizeof(ULONG) + 2 * sizeof(HANDLE) +
689 length_as_utf8(&entry->u.Open.symlink);
690 if (header_len > buf_len) {
692 goto out;
693 }
694 status = marshall_unicode_as_utf8(&tmp, entry->filename);
695 if (status) goto out;
696 RtlCopyMemory(tmp, &entry->u.Open.access_mask,
697 sizeof(entry->u.Open.access_mask));
698 tmp += sizeof(entry->u.Open.access_mask);
699 RtlCopyMemory(tmp, &entry->u.Open.access_mode,
700 sizeof(entry->u.Open.access_mode));
701 tmp += sizeof(entry->u.Open.access_mode);
702 RtlCopyMemory(tmp, &entry->u.Open.attrs, sizeof(entry->u.Open.attrs));
703 tmp += sizeof(entry->u.Open.attrs);
704 RtlCopyMemory(tmp, &entry->u.Open.copts, sizeof(entry->u.Open.copts));
705 tmp += sizeof(entry->u.Open.copts);
706 RtlCopyMemory(tmp, &entry->u.Open.disp, sizeof(entry->u.Open.disp));
707 tmp += sizeof(entry->u.Open.disp);
708 RtlCopyMemory(tmp, &entry->u.Open.open_owner_id,
709 sizeof(entry->u.Open.open_owner_id));
710 tmp += sizeof(entry->u.Open.open_owner_id);
711 RtlCopyMemory(tmp, &entry->u.Open.mode, sizeof(DWORD));
712 tmp += sizeof(DWORD);
713 RtlCopyMemory(tmp, &entry->u.Open.srv_open, sizeof(HANDLE));
714 tmp += sizeof(HANDLE);
715 status = marshall_unicode_as_utf8(&tmp, &entry->u.Open.symlink);
716 if (status) goto out;
717
718 _SEH2_TRY {
719 if (entry->u.Open.EaMdl) {
720 entry->u.Open.EaBuffer =
722#ifndef __REACTOS__
724#else
726#endif
727 if (entry->u.Open.EaBuffer == NULL) {
728 print_error("MmMapLockedPagesSpecifyCache failed to map pages\n");
730 goto out;
731 }
732 }
734 print_error("Call to MmMapLocked failed due to exception 0x%x\n", _SEH2_GetExceptionCode());
736 goto out;
737 } _SEH2_END;
738 RtlCopyMemory(tmp, &entry->u.Open.EaBuffer, sizeof(HANDLE));
739 *len = header_len;
740
741#ifdef DEBUG_MARSHAL_DETAIL
742 DbgP("marshal_nfs41_open: name=%wZ mask=0x%x access=0x%x attrs=0x%x "
743 "opts=0x%x dispo=0x%x open_owner_id=0x%x mode=%o srv_open=%p ea=%p\n",
744 entry->filename, entry->u.Open.access_mask,
745 entry->u.Open.access_mode, entry->u.Open.attrs, entry->u.Open.copts,
746 entry->u.Open.disp, entry->u.Open.open_owner_id, entry->u.Open.mode,
747 entry->u.Open.srv_open, entry->u.Open.EaBuffer);
748#endif
749out:
750 return status;
751}
752
755 unsigned char *buf,
756 ULONG buf_len,
757 ULONG *len)
758{
760 ULONG header_len = 0;
761 unsigned char *tmp = buf;
762
763 status = marshal_nfs41_header(entry, tmp, buf_len, len);
764 if (status) goto out;
765 else tmp += *len;
766
767 header_len = *len + sizeof(entry->buf_len) +
768 sizeof(entry->u.ReadWrite.offset) + sizeof(HANDLE);
769 if (header_len > buf_len) {
771 goto out;
772 }
773
774 RtlCopyMemory(tmp, &entry->buf_len, sizeof(entry->buf_len));
775 tmp += sizeof(entry->buf_len);
776 RtlCopyMemory(tmp, &entry->u.ReadWrite.offset,
777 sizeof(entry->u.ReadWrite.offset));
778 tmp += sizeof(entry->u.ReadWrite.offset);
779 _SEH2_TRY {
780 entry->u.ReadWrite.MdlAddress->MdlFlags |= MDL_MAPPING_CAN_FAIL;
781 entry->buf =
782 MmMapLockedPagesSpecifyCache(entry->u.ReadWrite.MdlAddress,
783#ifndef __REACTOS__
785#else
787#endif
788 if (entry->buf == NULL) {
789 print_error("MmMapLockedPagesSpecifyCache failed to map pages\n");
791 goto out;
792 }
796 print_error("Call to MmMapLocked failed due to exception 0x%x\n", code);
798 goto out;
799 } _SEH2_END;
800 RtlCopyMemory(tmp, &entry->buf, sizeof(HANDLE));
801 *len = header_len;
802
803#ifdef DEBUG_MARSHAL_DETAIL
804 DbgP("marshal_nfs41_rw: len=%lu offset=%llu MdlAddress=%p Userspace=%p\n",
805 entry->buf_len, entry->u.ReadWrite.offset,
806 entry->u.ReadWrite.MdlAddress, entry->buf);
807#endif
808out:
809 return status;
810}
811
814 unsigned char *buf,
815 ULONG buf_len,
816 ULONG *len)
817{
819 ULONG header_len = 0;
820 unsigned char *tmp = buf;
821
822 status = marshal_nfs41_header(entry, tmp, buf_len, len);
823 if (status) goto out;
824 else tmp += *len;
825
826 header_len = *len + 2 * sizeof(LONGLONG) + 2 * sizeof(BOOLEAN);
827 if (header_len > buf_len) {
829 goto out;
830 }
831 RtlCopyMemory(tmp, &entry->u.Lock.offset, sizeof(LONGLONG));
832 tmp += sizeof(LONGLONG);
833 RtlCopyMemory(tmp, &entry->u.Lock.length, sizeof(LONGLONG));
834 tmp += sizeof(LONGLONG);
835 RtlCopyMemory(tmp, &entry->u.Lock.exclusive, sizeof(BOOLEAN));
836 tmp += sizeof(BOOLEAN);
837 RtlCopyMemory(tmp, &entry->u.Lock.blocking, sizeof(BOOLEAN));
838 *len = header_len;
839
840#ifdef DEBUG_MARSHAL_DETAIL
841 DbgP("marshal_nfs41_lock: offset=%llx length=%llx exclusive=%u "
842 "blocking=%u\n", entry->u.Lock.offset, entry->u.Lock.length,
843 entry->u.Lock.exclusive, entry->u.Lock.blocking);
844#endif
845out:
846 return status;
847}
848
851 unsigned char *buf,
852 ULONG buf_len,
853 ULONG *len)
854{
856 ULONG header_len = 0;
857 unsigned char *tmp = buf;
859
860 status = marshal_nfs41_header(entry, tmp, buf_len, len);
861 if (status) goto out;
862 else tmp += *len;
863
864 header_len = *len + sizeof(ULONG) +
865 entry->u.Unlock.count * 2 * sizeof(LONGLONG);
866 if (header_len > buf_len) {
868 goto out;
869 }
870 RtlCopyMemory(tmp, &entry->u.Unlock.count, sizeof(ULONG));
871 tmp += sizeof(ULONG);
872
873 lock = &entry->u.Unlock.locks;
874 while (lock) {
875 RtlCopyMemory(tmp, &lock->ByteOffset, sizeof(LONGLONG));
876 tmp += sizeof(LONGLONG);
877 RtlCopyMemory(tmp, &lock->Length, sizeof(LONGLONG));
878 tmp += sizeof(LONGLONG);
879 lock = lock->Next;
880 }
881 *len = header_len;
882
883#ifdef DEBUG_MARSHAL_DETAIL
884 DbgP("marshal_nfs41_unlock: count=%u\n", entry->u.Unlock.count);
885#endif
886out:
887 return status;
888}
889
892 unsigned char *buf,
893 ULONG buf_len,
894 ULONG *len)
895{
897 ULONG header_len = 0;
898 unsigned char *tmp = buf;
899
900 status = marshal_nfs41_header(entry, tmp, buf_len, len);
901 if (status) goto out;
902 else tmp += *len;
903
904 header_len = *len + sizeof(BOOLEAN) + sizeof(HANDLE);
905 if (entry->u.Close.remove)
906 header_len += length_as_utf8(entry->filename) +
907 sizeof(BOOLEAN);
908
909 if (header_len > buf_len) {
911 goto out;
912 }
913 RtlCopyMemory(tmp, &entry->u.Close.remove, sizeof(BOOLEAN));
914 tmp += sizeof(BOOLEAN);
915 RtlCopyMemory(tmp, &entry->u.Close.srv_open, sizeof(HANDLE));
916 if (entry->u.Close.remove) {
917 tmp += sizeof(HANDLE);
918 status = marshall_unicode_as_utf8(&tmp, entry->filename);
919 if (status) goto out;
920 RtlCopyMemory(tmp, &entry->u.Close.renamed, sizeof(BOOLEAN));
921 }
922 *len = header_len;
923
924#ifdef DEBUG_MARSHAL_DETAIL
925 DbgP("marshal_nfs41_close: name=%wZ remove=%d srv_open=%p renamed=%d\n",
926 entry->filename->Length?entry->filename:&SLASH,
927 entry->u.Close.remove, entry->u.Close.srv_open, entry->u.Close.renamed);
928#endif
929out:
930 return status;
931}
932
935 unsigned char *buf,
936 ULONG buf_len,
937 ULONG *len)
938{
940 ULONG header_len = 0;
941 unsigned char *tmp = buf;
942
943 status = marshal_nfs41_header(entry, tmp, buf_len, len);
944 if (status) goto out;
945 else tmp += *len;
946
947 header_len = *len + 2 * sizeof(ULONG) + sizeof(HANDLE) +
948 length_as_utf8(entry->u.QueryFile.filter) + 3 * sizeof(BOOLEAN);
949 if (header_len > buf_len) {
951 goto out;
952 }
953
954 RtlCopyMemory(tmp, &entry->u.QueryFile.InfoClass, sizeof(ULONG));
955 tmp += sizeof(ULONG);
956 RtlCopyMemory(tmp, &entry->buf_len, sizeof(ULONG));
957 tmp += sizeof(ULONG);
958 status = marshall_unicode_as_utf8(&tmp, entry->u.QueryFile.filter);
959 if (status) goto out;
960 RtlCopyMemory(tmp, &entry->u.QueryFile.initial_query, sizeof(BOOLEAN));
961 tmp += sizeof(BOOLEAN);
962 RtlCopyMemory(tmp, &entry->u.QueryFile.restart_scan, sizeof(BOOLEAN));
963 tmp += sizeof(BOOLEAN);
964 RtlCopyMemory(tmp, &entry->u.QueryFile.return_single, sizeof(BOOLEAN));
965 tmp += sizeof(BOOLEAN);
966 _SEH2_TRY {
967 entry->u.QueryFile.mdl_buf =
968 MmMapLockedPagesSpecifyCache(entry->u.QueryFile.mdl,
969#ifndef __REACTOS__
971#else
973#endif
974 if (entry->u.QueryFile.mdl_buf == NULL) {
975 print_error("MmMapLockedPagesSpecifyCache failed to map pages\n");
977 goto out;
978 }
982 print_error("Call to MmMapLocked failed due to exception 0x%x\n", code);
984 goto out;
985 } _SEH2_END;
986 RtlCopyMemory(tmp, &entry->u.QueryFile.mdl_buf, sizeof(HANDLE));
987 *len = header_len;
988
989#ifdef DEBUG_MARSHAL_DETAIL
990 DbgP("marshal_nfs41_dirquery: filter='%wZ'class=%d len=%d "
991 "1st\\restart\\single=%d\\%d\\%d\n", entry->u.QueryFile.filter,
992 entry->u.QueryFile.InfoClass, entry->buf_len,
993 entry->u.QueryFile.initial_query, entry->u.QueryFile.restart_scan,
994 entry->u.QueryFile.return_single);
995#endif
996out:
997 return status;
998}
999
1002 unsigned char *buf,
1003 ULONG buf_len,
1004 ULONG *len)
1005{
1007 ULONG header_len = 0;
1008 unsigned char *tmp = buf;
1009
1010 status = marshal_nfs41_header(entry, tmp, buf_len, len);
1011 if (status) goto out;
1012 else tmp += *len;
1013
1014 header_len = *len + 2 * sizeof(ULONG);
1015 if (header_len > buf_len) {
1017 goto out;
1018 }
1019 RtlCopyMemory(tmp, &entry->u.QueryFile.InfoClass, sizeof(ULONG));
1020 tmp += sizeof(ULONG);
1021 RtlCopyMemory(tmp, &entry->buf_len, sizeof(ULONG));
1022 tmp += sizeof(ULONG);
1023 RtlCopyMemory(tmp, &entry->session, sizeof(HANDLE));
1024 tmp += sizeof(HANDLE);
1025 RtlCopyMemory(tmp, &entry->open_state, sizeof(HANDLE));
1026 *len = header_len;
1027
1028#ifdef DEBUG_MARSHAL_DETAIL
1029 DbgP("marshal_nfs41_filequery: class=%d\n", entry->u.QueryFile.InfoClass);
1030#endif
1031out:
1032 return status;
1033}
1034
1037 unsigned char *buf,
1038 ULONG buf_len,
1039 ULONG *len)
1040{
1042 ULONG header_len = 0;
1043 unsigned char *tmp = buf;
1044
1045 status = marshal_nfs41_header(entry, tmp, buf_len, len);
1046 if (status) goto out;
1047 else tmp += *len;
1048
1049 header_len = *len + length_as_utf8(entry->filename) +
1050 2 * sizeof(ULONG) + entry->buf_len;
1051 if (header_len > buf_len) {
1053 goto out;
1054 }
1055 status = marshall_unicode_as_utf8(&tmp, entry->filename);
1056 if (status) goto out;
1057 RtlCopyMemory(tmp, &entry->u.SetFile.InfoClass, sizeof(ULONG));
1058 tmp += sizeof(ULONG);
1059 RtlCopyMemory(tmp, &entry->buf_len, sizeof(ULONG));
1060 tmp += sizeof(ULONG);
1061 RtlCopyMemory(tmp, entry->buf, entry->buf_len);
1062 *len = header_len;
1063
1064#ifdef DEBUG_MARSHAL_DETAIL
1065 DbgP("marshal_nfs41_fileset: filename='%wZ' class=%d\n",
1066 entry->filename, entry->u.SetFile.InfoClass);
1067#endif
1068out:
1069 return status;
1070}
1071
1074 unsigned char *buf,
1075 ULONG buf_len,
1076 ULONG *len)
1077{
1079 ULONG header_len = 0;
1080 unsigned char *tmp = buf;
1081
1082 status = marshal_nfs41_header(entry, tmp, buf_len, len);
1083 if (status) goto out;
1084 else tmp += *len;
1085
1086 header_len = *len + length_as_utf8(entry->filename) +
1087 sizeof(ULONG) + entry->buf_len + sizeof(DWORD);
1088 if (header_len > buf_len) {
1090 goto out;
1091 }
1092
1093 status = marshall_unicode_as_utf8(&tmp, entry->filename);
1094 if (status) goto out;
1095 RtlCopyMemory(tmp, &entry->u.SetEa.mode, sizeof(DWORD));
1096 tmp += sizeof(DWORD);
1097 RtlCopyMemory(tmp, &entry->buf_len, sizeof(ULONG));
1098 tmp += sizeof(ULONG);
1099 RtlCopyMemory(tmp, entry->buf, entry->buf_len);
1100 *len = header_len;
1101
1102#ifdef DEBUG_MARSHAL_DETAIL
1103 DbgP("marshal_nfs41_easet: filename=%wZ, buflen=%d mode=0x%x\n",
1104 entry->filename, entry->buf_len, entry->u.SetEa.mode);
1105#endif
1106out:
1107 return status;
1108}
1109
1112 unsigned char *buf,
1113 ULONG buf_len,
1114 ULONG *len)
1115{
1117 ULONG header_len = 0;
1118 unsigned char *tmp = buf;
1119
1120 status = marshal_nfs41_header(entry, tmp, buf_len, len);
1121 if (status) goto out;
1122 else tmp += *len;
1123
1124 header_len = *len + length_as_utf8(entry->filename) +
1125 3 * sizeof(ULONG) + entry->u.QueryEa.EaListLength + 2 * sizeof(BOOLEAN);
1126
1127 if (header_len > buf_len) {
1129 goto out;
1130 }
1131
1132 status = marshall_unicode_as_utf8(&tmp, entry->filename);
1133 if (status) goto out;
1134 RtlCopyMemory(tmp, &entry->u.QueryEa.EaIndex, sizeof(ULONG));
1135 tmp += sizeof(ULONG);
1136 RtlCopyMemory(tmp, &entry->u.QueryEa.RestartScan, sizeof(BOOLEAN));
1137 tmp += sizeof(BOOLEAN);
1138 RtlCopyMemory(tmp, &entry->u.QueryEa.ReturnSingleEntry, sizeof(BOOLEAN));
1139 tmp += sizeof(BOOLEAN);
1140 RtlCopyMemory(tmp, &entry->buf_len, sizeof(ULONG));
1141 tmp += sizeof(ULONG);
1142 RtlCopyMemory(tmp, &entry->u.QueryEa.EaListLength, sizeof(ULONG));
1143 tmp += sizeof(ULONG);
1144 if (entry->u.QueryEa.EaList && entry->u.QueryEa.EaListLength)
1145 RtlCopyMemory(tmp, entry->u.QueryEa.EaList,
1146 entry->u.QueryEa.EaListLength);
1147 *len = header_len;
1148
1149#ifdef DEBUG_MARSHAL_DETAIL
1150 DbgP("marshal_nfs41_eaget: filename=%wZ, index=%d list_len=%d "
1151 "rescan=%d single=%d\n", entry->filename,
1152 entry->u.QueryEa.EaIndex, entry->u.QueryEa.EaListLength,
1153 entry->u.QueryEa.RestartScan, entry->u.QueryEa.ReturnSingleEntry);
1154#endif
1155out:
1156 return status;
1157}
1158
1161 unsigned char *buf,
1162 ULONG buf_len,
1163 ULONG *len)
1164{
1166 ULONG header_len = 0;
1167 unsigned char *tmp = buf;
1168
1169 status = marshal_nfs41_header(entry, tmp, buf_len, len);
1170 if (status) goto out;
1171 else tmp += *len;
1172
1173 header_len = *len + sizeof(BOOLEAN) + length_as_utf8(entry->filename);
1174 if (entry->u.Symlink.set)
1175 header_len += length_as_utf8(entry->u.Symlink.target);
1176 if (header_len > buf_len) {
1178 goto out;
1179 }
1180
1181 status = marshall_unicode_as_utf8(&tmp, entry->filename);
1182 if (status) goto out;
1183 RtlCopyMemory(tmp, &entry->u.Symlink.set, sizeof(BOOLEAN));
1184 tmp += sizeof(BOOLEAN);
1185 if (entry->u.Symlink.set) {
1186 status = marshall_unicode_as_utf8(&tmp, entry->u.Symlink.target);
1187 if (status) goto out;
1188 }
1189 *len = header_len;
1190
1191#ifdef DEBUG_MARSHAL_DETAIL
1192 DbgP("marshal_nfs41_symlink: name %wZ symlink target %wZ\n",
1193 entry->filename,
1194 entry->u.Symlink.set?entry->u.Symlink.target : NULL);
1195#endif
1196out:
1197 return status;
1198}
1199
1202 unsigned char *buf,
1203 ULONG buf_len,
1204 ULONG *len)
1205{
1207 ULONG header_len = 0;
1208 unsigned char *tmp = buf;
1209
1210 status = marshal_nfs41_header(entry, tmp, buf_len, len);
1211 if (status) goto out;
1212 else tmp += *len;
1213
1214 header_len = *len + sizeof(FS_INFORMATION_CLASS);
1215 if (header_len > buf_len) {
1217 goto out;
1218 }
1219
1220 RtlCopyMemory(tmp, &entry->u.Volume.query, sizeof(FS_INFORMATION_CLASS));
1221 *len = header_len;
1222
1223#ifdef DEBUG_MARSHAL_DETAIL
1224 DbgP("marshal_nfs41_volume: class=%d\n", entry->u.Volume.query);
1225#endif
1226out:
1227 return status;
1228}
1229
1232 unsigned char *buf,
1233 ULONG buf_len,
1234 ULONG *len)
1235{
1237 ULONG header_len = 0;
1238 unsigned char *tmp = buf;
1239
1240 status = marshal_nfs41_header(entry, tmp, buf_len, len);
1241 if (status) goto out;
1242 else tmp += *len;
1243
1244 header_len = *len + sizeof(SECURITY_INFORMATION);
1245 if (header_len > buf_len) {
1247 goto out;
1248 }
1249
1250 RtlCopyMemory(tmp, &entry->u.Acl.query, sizeof(SECURITY_INFORMATION));
1251 *len = header_len;
1252
1253#ifdef DEBUG_MARSHAL_DETAIL
1254 DbgP("marshal_nfs41_getacl: class=0x%x\n", entry->u.Acl.query);
1255#endif
1256out:
1257 return status;
1258}
1259
1262 unsigned char *buf,
1263 ULONG buf_len,
1264 ULONG *len)
1265{
1267 ULONG header_len = 0;
1268 unsigned char *tmp = buf;
1269
1270 status = marshal_nfs41_header(entry, tmp, buf_len, len);
1271 if (status) goto out;
1272 else tmp += *len;
1273
1274 header_len = *len + sizeof(SECURITY_INFORMATION) +
1275 sizeof(ULONG) + entry->buf_len;
1276 if (header_len > buf_len) {
1278 goto out;
1279 }
1280
1281 RtlCopyMemory(tmp, &entry->u.Acl.query, sizeof(SECURITY_INFORMATION));
1282 tmp += sizeof(SECURITY_INFORMATION);
1283 RtlCopyMemory(tmp, &entry->buf_len, sizeof(ULONG));
1284 tmp += sizeof(ULONG);
1285 RtlCopyMemory(tmp, entry->buf, entry->buf_len);
1286 *len = header_len;
1287
1288#ifdef DEBUG_MARSHAL_DETAIL
1289 DbgP("marshal_nfs41_setacl: class=0x%x sec_desc_len=%lu\n",
1290 entry->u.Acl.query, entry->buf_len);
1291#endif
1292out:
1293 return status;
1294}
1295
1298 unsigned char *buf,
1299 ULONG buf_len,
1300 ULONG *len)
1301{
1302 return marshal_nfs41_header(entry, buf, buf_len, len);
1303}
1304
1306 IN PRX_CONTEXT RxContext)
1307{
1308 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
1309 unsigned char *buf = LowIoContext->ParamsFor.IoCtl.pInputBuffer;
1311 PMRX_SRV_OPEN srv_open;
1312
1313 RtlCopyMemory(&srv_open, buf, sizeof(HANDLE));
1314#ifdef DEBUG_INVALIDATE_CACHE
1315 DbgP("nfs41_invalidate_cache: received srv_open=%p %wZ\n",
1316 srv_open, srv_open->pAlreadyPrefixedName);
1317#endif
1318 if (MmIsAddressValid(srv_open))
1320 srv_open->pFcb->pNetRoot->pSrvCall, srv_open,
1321 srv_open->Key, ULongToPtr(flag));
1322}
1323
1325 IN PRX_CONTEXT RxContext,
1327 OUT ULONG *len)
1328{
1330 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
1331 ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength;
1332 unsigned char *pbOut = LowIoContext->ParamsFor.IoCtl.pOutputBuffer;
1333
1334 status = SeImpersonateClientEx(entry->psec_ctx, NULL);
1335 if (status != STATUS_SUCCESS) {
1336 print_error("SeImpersonateClientEx failed %x\n", status);
1337 goto out;
1338 }
1339
1340 switch(entry->opcode) {
1341 case NFS41_SHUTDOWN:
1342 status = marshal_nfs41_shutdown(entry, pbOut, cbOut, len);
1343 KeSetEvent(&entry->cond, 0, FALSE);
1344 break;
1345 case NFS41_MOUNT:
1346 status = marshal_nfs41_mount(entry, pbOut, cbOut, len);
1347 break;
1348 case NFS41_UNMOUNT:
1349 status = marshal_nfs41_unmount(entry, pbOut, cbOut, len);
1350 break;
1351 case NFS41_OPEN:
1352 status = marshal_nfs41_open(entry, pbOut, cbOut, len);
1353 break;
1354 case NFS41_READ:
1355 status = marshal_nfs41_rw(entry, pbOut, cbOut, len);
1356 break;
1357 case NFS41_WRITE:
1358 status = marshal_nfs41_rw(entry, pbOut, cbOut, len);
1359 break;
1360 case NFS41_LOCK:
1361 status = marshal_nfs41_lock(entry, pbOut, cbOut, len);
1362 break;
1363 case NFS41_UNLOCK:
1364 status = marshal_nfs41_unlock(entry, pbOut, cbOut, len);
1365 break;
1366 case NFS41_CLOSE:
1367 status = marshal_nfs41_close(entry, pbOut, cbOut, len);
1368 break;
1369 case NFS41_DIR_QUERY:
1370 status = marshal_nfs41_dirquery(entry, pbOut, cbOut, len);
1371 break;
1372 case NFS41_FILE_QUERY:
1373 status = marshal_nfs41_filequery(entry, pbOut, cbOut, len);
1374 break;
1375 case NFS41_FILE_SET:
1376 status = marshal_nfs41_fileset(entry, pbOut, cbOut, len);
1377 break;
1378 case NFS41_EA_SET:
1379 status = marshal_nfs41_easet(entry, pbOut, cbOut, len);
1380 break;
1381 case NFS41_EA_GET:
1382 status = marshal_nfs41_eaget(entry, pbOut, cbOut, len);
1383 break;
1384 case NFS41_SYMLINK:
1385 status = marshal_nfs41_symlink(entry, pbOut, cbOut, len);
1386 break;
1387 case NFS41_VOLUME_QUERY:
1388 status = marshal_nfs41_volume(entry, pbOut, cbOut, len);
1389 break;
1390 case NFS41_ACL_QUERY:
1391 status = marshal_nfs41_getacl(entry, pbOut, cbOut, len);
1392 break;
1393 case NFS41_ACL_SET:
1394 status = marshal_nfs41_setacl(entry, pbOut, cbOut, len);
1395 break;
1396 default:
1398 print_error("Unknown nfs41 ops %d\n", entry->opcode);
1399 }
1400
1401 if (status == STATUS_SUCCESS)
1402 print_hexbuf(0, (unsigned char *)"upcall buffer", pbOut, *len);
1403
1404out:
1405 return status;
1406}
1407
1409 IN DWORD opcode,
1410 IN PSECURITY_CLIENT_CONTEXT clnt_sec_ctx,
1412 IN HANDLE open_state,
1415 OUT nfs41_updowncall_entry **entry_out)
1416{
1421
1424 if (entry == NULL) {
1426 goto out;
1427 }
1428
1431 entry->opcode = opcode;
1433 entry->session = session;
1434 entry->open_state = open_state;
1435 entry->version = version;
1436 if (filename && filename->Length) entry->filename = filename;
1437 else if (filename && !filename->Length) entry->filename = (PUNICODE_STRING)&SLASH;
1438 else entry->filename = (PUNICODE_STRING)&EMPTY_STRING;
1439 /*XXX KeInitializeEvent will bugcheck under verifier if allocated
1440 * from PagedPool? */
1443
1444 if (clnt_sec_ctx == NULL) {
1445 SeCaptureSubjectContext(&sec_ctx);
1448 sec_qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
1449 sec_qos.EffectiveOnly = 0;
1451 1, &entry->sec_ctx);
1452 if (status != STATUS_SUCCESS) {
1453 print_error("nfs41_UpcallCreate: "
1454 "SeCreateClientSecurityFromSubjectContext failed with %x\n",
1455 status);
1457 } else
1458 entry->psec_ctx = &entry->sec_ctx;
1459 SeReleaseSubjectContext(&sec_ctx);
1460 } else
1461 entry->psec_ctx = clnt_sec_ctx;
1462
1463 *entry_out = entry;
1464out:
1465 return status;
1466}
1467
1470 IN DWORD secs)
1471{
1473
1476 if (!entry->async_op) {
1478 timeout.QuadPart = RELATIVE(SECONDS(secs));
1479 /* 02/03/2011 AGLO: it is not clear what the "right" waiting design
1480 * should be. Having non-interruptable waiting seems to be the right
1481 * approach. However, when things go wrong, the only wait to proceed
1482 * is a reboot (since "waits" are not interruptable we can't stop a
1483 * hung task. Having interruptable wait causes issues with security
1484 * context. For now, I'm making CLOSE non-interruptable but keeping
1485 * the rest interruptable so that we don't have to reboot all the time
1486 */
1487 /* 02/15/2011 cbodley: added NFS41_UNLOCK for the same reason. locking
1488 * tests were triggering an interrupted unlock, which led to a bugcheck
1489 * in CloseSrvOpen() */
1490#define MAKE_WAITONCLOSE_NONITERRUPTABLE
1491#ifdef MAKE_WAITONCLOSE_NONITERRUPTABLE
1492 if (entry->opcode == NFS41_CLOSE || entry->opcode == NFS41_UNLOCK)
1495 else {
1497 UserMode, TRUE, &timeout);
1498 }
1499 if (status != STATUS_SUCCESS) {
1500 print_wait_status(1, "[downcall]", status,
1501 opcode2string(entry->opcode), entry, entry->xid);
1502 if (status == STATUS_TIMEOUT)
1504 }
1505#else
1506
1508#endif
1509 print_wait_status(0, "[downcall]", status, opcode2string(entry->opcode),
1510 entry, entry->xid);
1511 } else
1512 goto out;
1513
1514 switch(status) {
1515 case STATUS_SUCCESS: break;
1516 case STATUS_USER_APC:
1517 case STATUS_ALERTED:
1518 default:
1519 ExAcquireFastMutex(&entry->lock);
1520 if (entry->state == NFS41_DONE_PROCESSING) {
1521 ExReleaseFastMutex(&entry->lock);
1522 break;
1523 }
1524 DbgP("[upcall] abandoning %s entry=%p xid=%lld\n",
1525 opcode2string(entry->opcode), entry, entry->xid);
1526 entry->state = NFS41_NOT_WAITING;
1527 ExReleaseFastMutex(&entry->lock);
1528 goto out;
1529 }
1531out:
1532 return status;
1533}
1534
1536 IN PRX_CONTEXT RxContext)
1537{
1540 ULONG len = 0;
1542
1543process_upcall:
1545 if (pEntry) {
1548 ExAcquireFastMutex(&entry->lock);
1550 status = handle_upcall(RxContext, entry, &len);
1551 if (status == STATUS_SUCCESS &&
1554 ExReleaseFastMutex(&entry->lock);
1555 if (status) {
1556 entry->status = status;
1557 KeSetEvent(&entry->cond, 0, FALSE);
1558 RxContext->InformationToReturn = 0;
1559 } else
1560 RxContext->InformationToReturn = len;
1561 }
1562 else {
1565 print_wait_status(0, "[upcall]", status, NULL, NULL, 0);
1566 switch (status) {
1567 case STATUS_SUCCESS: goto process_upcall;
1568 case STATUS_USER_APC:
1569 case STATUS_ALERTED:
1570 default: goto out;
1571 }
1572 }
1573out:
1574 return status;
1575}
1576
1579 unsigned char **buf)
1580{
1582
1583 RtlCopyMemory(&tmp->xid, *buf, sizeof(tmp->xid));
1584 *buf += sizeof(tmp->xid);
1585 RtlCopyMemory(&tmp->opcode, *buf, sizeof(tmp->opcode));
1586 *buf += sizeof(tmp->opcode);
1587 RtlCopyMemory(&tmp->status, *buf, sizeof(tmp->status));
1588 *buf += sizeof(tmp->status);
1589 RtlCopyMemory(&tmp->errno, *buf, sizeof(tmp->errno));
1590 *buf += sizeof(tmp->errno);
1591#ifdef DEBUG_MARSHAL_HEADER
1592 DbgP("[downcall header] xid=%lld opcode=%s status=%d errno=%d\n", tmp->xid,
1593 opcode2string(tmp->opcode), tmp->status, tmp->errno);
1594#endif
1595}
1596
1599 unsigned char **buf)
1600{
1601 RtlCopyMemory(&cur->session, *buf, sizeof(HANDLE));
1602 *buf += sizeof(HANDLE);
1603 RtlCopyMemory(&cur->version, *buf, sizeof(DWORD));
1604 *buf += sizeof(DWORD);
1605 RtlCopyMemory(&cur->u.Mount.lease_time, *buf, sizeof(DWORD));
1606 *buf += sizeof(DWORD);
1607 RtlCopyMemory(cur->u.Mount.FsAttrs, *buf, sizeof(FILE_FS_ATTRIBUTE_INFORMATION));
1608#ifdef DEBUG_MARSHAL_DETAIL
1609 DbgP("unmarshal_nfs41_mount: session pointer 0x%x version %d lease_time "
1610 "%d\n", cur->session, cur->version, cur->u.Mount.lease_time);
1611#endif
1612}
1613
1616 PULONGLONG dest_buf,
1617 unsigned char **buf)
1618{
1619 RtlCopyMemory(dest_buf, *buf, sizeof(ULONGLONG));
1620#ifdef DEBUG_MARSHAL_DETAIL
1621 DbgP("unmarshal_nfs41_setattr: returned ChangeTime %llu\n", *dest_buf);
1622#endif
1623}
1624
1627 unsigned char **buf)
1628{
1630
1631 RtlCopyMemory(&cur->buf_len, *buf, sizeof(cur->buf_len));
1632 *buf += sizeof(cur->buf_len);
1633 RtlCopyMemory(&cur->ChangeTime, *buf, sizeof(ULONGLONG));
1634#ifdef DEBUG_MARSHAL_DETAIL
1635 DbgP("unmarshal_nfs41_rw: returned len %lu ChangeTime %llu\n",
1636 cur->buf_len, cur->ChangeTime);
1637#endif
1638#if 1
1639 /* 08/27/2010: it looks like we really don't need to call
1640 * MmUnmapLockedPages() eventhough we called
1641 * MmMapLockedPagesSpecifyCache() as the MDL passed to us
1642 * is already locked.
1643 */
1644 _SEH2_TRY {
1645 MmUnmapLockedPages(cur->buf, cur->u.ReadWrite.MdlAddress);
1647 NTSTATUS code;
1649 print_error("Call to MmUnmapLockedPages failed due to"
1650 " exception 0x%0x\n", code);
1652 } _SEH2_END;
1653#endif
1654 return status;
1655}
1656
1659 unsigned char **buf)
1660{
1662
1663 _SEH2_TRY {
1664 if (cur->u.Open.EaBuffer)
1665 MmUnmapLockedPages(cur->u.Open.EaBuffer, cur->u.Open.EaMdl);
1667 print_error("MmUnmapLockedPages thrown exception=0x%0x\n", _SEH2_GetExceptionCode());
1668 status = cur->status = STATUS_ACCESS_DENIED;
1669 goto out;
1670 } _SEH2_END;
1671
1672 RtlCopyMemory(&cur->u.Open.binfo, *buf, sizeof(FILE_BASIC_INFORMATION));
1673 *buf += sizeof(FILE_BASIC_INFORMATION);
1674 RtlCopyMemory(&cur->u.Open.sinfo, *buf, sizeof(FILE_STANDARD_INFORMATION));
1675 *buf += sizeof(FILE_STANDARD_INFORMATION);
1676 RtlCopyMemory(&cur->open_state, *buf, sizeof(HANDLE));
1677 *buf += sizeof(HANDLE);
1678 RtlCopyMemory(&cur->u.Open.mode, *buf, sizeof(DWORD));
1679 *buf += sizeof(DWORD);
1680 RtlCopyMemory(&cur->ChangeTime, *buf, sizeof(ULONGLONG));
1681 *buf += sizeof(ULONGLONG);
1682 RtlCopyMemory(&cur->u.Open.deleg_type, *buf, sizeof(DWORD));
1683 *buf += sizeof(DWORD);
1684 if (cur->errno == ERROR_REPARSE) {
1685 RtlCopyMemory(&cur->u.Open.symlink_embedded, *buf, sizeof(BOOLEAN));
1686 *buf += sizeof(BOOLEAN);
1687 RtlCopyMemory(&cur->u.Open.symlink.MaximumLength, *buf,
1688 sizeof(USHORT));
1689 *buf += sizeof(USHORT);
1690 cur->u.Open.symlink.Length = cur->u.Open.symlink.MaximumLength -
1691 sizeof(WCHAR);
1692 cur->u.Open.symlink.Buffer = RxAllocatePoolWithTag(NonPagedPool,
1693 cur->u.Open.symlink.MaximumLength, NFS41_MM_POOLTAG);
1694 if (cur->u.Open.symlink.Buffer == NULL) {
1697 goto out;
1698 }
1699 RtlCopyMemory(cur->u.Open.symlink.Buffer, *buf,
1700 cur->u.Open.symlink.MaximumLength);
1701#ifdef DEBUG_MARSHAL_DETAIL
1702 DbgP("unmarshal_nfs41_open: ERROR_REPARSE -> '%wZ'\n", &cur->u.Open.symlink);
1703#endif
1704 }
1705#ifdef DEBUG_MARSHAL_DETAIL
1706 DbgP("unmarshal_nfs41_open: open_state 0x%x mode %o changeattr %llu "
1707 "deleg_type %d\n", cur->open_state, cur->u.Open.mode,
1708 cur->ChangeTime, cur->u.Open.deleg_type);
1709#endif
1710out:
1711 return status;
1712}
1713
1716 unsigned char **buf)
1717{
1719 ULONG buf_len;
1720
1721 RtlCopyMemory(&buf_len, *buf, sizeof(ULONG));
1722#ifdef DEBUG_MARSHAL_DETAIL
1723 DbgP("unmarshal_nfs41_dirquery: reply size %d\n", buf_len);
1724#endif
1725 *buf += sizeof(ULONG);
1726 _SEH2_TRY {
1727 MmUnmapLockedPages(cur->u.QueryFile.mdl_buf, cur->u.QueryFile.mdl);
1729 NTSTATUS code;
1731 print_error("MmUnmapLockedPages thrown exception=0x%0x\n", code);
1733 } _SEH2_END;
1734 if (buf_len > cur->buf_len)
1735 cur->status = STATUS_BUFFER_TOO_SMALL;
1736 cur->buf_len = buf_len;
1737
1738 return status;
1739}
1740
1743 PVOID attr_value,
1744 ULONG *attr_len,
1745 unsigned char **buf)
1746{
1747 ULONG buf_len;
1748 RtlCopyMemory(&buf_len, *buf, sizeof(ULONG));
1749 if (buf_len > *attr_len) {
1750 cur->status = STATUS_BUFFER_TOO_SMALL;
1751 return;
1752 }
1753 *buf += sizeof(ULONG);
1754 *attr_len = buf_len;
1755 RtlCopyMemory(attr_value, *buf, buf_len);
1756 *buf += buf_len;
1757}
1758
1761 unsigned char **buf)
1762{
1763 RtlCopyMemory(&cur->u.QueryEa.Overflow, *buf, sizeof(ULONG));
1764 *buf += sizeof(ULONG);
1765 RtlCopyMemory(&cur->buf_len, *buf, sizeof(ULONG));
1766 *buf += sizeof(ULONG);
1767 if (cur->u.QueryEa.Overflow != ERROR_INSUFFICIENT_BUFFER) {
1768 RtlCopyMemory(cur->buf, *buf, cur->buf_len);
1769 *buf += cur->buf_len;
1770 }
1771}
1772
1775 unsigned char **buf)
1776{
1777 unmarshal_nfs41_attrget(cur, cur->buf, &cur->buf_len, buf);
1778 RtlCopyMemory(&cur->ChangeTime, *buf, sizeof(LONGLONG));
1779#ifdef DEBUG_MARSHAL_DETAIL
1780 if (cur->u.QueryFile.InfoClass == FileBasicInformation)
1781 DbgP("[unmarshal_nfs41_getattr] ChangeTime %llu\n", cur->ChangeTime);
1782#endif
1783}
1784
1787 unsigned char **buf)
1788{
1790 DWORD buf_len;
1791
1792 RtlCopyMemory(&buf_len, *buf, sizeof(DWORD));
1793 *buf += sizeof(DWORD);
1795 buf_len, NFS41_MM_POOLTAG_ACL);
1796 if (cur->buf == NULL) {
1798 goto out;
1799 }
1800 RtlCopyMemory(cur->buf, *buf, buf_len);
1801 if (buf_len > cur->buf_len)
1802 cur->status = STATUS_BUFFER_TOO_SMALL;
1803 cur->buf_len = buf_len;
1804
1805out:
1806 return status;
1807}
1808
1811 unsigned char **buf)
1812{
1813 if (cur->u.Symlink.set) return;
1814
1815 RtlCopyMemory(&cur->u.Symlink.target->Length, *buf, sizeof(USHORT));
1816 *buf += sizeof(USHORT);
1817 if (cur->u.Symlink.target->Length >
1818 cur->u.Symlink.target->MaximumLength) {
1819 cur->status = STATUS_BUFFER_TOO_SMALL;
1820 return;
1821 }
1822 RtlCopyMemory(cur->u.Symlink.target->Buffer, *buf,
1823 cur->u.Symlink.target->Length);
1824 cur->u.Symlink.target->Length -= sizeof(UNICODE_NULL);
1825}
1826
1828 IN PRX_CONTEXT RxContext)
1829{
1831 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
1832 ULONG in_len = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
1833 unsigned char *buf = LowIoContext->ParamsFor.IoCtl.pInputBuffer;
1836 BOOLEAN found = 0;
1837
1838 print_hexbuf(0, (unsigned char *)"downcall buffer", buf, in_len);
1839
1842 if (tmp == NULL) goto out;
1843
1845
1847 pEntry = &downcall.head;
1848 pEntry = pEntry->Flink;
1849 while (pEntry != NULL) {
1852 if (cur->xid == tmp->xid) {
1853 found = 1;
1854 break;
1855 }
1856 if (pEntry->Flink == &downcall.head)
1857 break;
1858 pEntry = pEntry->Flink;
1859 }
1862 if (!found) {
1863 print_error("Didn't find xid=%lld entry\n", tmp->xid);
1864 goto out_free;
1865 }
1866
1867 ExAcquireFastMutex(&cur->lock);
1868 if (cur->state == NFS41_NOT_WAITING) {
1869 DbgP("[downcall] Nobody is waiting for this request!!!\n");
1870 switch(cur->opcode) {
1871 case NFS41_WRITE:
1872 case NFS41_READ:
1873 MmUnmapLockedPages(cur->buf, cur->u.ReadWrite.MdlAddress);
1874 break;
1875 case NFS41_DIR_QUERY:
1876 MmUnmapLockedPages(cur->u.QueryFile.mdl_buf,
1877 cur->u.QueryFile.mdl);
1878 IoFreeMdl(cur->u.QueryFile.mdl);
1879 break;
1880 case NFS41_OPEN:
1881 if (cur->u.Open.EaMdl) {
1882 MmUnmapLockedPages(cur->u.Open.EaBuffer,
1883 cur->u.Open.EaMdl);
1884 IoFreeMdl(cur->u.Open.EaMdl);
1885 }
1886 break;
1887 }
1888 ExReleaseFastMutex(&cur->lock);
1890 RxFreePool(cur);
1892 goto out_free;
1893 }
1894 cur->state = NFS41_DONE_PROCESSING;
1895 cur->status = tmp->status;
1896 cur->errno = tmp->errno;
1898
1899 if (!tmp->status) {
1900 switch (tmp->opcode) {
1901 case NFS41_MOUNT:
1903 break;
1904 case NFS41_WRITE:
1905 case NFS41_READ:
1907 break;
1908 case NFS41_OPEN:
1910 break;
1911 case NFS41_DIR_QUERY:
1913 break;
1914 case NFS41_FILE_QUERY:
1916 break;
1917 case NFS41_EA_GET:
1919 break;
1920 case NFS41_SYMLINK:
1922 break;
1923 case NFS41_VOLUME_QUERY:
1924 unmarshal_nfs41_attrget(cur, cur->buf, &cur->buf_len, &buf);
1925 break;
1926 case NFS41_ACL_QUERY:
1928 break;
1929 case NFS41_FILE_SET:
1930 unmarshal_nfs41_setattr(cur, &cur->ChangeTime, &buf);
1931 break;
1932 case NFS41_EA_SET:
1933 unmarshal_nfs41_setattr(cur, &cur->ChangeTime, &buf);
1934 break;
1935 case NFS41_ACL_SET:
1936 unmarshal_nfs41_setattr(cur, &cur->ChangeTime, &buf);
1937 break;
1938 }
1939 }
1940 ExReleaseFastMutex(&cur->lock);
1941 if (cur->async_op) {
1942 if (cur->status == STATUS_SUCCESS) {
1943 cur->u.ReadWrite.rxcontext->StoredStatus = STATUS_SUCCESS;
1944 cur->u.ReadWrite.rxcontext->InformationToReturn =
1945 cur->buf_len;
1946 } else {
1947 cur->u.ReadWrite.rxcontext->StoredStatus =
1948 map_readwrite_errors(cur->status);
1949 cur->u.ReadWrite.rxcontext->InformationToReturn = 0;
1950 }
1952 RxLowIoCompletion(cur->u.ReadWrite.rxcontext);
1953 RxFreePool(cur);
1954 } else
1955 KeSetEvent(&cur->cond, 0, FALSE);
1956
1957out_free:
1958 RxFreePool(tmp);
1959out:
1960 return status;
1961}
1962
1964 DWORD version)
1965{
1968
1969 DbgEn();
1972 if (status) goto out;
1973
1975 SeDeleteClientSecurity(&entry->sec_ctx);
1976 if (status) goto out;
1977
1979out:
1980 DbgEx();
1981 return status;
1982}
1983
1985 OUT PHANDLE phSection)
1986{
1989 UNICODE_STRING SectionName;
1990 SECURITY_DESCRIPTOR SecurityDesc;
1991 OBJECT_ATTRIBUTES SectionAttrs;
1992 LARGE_INTEGER nSectionSize;
1993
1994 DbgEn();
1995
1997
1998 /* XXX: setting dacl=NULL grants access to everyone */
1999 status = RtlCreateSecurityDescriptor(&SecurityDesc,
2001 if (status) {
2002 print_error("RtlCreateSecurityDescriptor() failed with %08X\n", status);
2003 goto out;
2004 }
2006 if (status) {
2007 print_error("RtlSetDaclSecurityDescriptor() failed with %08X\n", status);
2008 goto out;
2009 }
2010
2011 InitializeObjectAttributes(&SectionAttrs, &SectionName,
2012 0, NULL, &SecurityDesc);
2013
2014 nSectionSize.QuadPart = sizeof(NFS41NP_SHARED_MEMORY);
2015
2016 status = ZwCreateSection(&hSection, SECTION_MAP_READ | SECTION_MAP_WRITE,
2017 &SectionAttrs, &nSectionSize, PAGE_READWRITE, SEC_COMMIT, NULL);
2018 switch (status) {
2019 case STATUS_SUCCESS:
2020 break;
2022 DbgP("section already created; returning success\n");
2024 goto out;
2025 default:
2026 DbgP("ZwCreateSection failed with %08X\n", status);
2027 goto out;
2028 }
2029out:
2030 DbgEx();
2031 return status;
2032}
2033
2036{
2038 DbgEn();
2040 DbgEx();
2041 return status;
2042}
2043
2044#ifdef __REACTOS__
2046#else
2048#endif
2049 IN OUT PRX_CONTEXT RxContext,
2051{
2053 NFS41GetDeviceExtension(RxContext, DevExt);
2054
2055 DbgEn();
2056
2057 status = SharedMemoryInit(&DevExt->SharedMemorySection);
2058 if (status) {
2059 print_error("InitSharedMemory failed with %08X\n", status);
2061 goto out;
2062 }
2063
2067out:
2068 DbgEx();
2069 return status;
2070}
2071
2072#ifdef __REACTOS__
2074#else
2076#endif
2077 IN OUT PRX_CONTEXT RxContext,
2079{
2081 NFS41GetDeviceExtension(RxContext, DevExt);
2082 DbgEn();
2083 status = SharedMemoryFree(DevExt->SharedMemorySection);
2084 DbgEx();
2085 return status;
2086}
2087
2089 IN PUNICODE_STRING ConnectionName,
2093{
2097
2098#ifdef DEBUG_MOUNT
2099 DbgEn();
2100#endif
2103
2104 print_error("Len %d Buf %p\n", EaLength, EaBuffer);
2105
2106 status = ZwCreateFile(Handle, SYNCHRONIZE, &ObjectAttributes,
2112
2113#ifdef DEBUG_MOUNT
2114 DbgEx();
2115#endif
2116 return status;
2117}
2118
2120 IN PVOID Buffer,
2121 IN ULONG BufferLen,
2122 OUT PUNICODE_STRING pConnectionName,
2123 OUT PVOID *ppEaBuffer,
2124 OUT PULONG pEaLength)
2125{
2127 USHORT NameLength, EaPadding;
2128 ULONG EaLength, BufferLenExpected;
2129 PBYTE ptr;
2130
2131 /* make sure buffer is at least big enough for header */
2132 if (BufferLen < sizeof(USHORT) + sizeof(USHORT) + sizeof(ULONG)) {
2134 print_error("Invalid input buffer.\n");
2135 pConnectionName->Length = pConnectionName->MaximumLength = 0;
2136 *ppEaBuffer = NULL;
2137 *pEaLength = 0;
2138 goto out;
2139 }
2140
2141 ptr = Buffer;
2142 NameLength = *(PUSHORT)ptr;
2143 ptr += sizeof(USHORT);
2144 EaPadding = *(PUSHORT)ptr;
2145 ptr += sizeof(USHORT);
2146 EaLength = *(PULONG)ptr;
2147 ptr += sizeof(ULONG);
2148
2149 /* validate buffer length */
2150 BufferLenExpected = sizeof(USHORT) + sizeof(USHORT) + sizeof(ULONG) +
2151 NameLength + EaPadding + EaLength;
2152 if (BufferLen != BufferLenExpected) {
2154 print_error("Received buffer of length %lu, but expected %lu bytes.\n",
2155 BufferLen, BufferLenExpected);
2156 pConnectionName->Length = pConnectionName->MaximumLength = 0;
2157 *ppEaBuffer = NULL;
2158 *pEaLength = 0;
2159 goto out;
2160 }
2161
2162 pConnectionName->Buffer = (PWCH)ptr;
2163 pConnectionName->Length = NameLength - sizeof(WCHAR);
2164 pConnectionName->MaximumLength = NameLength;
2165
2166 if (EaLength)
2167 *ppEaBuffer = ptr + NameLength + EaPadding;
2168 else
2169 *ppEaBuffer = NULL;
2170 *pEaLength = EaLength;
2171
2172out:
2173 return status;
2174}
2175
2177 IN PRX_CONTEXT RxContext,
2178 OUT PBOOLEAN PostToFsp)
2179{
2182 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
2184 ULONG BufferLen = LowIoContext->ParamsFor.IoCtl.InputBufferLength, EaLength;
2186 BOOLEAN Wait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
2187
2188#ifdef DEBUG_MOUNT
2189 DbgEn();
2190#endif
2191
2192 if (!Wait) {
2193 //just post right now!
2194 DbgP("returning STATUS_PENDING\n");
2195 *PostToFsp = TRUE;
2197 goto out;
2198 }
2199
2202 if (status != STATUS_SUCCESS)
2203 goto out;
2204
2207 ZwClose(Handle);
2208out:
2209#ifdef DEBUG_MOUNT
2210 DbgEx();
2211#endif
2212 return status;
2213}
2214
2215#ifdef ENABLE_TIMINGS
2216void print_op_stat(
2217 const char *op_str,
2218 nfs41_timings *time, BOOLEAN clear)
2219{
2220 DbgP("%-9s: num_ops=%-10d delta_ticks=%-10d size=%-10d\n", op_str,
2221 time->tops, time->tops ? time->ticks/time->tops : 0,
2222 time->sops ? time->size/time->sops : 0);
2223 if (clear) {
2224 time->tops = 0;
2225 time->ticks = 0;
2226 time->size = 0;
2227 time->sops = 0;
2228 }
2229}
2230#endif
2233 DWORD version,
2234 DWORD timeout)
2235{
2238
2239#ifdef DEBUG_MOUNT
2240 DbgEn();
2241#endif
2244 SeDeleteClientSecurity(&entry->sec_ctx);
2245 if (status) goto out;
2246
2249out:
2250#ifdef ENABLE_TIMINGS
2251 print_op_stat("lookup", &lookup, 1);
2252 print_op_stat("open", &open, 1);
2253 print_op_stat("close", &close, 1);
2254 print_op_stat("volume", &volume, 1);
2255 print_op_stat("getattr", &getattr, 1);
2256 print_op_stat("setattr", &setattr, 1);
2257 print_op_stat("getexattr", &getexattr, 1);
2258 print_op_stat("setexattr", &setexattr, 1);
2259 print_op_stat("readdir", &readdir, 1);
2260 print_op_stat("getacl", &getacl, 1);
2261 print_op_stat("setacl", &setacl, 1);
2262 print_op_stat("read", &read, 1);
2263 print_op_stat("write", &write, 1);
2264 print_op_stat("lock", &lock, 1);
2265 print_op_stat("unlock", &unlock, 1);
2266#endif
2267#ifdef DEBUG_MOUNT
2268 DbgEx();
2269#endif
2270 return status;
2271}
2272
2274 IN PRX_CONTEXT RxContext,
2275 OUT PBOOLEAN PostToFsp)
2276{
2278 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
2279 PWCHAR ConnectName = LowIoContext->ParamsFor.IoCtl.pInputBuffer;
2280 ULONG ConnectNameLen = LowIoContext->ParamsFor.IoCtl.InputBufferLength;
2281 HANDLE Handle;
2283 PFILE_OBJECT pFileObject;
2284 BOOLEAN Wait = BooleanFlagOn(RxContext->Flags, RX_CONTEXT_FLAG_WAIT);
2285
2286#ifdef DEBUG_MOUNT
2287 DbgEn();
2288#endif
2289
2290 if (!Wait) {
2291 //just post right now!
2292 *PostToFsp = TRUE;
2293 DbgP("returning STATUS_PENDING\n");
2295 goto out;
2296 }
2297
2298 FileName.Buffer = ConnectName;
2299 FileName.Length = (USHORT) ConnectNameLen - sizeof(WCHAR);
2300 FileName.MaximumLength = (USHORT) ConnectNameLen;
2301
2303 if (status != STATUS_SUCCESS)
2304 goto out;
2305
2307 (PVOID *)&pFileObject, NULL);
2308 if (NT_SUCCESS(status)) {
2309 PV_NET_ROOT VNetRoot;
2310
2311 // VNetRoot exists as FOBx in the FsContext2
2312 VNetRoot = (PV_NET_ROOT) pFileObject->FsContext2;
2313 // make sure the node looks right
2314 if (NodeType(VNetRoot) == RDBSS_NTC_V_NETROOT)
2315 {
2316#ifdef DEBUG_MOUNT
2317 DbgP("Calling RxFinalizeConnection for NetRoot %p from VNetRoot %p\n",
2318 VNetRoot->NetRoot, VNetRoot);
2319#endif
2320 status = RxFinalizeConnection(VNetRoot->NetRoot, VNetRoot, TRUE);
2321 }
2322 else
2324
2325 ObDereferenceObject(pFileObject);
2326 }
2327 ZwClose(Handle);
2328out:
2329#ifdef DEBUG_MOUNT
2330 DbgEx();
2331#endif
2332 return status;
2333}
2334
2335#ifdef __REACTOS__
2337#else
2339#endif
2340 IN OUT PRX_CONTEXT RxContext)
2341{
2343 UCHAR op = RxContext->MajorFunction;
2344 PLOWIO_CONTEXT io_ctx = &RxContext->LowIoContext;
2345 ULONG fsop = io_ctx->ParamsFor.FsCtl.FsControlCode, state;
2346 ULONG in_len = io_ctx->ParamsFor.IoCtl.InputBufferLength;
2348 NFS41GetDeviceExtension(RxContext, DevExt);
2349 DWORD nfs41d_version = 0;
2350
2351 //DbgEn();
2352
2353 print_ioctl(0, op);
2354 switch(op) {
2357 break;
2360 print_fs_ioctl(0, fsop);
2361 switch (fsop) {
2363 nfs41_invalidate_cache(RxContext);
2365 break;
2366 case IOCTL_NFS41_READ:
2367 status = nfs41_upcall(RxContext);
2368 break;
2369 case IOCTL_NFS41_WRITE:
2370 status = nfs41_downcall(RxContext);
2371 break;
2373 status = nfs41_CreateConnection(RxContext, &RxContext->PostRequest);
2374 break;
2376 if (RxContext->RxDeviceObject->NumberOfActiveFcbs > 0) {
2377 DbgP("device has open handles %d\n",
2378 RxContext->RxDeviceObject->NumberOfActiveFcbs);
2379#ifdef __REACTOS__
2380 if (RxContext->RxDeviceObject->pRxNetNameTable != NULL)
2381 {
2382#define DUMP_FCB_TABLE_FROM_NETROOT(N) \
2383{ \
2384 USHORT Bucket2; \
2385 BOOLEAN Release2 = FALSE; \
2386 if (!RxIsFcbTableLockAcquired(&(N)->FcbTable)) \
2387 { \
2388 RxAcquireFcbTableLockExclusive(&(N)->FcbTable, TRUE); \
2389 Release2 = TRUE; \
2390 } \
2391 for (Bucket2 = 0; Bucket2 < (N)->FcbTable.NumberOfBuckets; ++Bucket2) \
2392 { \
2393 PLIST_ENTRY Entry2; \
2394 for (Entry2 = (N)->FcbTable.HashBuckets[Bucket2].Flink; \
2395 Entry2 != &(N)->FcbTable.HashBuckets[Bucket2]; \
2396 Entry2 = Entry2->Flink) \
2397 { \
2398 PFCB Fcb; \
2399 Fcb = CONTAINING_RECORD(Entry2, FCB, FcbTableEntry.HashLinks); \
2400 DbgP("Fcb: %p still has %d references\n", Fcb, Fcb->NodeReferenceCount); \
2401 DbgP("It is for: %wZ\n", &Fcb->FcbTableEntry.Path); \
2402 } \
2403 } \
2404 if (Release2) \
2405 { \
2406 RxReleaseFcbTableLock(&(N)->FcbTable); \
2407 } \
2408}
2409 USHORT Bucket;
2411
2412 if (!RxIsPrefixTableLockAcquired(RxContext->RxDeviceObject->pRxNetNameTable))
2413 {
2414 RxAcquirePrefixTableLockExclusive(RxContext->RxDeviceObject->pRxNetNameTable, TRUE);
2415 Release = TRUE;
2416 }
2417
2418 for (Bucket = 0; Bucket < RxContext->RxDeviceObject->pRxNetNameTable->TableSize; ++Bucket)
2419 {
2421
2422 for (Entry = RxContext->RxDeviceObject->pRxNetNameTable->HashBuckets[Bucket].Flink;
2423 Entry != &RxContext->RxDeviceObject->pRxNetNameTable->HashBuckets[Bucket];
2424 Entry = Entry->Flink)
2425 {
2426 PVOID Container;
2427
2428 Container = CONTAINING_RECORD(Entry, RX_PREFIX_ENTRY, HashLinks)->ContainingRecord;
2429 switch (NodeType(Container) & ~RX_SCAVENGER_MASK)
2430 {
2431 case RDBSS_NTC_NETROOT:
2432 {
2433 PNET_ROOT NetRoot;
2434
2435 NetRoot = Container;
2436 DUMP_FCB_TABLE_FROM_NETROOT(NetRoot);
2437 break;
2438 }
2439
2441 {
2442 PV_NET_ROOT VNetRoot;
2443
2444 VNetRoot = Container;
2445 if (VNetRoot->NetRoot != NULL)
2446 {
2447 PNET_ROOT NetRoot;
2448
2449 NetRoot = VNetRoot->NetRoot;
2450 DUMP_FCB_TABLE_FROM_NETROOT(NetRoot);
2451 }
2452 break;
2453 }
2454
2455 default:
2456 {
2457 DbgP("Other node found: %x\n", NodeType(Container));
2458 break;
2459 }
2460 }
2461 }
2462 }
2463
2464 if (Release)
2465 {
2466 RxReleasePrefixTableLock(RxContext->RxDeviceObject->pRxNetNameTable);
2467 }
2468#undef DUMP_FCB_TABLE_FROM_NETROOT
2469 }
2470 else
2471 {
2472 DbgP("RxNetNameTable is NULL for: %p\n", RxContext->RxDeviceObject);
2473 }
2474#endif
2476 break;
2477 }
2478 status = nfs41_DeleteConnection(RxContext, &RxContext->PostRequest);
2479 break;
2482
2483 if (io_ctx->ParamsFor.IoCtl.OutputBufferLength >= sizeof(ULONG)) {
2484 // map the states to control app's equivalents
2486 switch (nfs41_start_state) {
2490 break;
2493 break;
2496 break;
2497 }
2498 *(ULONG *)io_ctx->ParamsFor.IoCtl.pOutputBuffer = state;
2499 RxContext->InformationToReturn = sizeof(ULONG);
2501 } else
2503 break;
2504 case IOCTL_NFS41_START:
2506 if (in_len >= sizeof(DWORD)) {
2507 RtlCopyMemory(&nfs41d_version, buf, sizeof(DWORD));
2508 DbgP("NFS41 Daemon sent start request with version %d\n",
2509 nfs41d_version);
2510 DbgP("Currently used NFS41 Daemon version is %d\n",
2511 DevExt->nfs41d_version);
2512 DevExt->nfs41d_version = nfs41d_version;
2513 }
2514 switch(nfs41_start_state) {
2520 //lack of break is intentional
2522 status = RxStartMinirdr(RxContext, &RxContext->PostRequest);
2524 DbgP("redirector started\n");
2526 } else if (status == STATUS_PENDING &&
2527 RxContext->PostRequest == TRUE) {
2528 DbgP("RxStartMinirdr pending %08lx\n", status);
2530 }
2531 break;
2534 break;
2535 default:
2537 }
2538 break;
2539 case IOCTL_NFS41_STOP:
2541 nfs41_shutdown_daemon(DevExt->nfs41d_version);
2542 if (RxContext->RxDeviceObject->NumberOfActiveFcbs > 0) {
2543 DbgP("device has open handles %d\n",
2544 RxContext->RxDeviceObject->NumberOfActiveFcbs);
2546 break;
2547 }
2548
2553
2554 status = RxStopMinirdr(RxContext, &RxContext->PostRequest);
2555 DbgP("RxStopMinirdr status %08lx\n", status);
2556 if (status == STATUS_PENDING && RxContext->PostRequest == TRUE )
2558 break;
2559 default:
2561 };
2562 break;
2563 default:
2565 };
2566
2567 //DbgEx();
2568 return status;
2569}
2570
2571#ifndef __REACTOS__
2573 PMRX_SRVCALL_CALLBACK_CONTEXT pCallbackContext)
2574{
2575#else
2577 PVOID pContext)
2578{
2579 PMRX_SRVCALL_CALLBACK_CONTEXT pCallbackContext = pContext;
2580#endif
2582 PMRX_SRVCALL_CALLBACK_CONTEXT SCCBC = pCallbackContext;
2583 PMRX_SRV_CALL pSrvCall;
2584 PMRX_SRVCALLDOWN_STRUCTURE SrvCalldownStructure =
2586 PNFS41_SERVER_ENTRY pServerEntry = NULL;
2587
2588#ifdef DEBUG_MOUNT
2589 DbgEn();
2590#endif
2591
2592 pSrvCall = SrvCalldownStructure->SrvCall;
2593
2594 ASSERT( pSrvCall );
2595 ASSERT( NodeType(pSrvCall) == RDBSS_NTC_SRVCALL );
2596 print_srv_call(0, pSrvCall);
2597
2598 // validate the server name with the test name of 'pnfs'
2599#ifdef DEBUG_MOUNT
2600 DbgP("SrvCall: Connection Name Length: %d %wZ\n",
2601 pSrvCall->pSrvCallName->Length, pSrvCall->pSrvCallName);
2602#endif
2603
2604 if (pSrvCall->pSrvCallName->Length > SERVER_NAME_BUFFER_SIZE) {
2605 print_error("Server name '%wZ' too long for server entry (max %u)\n",
2608 goto out;
2609 }
2610
2611 /* Let's create our own representation of the server */
2614 if (pServerEntry == NULL) {
2616 goto out;
2617 }
2618 RtlZeroMemory(pServerEntry, sizeof(NFS41_SERVER_ENTRY));
2619
2620 pServerEntry->Name.Buffer = pServerEntry->NameBuffer;
2621 pServerEntry->Name.Length = pSrvCall->pSrvCallName->Length;
2623 RtlCopyMemory(pServerEntry->Name.Buffer, pSrvCall->pSrvCallName->Buffer,
2624 pServerEntry->Name.Length);
2625
2626 pCallbackContext->RecommunicateContext = pServerEntry;
2627#ifdef __REACTOS__
2628 InterlockedExchangePointer((void * volatile *)&pServerEntry->pRdbssSrvCall, pSrvCall);
2629#else
2630 InterlockedExchangePointer(&pServerEntry->pRdbssSrvCall, pSrvCall);
2631#endif
2632
2633out:
2634 SCCBC->Status = status;
2635 SrvCalldownStructure->CallBack(SCCBC);
2636
2637#ifdef DEBUG_MOUNT
2638 DbgEx();
2639#endif
2640 return status;
2641}
2642
2643#ifdef __REACTOS__
2644VOID NTAPI _nfs41_CreateSrvCall_v(
2645 PVOID pCallbackContext)
2646{
2647 _nfs41_CreateSrvCall(pCallbackContext);
2648}
2649#endif
2650
2651#ifdef __REACTOS__
2653#else
2655#endif
2656 PMRX_SRV_CALL pSrvCall,
2657 PMRX_SRVCALL_CALLBACK_CONTEXT pCallbackContext)
2658{
2660
2661 ASSERT( pSrvCall );
2662 ASSERT( NodeType(pSrvCall) == RDBSS_NTC_SRVCALL );
2663
2665 DbgP("executing with RDBSS context\n");
2666 status = _nfs41_CreateSrvCall(pCallbackContext);
2667 } else {
2669#ifdef __REACTOS__
2670 _nfs41_CreateSrvCall_v, pCallbackContext);
2671#else
2672 _nfs41_CreateSrvCall, pCallbackContext);
2673#endif
2674 if (status != STATUS_SUCCESS) {
2675 print_error("RxDispatchToWorkerThread returned status %08lx\n",
2676 status);
2677 pCallbackContext->Status = status;
2678 pCallbackContext->SrvCalldownStructure->CallBack(pCallbackContext);
2680 }
2681 }
2682 /* RDBSS expects MRxCreateSrvCall to return STATUS_PENDING */
2683 if (status == STATUS_SUCCESS)
2685
2686 return status;
2687}
2688
2689#ifdef __REACTOS__
2691#else
2693#endif
2694 IN OUT PMRX_SRV_CALL pSrvCall,
2695 IN BOOLEAN ThisMinirdrIsTheWinner,
2696 IN OUT PVOID pSrvCallContext)
2697{
2699 PNFS41_SERVER_ENTRY pServerEntry;
2700
2701 pServerEntry = (PNFS41_SERVER_ENTRY)pSrvCallContext;
2702
2703 if (!ThisMinirdrIsTheWinner) {
2704 ASSERT(1);
2705 goto out;
2706 }
2707
2708 pSrvCall->Context = pServerEntry;
2709out:
2710 return status;
2711}
2712
2714 DWORD status)
2715{
2716 switch (status) {
2717 case NO_ERROR: return STATUS_SUCCESS;
2722 default:
2723 print_error("failed to map windows error %d to NTSTATUS; "
2724 "defaulting to STATUS_INSUFFICIENT_RESOURCES\n", status);
2726 }
2727}
2728
2733 DWORD *version,
2735{
2738
2739#ifdef DEBUG_MOUNT
2740 DbgEn();
2741 DbgP("Server Name %wZ Mount Point %wZ SecFlavor %d\n",
2742 &config->SrvName, &config->MntPt, sec_flavor);
2743#endif
2746 if (status) goto out;
2747
2748 entry->u.Mount.srv_name = &config->SrvName;
2749 entry->u.Mount.root = &config->MntPt;
2750 entry->u.Mount.rsize = config->ReadSize;
2751 entry->u.Mount.wsize = config->WriteSize;
2752 entry->u.Mount.sec_flavor = sec_flavor;
2753 entry->u.Mount.FsAttrs = FsAttrs;
2754
2756 SeDeleteClientSecurity(&entry->sec_ctx);
2757 if (status) goto out;
2758 *session = entry->session;
2759 if (entry->u.Mount.lease_time > config->timeout)
2760 config->timeout = entry->u.Mount.lease_time;
2761
2762 /* map windows ERRORs to NTSTATUS */
2763 status = map_mount_errors(entry->status);
2764 if (status == STATUS_SUCCESS)
2765 *version = entry->version;
2767out:
2768#ifdef DEBUG_MOUNT
2769 DbgEx();
2770#endif
2771 return status;
2772}
2773
2774/* TODO: move mount config stuff to another file -cbodley */
2775
2778{
2780
2783 Config->ReadOnly = FALSE;
2784 Config->write_thru = FALSE;
2785 Config->nocache = FALSE;
2786 Config->SrvName.Length = 0;
2787 Config->SrvName.MaximumLength = SERVER_NAME_BUFFER_SIZE;
2788 Config->SrvName.Buffer = Config->srv_buffer;
2789 Config->MntPt.Length = 0;
2790 Config->MntPt.MaximumLength = MAX_PATH;
2791 Config->MntPt.Buffer = Config->mntpt_buffer;
2792 Config->SecFlavor.Length = 0;
2793 Config->SecFlavor.MaximumLength = MAX_SEC_FLAVOR_LEN;
2794 Config->SecFlavor.Buffer = Config->sec_flavor;
2795 RtlCopyUnicodeString(&Config->SecFlavor, &AUTH_SYS_NAME);
2796 Config->timeout = UPCALL_TIMEOUT_DEFAULT;
2797}
2798
2801 IN PUNICODE_STRING usValue,
2803{
2805
2806 /* if no value is specified, assume TRUE
2807 * if a value is specified, it must be a '1' */
2808 if (Option->EaValueLength == 0 || *usValue->Buffer == L'1')
2809 *Value = TRUE;
2810 else
2811 *Value = FALSE;
2812
2813 DbgP(" '%ls' -> '%wZ' -> %u\n",
2814 (LPWSTR)Option->EaName, usValue, *Value);
2815 return status;
2816}
2817
2820 IN PUNICODE_STRING usValue,
2822 IN DWORD Minimum,
2823 IN DWORD Maximum)
2824{
2826 LPWSTR Name = (LPWSTR)Option->EaName;
2827
2828 if (Option->EaValueLength) {
2829 status = RtlUnicodeStringToInteger(usValue, 0, Value);
2830 if (status == STATUS_SUCCESS) {
2831#ifdef IMPOSE_MINMAX_RWSIZES
2832 if (*Value < Minimum)
2833 *Value = Minimum;
2834 if (*Value > Maximum)
2835 *Value = Maximum;
2836 DbgP(" '%ls' -> '%wZ' -> %lu\n", Name, usValue, *Value);
2837#endif
2838 }
2839 else
2840 print_error("Failed to convert %s='%wZ' to unsigned long.\n",
2841 Name, usValue);
2842 }
2843
2844 return status;
2845}
2846
2851{
2854 LPWSTR Name;
2855 size_t NameLen;
2856 UNICODE_STRING usValue;
2857 Option = EaBuffer;
2858 while (status == STATUS_SUCCESS) {
2859 Name = (LPWSTR)Option->EaName;
2860 NameLen = Option->EaNameLength/sizeof(WCHAR);
2861
2862 usValue.Length = usValue.MaximumLength = Option->EaValueLength;
2863 usValue.Buffer = (PWCH)(Option->EaName +
2864 Option->EaNameLength + sizeof(WCHAR));
2865
2866 if (wcsncmp(L"ro", Name, NameLen) == 0) {
2867 status = nfs41_MountConfig_ParseBoolean(Option, &usValue,
2868 &Config->ReadOnly);
2869 }
2870 else if (wcsncmp(L"writethru", Name, NameLen) == 0) {
2871 status = nfs41_MountConfig_ParseBoolean(Option, &usValue,
2872 &Config->write_thru);
2873 }
2874 else if (wcsncmp(L"nocache", Name, NameLen) == 0) {
2875 status = nfs41_MountConfig_ParseBoolean(Option, &usValue,
2876 &Config->nocache);
2877 }
2878 else if (wcsncmp(L"timeout", Name, NameLen) == 0) {
2879 status = nfs41_MountConfig_ParseDword(Option, &usValue,
2880 &Config->timeout, UPCALL_TIMEOUT_DEFAULT,
2882 }
2883 else if (wcsncmp(L"rsize", Name, NameLen) == 0) {
2884 status = nfs41_MountConfig_ParseDword(Option, &usValue,
2885 &Config->ReadSize, MOUNT_CONFIG_RW_SIZE_MIN,
2887 }
2888 else if (wcsncmp(L"wsize", Name, NameLen) == 0) {
2889 status = nfs41_MountConfig_ParseDword(Option, &usValue,
2890 &Config->WriteSize, MOUNT_CONFIG_RW_SIZE_MIN,
2892 }
2893 else if (wcsncmp(L"srvname", Name, NameLen) == 0) {
2894 if (usValue.Length > Config->SrvName.MaximumLength)
2896 else
2897 RtlCopyUnicodeString(&Config->SrvName, &usValue);
2898 }
2899 else if (wcsncmp(L"mntpt", Name, NameLen) == 0) {
2900 if (usValue.Length > Config->MntPt.MaximumLength)
2902 else
2903 RtlCopyUnicodeString(&Config->MntPt, &usValue);
2904 }
2905 else if (wcsncmp(L"sec", Name, NameLen) == 0) {
2906 if (usValue.Length > Config->SecFlavor.MaximumLength)
2908 else
2909 RtlCopyUnicodeString(&Config->SecFlavor, &usValue);
2910 }
2911 else {
2913 print_error("Unrecognized option '%ls' -> '%wZ'\n",
2914 Name, usValue);
2915 }
2916
2917 if (Option->NextEntryOffset == 0)
2918 break;
2919
2920 Option = (PFILE_FULL_EA_INFORMATION)
2921 ((PBYTE)Option + Option->NextEntryOffset);
2922 }
2923
2924 return status;
2925}
2926
2928 IN PUNICODE_STRING SrvCallName,
2929 IN PUNICODE_STRING NetRootName)
2930{
2932
2933 if (NetRootName->Length == SrvCallName->Length + NfsPrefix.Length) {
2934 const UNICODE_STRING NetRootPrefix = {
2935 NfsPrefix.Length,
2936 NetRootName->MaximumLength - SrvCallName->Length,
2937 &NetRootName->Buffer[SrvCallName->Length/2]
2938 };
2939 if (RtlCompareUnicodeString(&NetRootPrefix, &NfsPrefix, FALSE) == 0)
2941 }
2942 return status;
2943}
2944
2946 IN PUNICODE_STRING sec_flavor_name,
2948{
2949 if (RtlCompareUnicodeString(sec_flavor_name, &AUTH_SYS_NAME, FALSE) == 0)
2951 else if (RtlCompareUnicodeString(sec_flavor_name, &AUTHGSS_KRB5_NAME, FALSE) == 0)
2953 else if (RtlCompareUnicodeString(sec_flavor_name, &AUTHGSS_KRB5I_NAME, FALSE) == 0)
2955 else if (RtlCompareUnicodeString(sec_flavor_name, &AUTHGSS_KRB5P_NAME, FALSE) == 0)
2957 else return STATUS_INVALID_PARAMETER;
2958 return STATUS_SUCCESS;
2959}
2960
2962 PLUID id)
2963{
2967 SECURITY_CLIENT_CONTEXT clnt_sec_ctx;
2968
2969 SeCaptureSubjectContext(&sec_ctx);
2972 sec_qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
2973 sec_qos.EffectiveOnly = 0;
2974 status = SeCreateClientSecurityFromSubjectContext(&sec_ctx, &sec_qos, 1,
2975 &clnt_sec_ctx);
2976 if (status) {
2977 print_error("nfs41_GetLUID: SeCreateClientSecurityFromSubjectContext "
2978 "failed %x\n", status);
2979 goto release_sec_ctx;
2980 }
2982 if (status) {
2983 print_error("SeQueryAuthenticationIdToken failed %x\n", status);
2984 goto release_clnt_sec_ctx;
2985 }
2986release_clnt_sec_ctx:
2987 SeDeleteClientSecurity(&clnt_sec_ctx);
2988release_sec_ctx:
2989 SeReleaseSubjectContext(&sec_ctx);
2990
2991 return status;
2992}
2993
2997{
3001
3004 sec_qos.ImpersonationLevel = level;
3005 sec_qos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
3006 sec_qos.EffectiveOnly = 0;
3007 status = SeCreateClientSecurityFromSubjectContext(&ctx, &sec_qos, 1, out_ctx);
3008 if (status != STATUS_SUCCESS) {
3009 print_error("SeCreateClientSecurityFromSubjectContext "
3010 "failed with %x\n", status);
3011 }
3012#ifdef DEBUG_MOUNT
3013 DbgP("Created client security token %p\n", out_ctx->ClientToken);
3014#endif
3016
3017 return status;
3018}
3019
3020#ifdef __REACTOS__
3022#else
3024#endif
3025 IN OUT PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext)
3026{
3030 pCreateNetRootContext->pVNetRoot;
3031 __notnull PMRX_NET_ROOT pNetRoot = pVNetRoot->pNetRoot;
3032 __notnull PMRX_SRV_CALL pSrvCall = pNetRoot->pSrvCall;
3033 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
3034 NFS41GetVNetRootExtension(pVNetRoot);
3035 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
3036 NFS41GetNetRootExtension(pNetRoot);
3037 NFS41GetDeviceExtension(pCreateNetRootContext->RxContext,DevExt);
3038 DWORD nfs41d_version = DevExt->nfs41d_version;
3039 nfs41_mount_entry *existing_mount = NULL;
3040 LUID luid;
3041 BOOLEAN found_existing_mount = FALSE, found_matching_flavor = FALSE;
3042
3043 ASSERT((NodeType(pNetRoot) == RDBSS_NTC_NETROOT) &&
3044 (NodeType(pNetRoot->pSrvCall) == RDBSS_NTC_SRVCALL));
3045
3046#ifdef DEBUG_MOUNT
3047 DbgEn();
3048 print_srv_call(0, pSrvCall);
3049 print_net_root(0, pNetRoot);
3050 print_v_net_root(0, pVNetRoot);
3051
3052 DbgP("pVNetRoot=%p pNetRoot=%p pSrvCall=%p\n", pVNetRoot, pNetRoot, pSrvCall);
3053 DbgP("pNetRoot=%wZ Type=%d pSrvCallName=%wZ VirtualNetRootStatus=0x%x "
3054 "NetRootStatus=0x%x\n", pNetRoot->pNetRootName,
3055 pNetRoot->Type, pSrvCall->pSrvCallName,
3056 pCreateNetRootContext->VirtualNetRootStatus,
3057 pCreateNetRootContext->NetRootStatus);
3058#endif
3059
3060 if (pNetRoot->Type != NET_ROOT_DISK && pNetRoot->Type != NET_ROOT_WILD) {
3061 print_error("nfs41_CreateVNetRoot: Unsupported NetRoot Type %u\n",
3062 pNetRoot->Type);
3064 goto out;
3065 }
3066
3067 pVNetRootContext->session = INVALID_HANDLE_VALUE;
3068
3069 /* In order to cooperate with other network providers, we must
3070 * only claim paths of the form '\\server\nfs4\path' */
3071 status = has_nfs_prefix(pSrvCall->pSrvCallName, pNetRoot->pNetRootName);
3072 if (status) {
3073 print_error("nfs41_CreateVNetRoot: NetRootName %wZ doesn't match "
3074 "'\\nfs4'!\n", pNetRoot->pNetRootName);
3075 goto out;
3076 }
3077 pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_GOOD;
3078 pNetRoot->DeviceType = FILE_DEVICE_DISK;
3079
3082 if (Config == NULL) {
3084 goto out;
3085 }
3087
3088 if (pCreateNetRootContext->RxContext->Create.EaLength) {
3089 /* parse the extended attributes for mount options */
3091 pCreateNetRootContext->RxContext->Create.EaBuffer,
3092 pCreateNetRootContext->RxContext->Create.EaLength,
3093 Config);
3094 if (status != STATUS_SUCCESS)
3095 goto out_free;
3096 pVNetRootContext->read_only = Config->ReadOnly;
3097 pVNetRootContext->write_thru = Config->write_thru;
3098 pVNetRootContext->nocache = Config->nocache;
3099 } else {
3100 /* use the SRV_CALL name (without leading \‍) as the hostname */
3101 Config->SrvName.Buffer = pSrvCall->pSrvCallName->Buffer + 1;
3102 Config->SrvName.Length =
3103 pSrvCall->pSrvCallName->Length - sizeof(WCHAR);
3104 Config->SrvName.MaximumLength =
3105 pSrvCall->pSrvCallName->MaximumLength - sizeof(WCHAR);
3106 }
3107 pVNetRootContext->MountPathLen = Config->MntPt.Length;
3108 pVNetRootContext->timeout = Config->timeout;
3109
3110 status = map_sec_flavor(&Config->SecFlavor, &pVNetRootContext->sec_flavor);
3111 if (status != STATUS_SUCCESS) {
3112 DbgP("Invalid rpcsec security flavor %wZ\n", &Config->SecFlavor);
3113 goto out_free;
3114 }
3115
3116 status = nfs41_GetLUID(&luid);
3117 if (status)
3118 goto out_free;
3119
3120 if (!pNetRootContext->mounts_init) {
3121#ifdef DEBUG_MOUNT
3122 DbgP("Initializing mount array\n");
3123#endif
3124 ExInitializeFastMutex(&pNetRootContext->mountLock);
3125 InitializeListHead(&pNetRootContext->mounts.head);
3126 pNetRootContext->mounts_init = TRUE;
3127 } else {
3129
3130 ExAcquireFastMutex(&pNetRootContext->mountLock);
3131 pEntry = &pNetRootContext->mounts.head;
3132 pEntry = pEntry->Flink;
3133 while (pEntry != NULL) {
3134 existing_mount = (nfs41_mount_entry *)CONTAINING_RECORD(pEntry,
3136#ifdef DEBUG_MOUNT
3137 DbgP("comparing %x.%x with %x.%x\n", luid.HighPart, luid.LowPart,
3138 existing_mount->login_id.HighPart, existing_mount->login_id.LowPart);
3139#endif
3140 if (RtlEqualLuid(&luid, &existing_mount->login_id)) {
3141#ifdef DEBUG_MOUNT
3142 DbgP("Found a matching LUID entry\n");
3143#endif
3144 found_existing_mount = TRUE;
3145 switch(pVNetRootContext->sec_flavor) {
3146 case RPCSEC_AUTH_SYS:
3147 if (existing_mount->authsys_session != INVALID_HANDLE_VALUE)
3148 pVNetRootContext->session =
3149 existing_mount->authsys_session;
3150 break;
3152 if (existing_mount->gssi_session != INVALID_HANDLE_VALUE)
3153 pVNetRootContext->session = existing_mount->gss_session;
3154 break;
3156 if (existing_mount->gss_session != INVALID_HANDLE_VALUE)
3157 pVNetRootContext->session = existing_mount->gssi_session;
3158 break;
3160 if (existing_mount->gssp_session != INVALID_HANDLE_VALUE)
3161 pVNetRootContext->session = existing_mount->gssp_session;
3162 break;
3163 }
3164 if (pVNetRootContext->session &&
3165 pVNetRootContext->session != INVALID_HANDLE_VALUE)
3166 found_matching_flavor = 1;
3167 break;
3168 }
3169 if (pEntry->Flink == &pNetRootContext->mounts.head)
3170 break;
3171 pEntry = pEntry->Flink;
3172 }
3173 ExReleaseFastMutex(&pNetRootContext->mountLock);
3174#ifdef DEBUG_MOUNT
3175 if (!found_matching_flavor)
3176 DbgP("Didn't find matching security flavor\n");
3177#endif
3178 }
3179
3180 /* send the mount upcall */
3181 status = nfs41_mount(Config, pVNetRootContext->sec_flavor,
3182 &pVNetRootContext->session, &nfs41d_version,
3183 &pVNetRootContext->FsAttrs);
3184 if (status != STATUS_SUCCESS) {
3185 BOOLEAN MountsEmpty;
3186 nfs41_IsListEmpty(pNetRootContext->mountLock,
3187 pNetRootContext->mounts, MountsEmpty);
3188 if (!found_existing_mount && MountsEmpty)
3189 pNetRootContext->mounts_init = FALSE;
3190 pVNetRootContext->session = INVALID_HANDLE_VALUE;
3191 goto out_free;
3192 }
3193 pVNetRootContext->timeout = Config->timeout;
3194
3195 if (!found_existing_mount) {
3196 /* create a new mount entry and add it to the list */
3200 if (entry == NULL) {
3202 goto out_free;
3203 }
3204 entry->authsys_session = entry->gss_session =
3205 entry->gssi_session = entry->gssp_session = INVALID_HANDLE_VALUE;
3206 switch (pVNetRootContext->sec_flavor) {
3207 case RPCSEC_AUTH_SYS:
3208 entry->authsys_session = pVNetRootContext->session; break;
3210 entry->gss_session = pVNetRootContext->session; break;
3212 entry->gssi_session = pVNetRootContext->session; break;
3214 entry->gssp_session = pVNetRootContext->session; break;
3215 }
3216 RtlCopyLuid(&entry->login_id, &luid);
3217 nfs41_AddEntry(pNetRootContext->mountLock,
3218 pNetRootContext->mounts, entry);
3219 } else if (!found_matching_flavor) {
3220 ASSERT(existing_mount != NULL);
3221 /* modify existing mount entry */
3222#ifdef DEBUG_MOUNT
3223 DbgP("Using existing %d flavor session 0x%x\n",
3224 pVNetRootContext->sec_flavor);
3225#endif
3226 switch (pVNetRootContext->sec_flavor) {
3227 case RPCSEC_AUTH_SYS:
3228 existing_mount->authsys_session = pVNetRootContext->session; break;
3230 existing_mount->gss_session = pVNetRootContext->session; break;
3232 existing_mount->gssi_session = pVNetRootContext->session; break;
3234 existing_mount->gssp_session = pVNetRootContext->session; break;
3235 }
3236 }
3237 pNetRootContext->nfs41d_version = nfs41d_version;
3238#ifdef DEBUG_MOUNT
3239 DbgP("Saving new session 0x%x\n", pVNetRootContext->session);
3240#endif
3241#ifdef STORE_MOUNT_SEC_CONTEXT
3243 &pVNetRootContext->mount_sec_ctx);
3244#endif
3245
3246out_free:
3248out:
3249 pCreateNetRootContext->VirtualNetRootStatus = status;
3250 if (pNetRoot->Context == NULL)
3251 pCreateNetRootContext->NetRootStatus = status;
3252 pCreateNetRootContext->Callback(pCreateNetRootContext);
3253
3254 /* RDBSS expects that MRxCreateVNetRoot returns STATUS_PENDING
3255 * on success or failure */
3257#ifdef DEBUG_MOUNT
3258 DbgEx();
3259#endif
3260 return status;
3261}
3262
3263#ifdef __REACTOS__
3265#else
3267#endif
3268 IN PUNICODE_STRING FilePathName,
3269 IN PMRX_SRV_CALL SrvCall,
3270 OUT PUNICODE_STRING NetRootName,
3271 OUT PUNICODE_STRING RestOfName OPTIONAL)
3272{
3273 ULONG length = FilePathName->Length;
3274 PWCH w = FilePathName->Buffer;
3275 PWCH wlimit = (PWCH)(((PCHAR)w)+length);
3276 PWCH wlow;
3277
3278 w += (SrvCall->pSrvCallName->Length/sizeof(WCHAR));
3279 NetRootName->Buffer = wlow = w;
3280 /* parse the entire path into NetRootName */
3281#if USE_ENTIRE_PATH
3282 w = wlimit;
3283#else
3284 for (;;) {
3285 if (w >= wlimit)
3286 break;
3287 if ((*w == OBJ_NAME_PATH_SEPARATOR) && (w != wlow))
3288 break;
3289 w++;
3290 }
3291#endif
3292 NetRootName->Length = NetRootName->MaximumLength
3293 = (USHORT)((PCHAR)w - (PCHAR)wlow);
3294#ifdef DEBUG_MOUNT
3295 DbgP("In: pSrvCall %p PathName=%wZ SrvCallName=%wZ Out: NetRootName=%wZ\n",
3296 SrvCall, FilePathName, SrvCall->pSrvCallName, NetRootName);
3297#endif
3298 return;
3299
3300}
3301
3302#ifdef __REACTOS__
3304#else
3306#endif
3307 PMRX_SRV_CALL pSrvCall,
3308 BOOLEAN Force)
3309{
3311 PNFS41_SERVER_ENTRY pServerEntry = (PNFS41_SERVER_ENTRY)(pSrvCall->Context);
3312
3313#ifdef DEBUG_MOUNT
3314 DbgEn();
3315#endif
3316 print_srv_call(0, pSrvCall);
3317
3318 if (pSrvCall->Context == NULL)
3319 goto out;
3320
3321#ifndef __REACTOS__
3323 NULL, pSrvCall);
3324#else
3325 InterlockedCompareExchangePointer((void * volatile *)&pServerEntry->pRdbssSrvCall,
3326 NULL, pSrvCall);
3327#endif
3328 RxFreePool(pServerEntry);
3329
3330 pSrvCall->Context = NULL;
3331out:
3332#ifdef DEBUG_MOUNT
3333 DbgEx();
3334#endif
3335 return status;
3336}
3337
3338#ifdef __REACTOS__
3340#else
3342#endif
3343 IN OUT PMRX_NET_ROOT pNetRoot,
3345{
3347 PNFS41_NETROOT_EXTENSION pNetRootContext =
3350 nfs41_mount_entry *mount_tmp;
3351
3352#ifdef DEBUG_MOUNT
3353 DbgEn();
3354 print_net_root(1, pNetRoot);
3355#endif
3356
3357 if (pNetRoot->Type != NET_ROOT_DISK && pNetRoot->Type != NET_ROOT_WILD) {
3359 goto out;
3360 }
3361
3362 if (pNetRootContext == NULL || !pNetRootContext->mounts_init) {
3363 print_error("nfs41_FinalizeNetRoot: No valid session established\n");
3364 goto out;
3365 }
3366
3367 if (pNetRoot->NumberOfFcbs > 0 || pNetRoot->NumberOfSrvOpens > 0) {
3368 print_error("%d open Fcbs %d open SrvOpens\n", pNetRoot->NumberOfFcbs,
3369 pNetRoot->NumberOfSrvOpens);
3370 goto out;
3371 }
3372
3373 do {
3374 nfs41_GetFirstMountEntry(pNetRootContext->mountLock,
3375 pNetRootContext->mounts, mount_tmp);
3376 if (mount_tmp == NULL)
3377 break;
3378#ifdef DEBUG_MOUNT
3379 DbgP("Removing entry luid %x.%x from mount list\n",
3380 mount_tmp->login_id.HighPart, mount_tmp->login_id.LowPart);
3381#endif
3382 if (mount_tmp->authsys_session != INVALID_HANDLE_VALUE) {
3384 pNetRootContext->nfs41d_version, UPCALL_TIMEOUT_DEFAULT);
3385 if (status)
3386 print_error("nfs41_unmount AUTH_SYS failed with %d\n", status);
3387 }
3388 if (mount_tmp->gss_session != INVALID_HANDLE_VALUE) {
3389 status = nfs41_unmount(mount_tmp->gss_session,
3390 pNetRootContext->nfs41d_version, UPCALL_TIMEOUT_DEFAULT);
3391 if (status)
3392 print_error("nfs41_unmount RPCSEC_GSS_KRB5 failed with %d\n",
3393 status);
3394 }
3395 if (mount_tmp->gssi_session != INVALID_HANDLE_VALUE) {
3396 status = nfs41_unmount(mount_tmp->gssi_session,
3397 pNetRootContext->nfs41d_version, UPCALL_TIMEOUT_DEFAULT);
3398 if (status)
3399 print_error("nfs41_unmount RPCSEC_GSS_KRB5I failed with %d\n",
3400 status);
3401 }
3402 if (mount_tmp->gssp_session != INVALID_HANDLE_VALUE) {
3403 status = nfs41_unmount(mount_tmp->gssp_session,
3404 pNetRootContext->nfs41d_version, UPCALL_TIMEOUT_DEFAULT);
3405 if (status)
3406 print_error("nfs41_unmount RPCSEC_GSS_KRB5P failed with %d\n",
3407 status);
3408 }
3409 nfs41_RemoveEntry(pNetRootContext->mountLock, mount_tmp);
3410 RxFreePool(mount_tmp);
3411 } while (1);
3412 /* ignore any errors from unmount */
3414
3415 // check if there is anything waiting in the upcall or downcall queue
3416 do {
3418 if (tmp != NULL) {
3419 DbgP("Removing entry from upcall list\n");
3422 KeSetEvent(&tmp->cond, 0, FALSE);
3423 } else
3424 break;
3425 } while (1);
3426
3427 do {
3429 if (tmp != NULL) {
3430 DbgP("Removing entry from downcall list\n");
3433 KeSetEvent(&tmp->cond, 0, FALSE);
3434 } else
3435 break;
3436 } while (1);
3437out:
3438#ifdef DEBUG_MOUNT
3439 DbgEx();
3440#endif
3441 return status;
3442}
3443
3444#ifdef __REACTOS__
3446#else
3448#endif
3449 IN OUT PMRX_V_NET_ROOT pVNetRoot,
3451{
3453 PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
3454 NFS41GetVNetRootExtension(pVNetRoot);
3455#ifdef DEBUG_MOUNT
3456 DbgEn();
3457 print_v_net_root(1, pVNetRoot);
3458#endif
3459 if (pVNetRoot->pNetRoot->Type != NET_ROOT_DISK &&
3460 pVNetRoot->pNetRoot->Type != NET_ROOT_WILD)
3462#ifdef STORE_MOUNT_SEC_CONTEXT
3463 else if (pVNetRootContext->session != INVALID_HANDLE_VALUE) {
3464#ifdef DEBUG_MOUNT
3465 DbgP("nfs41_FinalizeVNetRoot: deleting security context: %p\n",
3466 pVNetRootContext->mount_sec_ctx.ClientToken);
3467#endif
3468 SeDeleteClientSecurity(&pVNetRootContext->mount_sec_ctx);
3469 }
3470#endif
3471#ifdef DEBUG_MOUNT
3472 DbgEx();
3473#endif
3474 return status;
3475}
3476
3479{
3481 return TRUE;
3482 return FALSE;
3483}
3484
3486 ULONG disposition)
3487{
3488 if (disposition == FILE_CREATE || disposition == FILE_OPEN_IF ||
3489 disposition == FILE_OVERWRITE_IF || disposition == FILE_SUPERSEDE)
3490 return TRUE;
3491 return FALSE;
3492}
3493
3496 PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext)
3497{
3498 PFILE_FS_ATTRIBUTE_INFORMATION attrs = &pVNetRootContext->FsAttrs;
3499 LONG len = attrs->MaximumComponentNameLength, count = 1, i;
3500 PWCH p = name->Buffer;
3501 for (i = 0; i < name->Length / 2; i++) {
3502 if (p[0] == L'\\') count = 1;
3503 else {
3504 if (p[0] == L'\0') return FALSE;
3505 if (count > len) return TRUE;
3506 count++;
3507 }
3508 p++;
3509 }
3510 return FALSE;
3511}
3512
3515{
3516 LONG i;
3517 PWCH p = name->Buffer;
3518 for (i = 0; i < name->Length / 2; i++) {
3519 if (p[0] == L':') return TRUE;
3520 else if (p[0] == L'\0') return FALSE;
3521 p++;
3522 }
3523 return FALSE;
3524}
3525
3527{
3528 /* from ms-fsa page 52 */
3529 if ((params->CreateOptions & FILE_DELETE_ON_CLOSE) &&
3530 !(params->DesiredAccess & DELETE))
3531 return FALSE;
3532 if ((params->CreateOptions & FILE_DIRECTORY_FILE) &&
3533 (params->Disposition == FILE_SUPERSEDE ||
3534 params->Disposition == FILE_OVERWRITE ||
3535 params->Disposition == FILE_OVERWRITE_IF))
3536 return FALSE;
3537 if ((params->CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING) &&
3538 (params->DesiredAccess & FILE_APPEND_DATA) &&
3539 !(params->DesiredAccess & FILE_WRITE_DATA))
3540 return FALSE;
3541 /* from ms-fsa 3.1.5.1.1 page 56 */
3542 if ((params->CreateOptions & FILE_DIRECTORY_FILE) &&
3543 (params->FileAttributes & FILE_ATTRIBUTE_TEMPORARY))
3544 return FALSE;
3545 return TRUE;
3546}
3547
3549 DWORD status,
3550 USHORT len)
3551{
3552 switch (status) {
3553 case NO_ERROR: return STATUS_SUCCESS;
3555 if (len > 0) return STATUS_ACCESS_DENIED;
3556 else return STATUS_SUCCESS;
3567 case ERROR_REPARSE: return STATUS_REPARSE;
3571 default:
3572 print_error("[ERROR] nfs41_Create: upcall returned %d returning "
3573 "STATUS_INSUFFICIENT_RESOURCES\n", status);
3575 }
3576}
3577
3579 DWORD disposition,
3580 DWORD errno)
3581{
3582 switch(disposition) {
3583 case FILE_SUPERSEDE:
3585 else return FILE_SUPERSEDED;
3586 case FILE_CREATE: return FILE_CREATED;
3587 case FILE_OPEN: return FILE_OPENED;
3588 case FILE_OPEN_IF:
3590 else return FILE_OPENED;
3591 case FILE_OVERWRITE: return FILE_OVERWRITTEN;
3592 case FILE_OVERWRITE_IF:
3594 else return FILE_OVERWRITTEN;
3595 default:
3596 print_error("unknown disposition %d\n", disposition);
3597 return FILE_OPENED;
3598 }
3599}
3600
3603 IN ULONG disposition)
3604{
3605 /* don't pass cygwin EAs */
3606 if (AnsiStrEq(&NfsV3Attributes, ea->EaName, ea->EaNameLength)
3607 || AnsiStrEq(&NfsActOnLink, ea->EaName, ea->EaNameLength)
3608 || AnsiStrEq(&NfsSymlinkTargetName, ea->EaName, ea->EaNameLength))
3609 return FALSE;
3610 /* only set EAs on file creation */
3611 return disposition == FILE_SUPERSEDE || disposition == FILE_CREATE
3612 || disposition == FILE_OPEN_IF || disposition == FILE_OVERWRITE
3613 || disposition == FILE_OVERWRITE_IF;
3614}
3615
3617 IN PRX_CONTEXT RxContext)
3618{
3620 PNT_CREATE_PARAMETERS params = &RxContext->Create.NtCreateParameters;
3621 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
3622 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
3623 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
3625 &pVNetRootContext->FsAttrs;
3626 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
3627 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
3628 __notnull PMRX_FCB Fcb = RxContext->pFcb;
3629 __notnull PNFS41_FCB nfs41_fcb = (PNFS41_FCB)Fcb->Context;
3631 RxContext->CurrentIrp->AssociatedIrp.SystemBuffer;
3632
3633 if (Fcb->pNetRoot->Type != NET_ROOT_DISK &&
3634 Fcb->pNetRoot->Type != NET_ROOT_WILD) {
3635 print_error("nfs41_Create: Unsupported NetRoot Type %u\n",
3636 Fcb->pNetRoot->Type);
3638 goto out;
3639 }
3640
3642 print_error("FCB_STATE_PAGING_FILE not implemented\n");
3644 goto out;
3645 }
3646
3647 if (!pNetRootContext->mounts_init) {
3648 print_error("nfs41_Create: No valid session established\n");
3650 goto out;
3651 }
3652
3653 if (isStream(SrvOpen->pAlreadyPrefixedName)) {
3655 goto out;
3656 }
3657
3658 if (pVNetRootContext->read_only &&
3659 (params->DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA))) {
3661 goto out;
3662 }
3663
3664 /* if FCB was marked for deletion and opened multiple times, as soon
3665 * as first close happen, FCB transitions into delete_pending state
3666 * no more opens allowed
3667 */
3668 if (Fcb->OpenCount && nfs41_fcb->DeletePending) {
3670 goto out;
3671 }
3672
3673 /* ms-fsa: 3.1.5.1.2.1 page 68 */
3674 if (Fcb->OpenCount && nfs41_fcb->StandardInfo.DeletePending &&
3675 !(params->ShareAccess & FILE_SHARE_DELETE) &&
3676 (params->DesiredAccess & (FILE_EXECUTE | FILE_READ_DATA |
3679 goto out;
3680 }
3681
3682 /* rdbss seems miss this sharing_violation check */
3683 if (Fcb->OpenCount && params->Disposition == FILE_SUPERSEDE) {
3684#ifdef __REACTOS__
3685 if ((!RxContext->CurrentIrpSp->FileObject->SharedRead &&
3686 (params->DesiredAccess & FILE_READ_DATA)) ||
3687 ((!RxContext->CurrentIrpSp->FileObject->SharedWrite &&
3688 (params->DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA |
3690 (!RxContext->CurrentIrpSp->FileObject->SharedDelete &&
3691 (params->DesiredAccess & DELETE)))) {
3692#else
3693 if ((!RxContext->CurrentIrpSp->FileObject->SharedRead &&
3694 (params->DesiredAccess & FILE_READ_DATA)) ||
3695 (!RxContext->CurrentIrpSp->FileObject->SharedWrite &&
3696 (params->DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA |
3698 (!RxContext->CurrentIrpSp->FileObject->SharedDelete &&
3699 (params->DesiredAccess & DELETE)))) {
3700#endif
3702 goto out;
3703 }
3704 }
3705 if (isFilenameTooLong(SrvOpen->pAlreadyPrefixedName, pVNetRootContext)) {
3707 goto out;
3708 }
3709
3710 if (!areOpenParamsValid(params)) {
3712 goto out;
3713 }
3714
3715 /* from ms-fsa 3.1.5.1.1 page 56 */
3716 if ((params->CreateOptions & FILE_DELETE_ON_CLOSE) &&
3717 (params->FileAttributes & FILE_ATTRIBUTE_READONLY)) {
3719 goto out;
3720 }
3721
3722 if (ea) {
3723 /* ignore cygwin EAs when checking support and access */
3724 if (!AnsiStrEq(&NfsV3Attributes, ea->EaName, ea->EaNameLength) &&
3725 !AnsiStrEq(&NfsActOnLink, ea->EaName, ea->EaNameLength) &&
3726 !AnsiStrEq(&NfsSymlinkTargetName, ea->EaName, ea->EaNameLength)) {
3727 if (!(FsAttrs->FileSystemAttributes & FILE_SUPPORTS_EXTENDED_ATTRIBUTES)) {
3729 goto out;
3730 }
3731 }
3732 } else if (RxContext->CurrentIrpSp->Parameters.Create.EaLength) {
3734 goto out;
3735 }
3736
3737out:
3738 return status;
3739}
3740
3741#ifdef __REACTOS__
3743#else
3745#endif
3746 IN OUT PRX_CONTEXT RxContext)
3747{
3750 PNT_CREATE_PARAMETERS params = &RxContext->Create.NtCreateParameters;
3752 RxContext->CurrentIrp->AssociatedIrp.SystemBuffer;
3753 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
3754 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
3755 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
3756 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
3757 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
3758 __notnull PMRX_FCB Fcb = RxContext->pFcb;
3759 __notnull PNFS41_FCB nfs41_fcb = (PNFS41_FCB)Fcb->Context;
3760 PNFS41_FOBX nfs41_fobx = NULL;
3761 BOOLEAN oldDeletePending = nfs41_fcb->StandardInfo.DeletePending;
3762#ifdef ENABLE_TIMINGS
3763 LARGE_INTEGER t1, t2;
3765#endif
3766
3767 ASSERT( NodeType(SrvOpen) == RDBSS_NTC_SRVOPEN );
3768
3769#ifdef DEBUG_OPEN
3770 DbgEn();
3771 print_debug_header(RxContext);
3772 print_nt_create_params(1, RxContext->Create.NtCreateParameters);
3773 if (ea) print_ea_info(0, ea);
3774#endif
3775
3776 status = check_nfs41_create_args(RxContext);
3777 if (status) goto out;
3778
3779#if defined(STORE_MOUNT_SEC_CONTEXT) && defined (USE_MOUNT_SEC_CONTEXT)
3780 status = nfs41_UpcallCreate(NFS41_OPEN, &pVNetRootContext->mount_sec_ctx,
3781#else
3783#endif
3784 pVNetRootContext->session, INVALID_HANDLE_VALUE,
3785 pNetRootContext->nfs41d_version,
3786 SrvOpen->pAlreadyPrefixedName, &entry);
3787 if (status) goto out;
3788
3789 entry->u.Open.access_mask = params->DesiredAccess;
3790 entry->u.Open.access_mode = params->ShareAccess;
3791 entry->u.Open.attrs = params->FileAttributes;
3792 if (!(params->CreateOptions & FILE_DIRECTORY_FILE))
3793 entry->u.Open.attrs |= FILE_ATTRIBUTE_ARCHIVE;
3794 entry->u.Open.disp = params->Disposition;
3795 entry->u.Open.copts = params->CreateOptions;
3796 entry->u.Open.srv_open = SrvOpen;
3797 /* treat the NfsActOnLink ea as FILE_OPEN_REPARSE_POINT */
3798 if ((ea && AnsiStrEq(&NfsActOnLink, ea->EaName, ea->EaNameLength)) ||
3799 (entry->u.Open.access_mask & DELETE))
3800 entry->u.Open.copts |= FILE_OPEN_REPARSE_POINT;
3801 if (isDataAccess(params->DesiredAccess) || isOpen2Create(params->Disposition))
3802 entry->u.Open.open_owner_id = InterlockedIncrement(&open_owner_id);
3803 // if we are creating a file check if nfsv3attributes were passed in
3804 if (params->Disposition != FILE_OPEN && params->Disposition != FILE_OVERWRITE) {
3805 entry->u.Open.mode = 0777;
3806 if (ea && AnsiStrEq(&NfsV3Attributes, ea->EaName, ea->EaNameLength)) {
3807 nfs3_attrs *attrs = (nfs3_attrs *)(ea->EaName + ea->EaNameLength + 1);
3808#ifdef DEBUG_OPEN
3809 DbgP("creating file with mode %o\n", attrs->mode);
3810#endif
3811 entry->u.Open.mode = attrs->mode;
3812 }
3813 if (params->FileAttributes & FILE_ATTRIBUTE_READONLY)
3814 entry->u.Open.mode = 0444;
3815 }
3816 if (entry->u.Open.disp == FILE_CREATE && ea &&
3817 AnsiStrEq(&NfsSymlinkTargetName, ea->EaName, ea->EaNameLength)) {
3818 /* for a cygwin symlink, given as a unicode string */
3819 entry->u.Open.symlink.Buffer = (PWCH)(ea->EaName + ea->EaNameLength + 1);
3820 entry->u.Open.symlink.MaximumLength = entry->u.Open.symlink.Length = ea->EaValueLength;
3821 }
3822retry_on_link:
3823 if (ea && create_should_pass_ea(ea, params->Disposition)) {
3824 /* lock the extended attribute buffer for read access in user space */
3825 entry->u.Open.EaMdl = IoAllocateMdl(ea,
3826 RxContext->CurrentIrpSp->Parameters.Create.EaLength,
3827 FALSE, FALSE, NULL);
3828 if (entry->u.Open.EaMdl == NULL) {
3829 status = STATUS_INTERNAL_ERROR;
3830 RxFreePool(entry);
3831 goto out;
3832 }
3833 entry->u.Open.EaMdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
3835 }
3836
3837 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
3838#ifndef USE_MOUNT_SEC_CONTEXT
3839 SeDeleteClientSecurity(&entry->sec_ctx);
3840#endif
3841 if (status) goto out;
3842
3843 if (entry->u.Open.EaMdl) {
3844 MmUnlockPages(entry->u.Open.EaMdl);
3845 IoFreeMdl(entry->u.Open.EaMdl);
3846 }
3847
3848 if (entry->status == NO_ERROR && entry->errno == ERROR_REPARSE) {
3849 /* symbolic link handling. when attempting to open a symlink when the
3850 * FILE_OPEN_REPARSE_POINT flag is not set, replace the filename with
3851 * the symlink target's by calling RxPrepareToReparseSymbolicLink()
3852 * and returning STATUS_REPARSE. the object manager will attempt to
3853 * open the new path, and return its handle for the original open */
3854 PRDBSS_DEVICE_OBJECT DeviceObject = RxContext->RxDeviceObject;
3855 PV_NET_ROOT VNetRoot = (PV_NET_ROOT)
3856 RxContext->pRelevantSrvOpen->pVNetRoot;
3857 PUNICODE_STRING VNetRootPrefix = &VNetRoot->PrefixEntry.Prefix;
3858 UNICODE_STRING AbsPath;
3859 PCHAR buf;
3860 BOOLEAN ReparseRequired;
3861
3862 /* allocate the string for RxPrepareToReparseSymbolicLink(), and
3863 * format an absolute path "DeviceName+VNetRootName+symlink" */
3864 AbsPath.Length = DeviceObject->DeviceName.Length +
3865 VNetRootPrefix->Length + entry->u.Open.symlink.Length;
3866 AbsPath.MaximumLength = AbsPath.Length + sizeof(UNICODE_NULL);
3867 AbsPath.Buffer = RxAllocatePoolWithTag(NonPagedPool,
3868 AbsPath.MaximumLength, NFS41_MM_POOLTAG);
3869 if (AbsPath.Buffer == NULL) {
3871 goto out_free;
3872 }
3873
3874 buf = (PCHAR)AbsPath.Buffer;
3875 RtlCopyMemory(buf, DeviceObject->DeviceName.Buffer,
3876 DeviceObject->DeviceName.Length);
3877 buf += DeviceObject->DeviceName.Length;
3878 RtlCopyMemory(buf, VNetRootPrefix->Buffer, VNetRootPrefix->Length);
3879 buf += VNetRootPrefix->Length;
3880 RtlCopyMemory(buf, entry->u.Open.symlink.Buffer,
3881 entry->u.Open.symlink.Length);
3882 RxFreePool(entry->u.Open.symlink.Buffer);
3883 buf += entry->u.Open.symlink.Length;
3885
3887 entry->u.Open.symlink_embedded, &AbsPath, TRUE, &ReparseRequired);
3888#ifdef DEBUG_OPEN
3889 DbgP("RxPrepareToReparseSymbolicLink(%u, '%wZ') returned %08lX, "
3890 "FileName is '%wZ'\n", entry->u.Open.symlink_embedded,
3891 &AbsPath, status, &RxContext->CurrentIrpSp->FileObject->FileName);
3892#endif
3893 if (status == STATUS_SUCCESS) {
3894 /* if a reparse is not required, reopen the link itself. this
3895 * happens with operations on cygwin symlinks, where the reparse
3896 * flag is not set */
3897 if (!ReparseRequired) {
3898 entry->u.Open.symlink.Length = 0;
3899 entry->u.Open.copts |= FILE_OPEN_REPARSE_POINT;
3900 goto retry_on_link;
3901 }
3903 }
3904 goto out_free;
3905 }
3906
3907 status = map_open_errors(entry->status,
3908 SrvOpen->pAlreadyPrefixedName->Length);
3909 if (status) {
3910#ifdef DEBUG_OPEN
3912#endif
3913 goto out_free;
3914 }
3915
3919 }
3920
3921 RxContext->pFobx = RxCreateNetFobx(RxContext, SrvOpen);
3922 if (RxContext->pFobx == NULL) {
3924 goto out_free;
3925 }
3926#ifdef DEBUG_OPEN
3927 DbgP("nfs41_Create: created FOBX %p\n", RxContext->pFobx);
3928#endif
3929 nfs41_fobx = (PNFS41_FOBX)(RxContext->pFobx)->Context;
3930 nfs41_fobx->nfs41_open_state = entry->open_state;
3931#ifndef USE_MOUNT_SEC_CONTEXT
3932 status = nfs41_get_sec_ctx(SecurityImpersonation, &nfs41_fobx->sec_ctx);
3933 if (status)
3934 goto out_free;
3935#else
3936 RtlCopyMemory(&nfs41_fobx->sec_ctx, &pVNetRootContext->mount_sec_ctx,
3937 sizeof(nfs41_fobx->sec_ctx));
3938#endif
3939
3940 // we get attributes only for data access and file (not directories)
3941 if (Fcb->OpenCount == 0 ||
3942 (Fcb->OpenCount > 0 &&
3943 nfs41_fcb->changeattr != entry->ChangeTime)) {
3944 FCB_INIT_PACKET InitPacket;
3945 RX_FILE_TYPE StorageType = FileTypeNotYetKnown;
3946 RtlCopyMemory(&nfs41_fcb->BasicInfo, &entry->u.Open.binfo,
3947 sizeof(entry->u.Open.binfo));
3948 RtlCopyMemory(&nfs41_fcb->StandardInfo, &entry->u.Open.sinfo,
3949 sizeof(entry->u.Open.sinfo));
3950 nfs41_fcb->mode = entry->u.Open.mode;
3951 nfs41_fcb->changeattr = entry->ChangeTime;
3952 if (((params->CreateOptions & FILE_DELETE_ON_CLOSE) &&
3953 !pVNetRootContext->read_only) || oldDeletePending)
3954 nfs41_fcb->StandardInfo.DeletePending = TRUE;
3955
3956 RxFormInitPacket(InitPacket,
3957 &entry->u.Open.binfo.FileAttributes,
3958 &entry->u.Open.sinfo.NumberOfLinks,
3959 &entry->u.Open.binfo.CreationTime,
3960 &entry->u.Open.binfo.LastAccessTime,
3961 &entry->u.Open.binfo.LastWriteTime,
3962 &entry->u.Open.binfo.ChangeTime,
3963 &entry->u.Open.sinfo.AllocationSize,
3964 &entry->u.Open.sinfo.EndOfFile,
3965 &entry->u.Open.sinfo.EndOfFile);
3966
3967 if (entry->u.Open.sinfo.Directory)
3968 StorageType = FileTypeDirectory;
3969 else
3970 StorageType = FileTypeFile;
3971
3973 &InitPacket);
3974 }
3975#ifdef DEBUG_OPEN
3976 else
3977 DbgP("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");
3978
3979 print_basic_info(1, &nfs41_fcb->BasicInfo);
3980 print_std_info(1, &nfs41_fcb->StandardInfo);
3981#endif
3982
3983 /* aglo: 05/10/2012. it seems like always have to invalid the cache if the
3984 * file has been opened before and being opened again for data access.
3985 * If the file was opened before, RDBSS might have cached (unflushed) data
3986 * and by opening it again, we will not have the correct representation of
3987 * the file size and data content. fileio tests 208, 219, 221.
3988 */
3989 if (Fcb->OpenCount > 0 && (isDataAccess(params->DesiredAccess) ||
3990 nfs41_fcb->changeattr != entry->ChangeTime) &&
3991 !nfs41_fcb->StandardInfo.Directory) {
3993#ifdef DEBUG_OPEN
3994 DbgP("nfs41_Create: reopening (changed) file %wZ\n",
3995 SrvOpen->pAlreadyPrefixedName);
3996#endif
3998 }
3999 if (!nfs41_fcb->StandardInfo.Directory &&
4000 isDataAccess(params->DesiredAccess)) {
4001 nfs41_fobx->deleg_type = entry->u.Open.deleg_type;
4002#ifdef DEBUG_OPEN
4003 DbgP("nfs41_Create: received delegation %d\n", entry->u.Open.deleg_type);
4004#endif
4005 if (!(params->CreateOptions & FILE_WRITE_THROUGH) &&
4006 !pVNetRootContext->write_thru &&
4007 (entry->u.Open.deleg_type == 2 ||
4008 (params->DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)))) {
4009#ifdef DEBUG_OPEN
4010 DbgP("nfs41_Create: enabling write buffering\n");
4011#endif
4012 SrvOpen->BufferingFlags |=
4015 } else if (params->CreateOptions & FILE_WRITE_THROUGH ||
4016 pVNetRootContext->write_thru)
4017 nfs41_fobx->write_thru = TRUE;
4018 if (entry->u.Open.deleg_type >= 1 ||
4019 params->DesiredAccess & FILE_READ_DATA) {
4020#ifdef DEBUG_OPEN
4021 DbgP("nfs41_Create: enabling read buffering\n");
4022#endif
4023 SrvOpen->BufferingFlags |=
4026 }
4027 if (pVNetRootContext->nocache ||
4028 (params->CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)) {
4029#ifdef DEBUG_OPEN
4030 DbgP("nfs41_Create: disabling buffering\n");
4031#endif
4032 SrvOpen->BufferingFlags = FCB_STATE_DISABLE_LOCAL_BUFFERING;
4033 nfs41_fobx->nocache = TRUE;
4034 } else if (!entry->u.Open.deleg_type && !Fcb->OpenCount) {
4035 nfs41_fcb_list_entry *oentry;
4036#ifdef DEBUG_OPEN
4037 DbgP("nfs41_Create: received no delegations: srv_open=%p "
4038 "ctime=%llu\n", SrvOpen, entry->ChangeTime);
4039#endif
4042 if (oentry == NULL) {
4044 goto out_free;
4045 }
4046 oentry->fcb = RxContext->pFcb;
4047 oentry->nfs41_fobx = nfs41_fobx;
4048 oentry->session = pVNetRootContext->session;
4049 oentry->ChangeTime = entry->ChangeTime;
4050 oentry->skip = FALSE;
4052 }
4053 }
4054
4055 if ((params->CreateOptions & FILE_DELETE_ON_CLOSE) &&
4056 !pVNetRootContext->read_only)
4057 nfs41_fcb->StandardInfo.DeletePending = TRUE;
4058
4059 RxContext->Create.ReturnedCreateInformation =
4060 map_disposition_to_create_retval(params->Disposition, entry->errno);
4061
4062 RxContext->pFobx->OffsetOfNextEaToReturn = 1;
4063#ifndef __REACTOS__
4064 RxContext->CurrentIrp->IoStatus.Information =
4065 RxContext->Create.ReturnedCreateInformation;
4066#endif
4067 status = RxContext->CurrentIrp->IoStatus.Status = STATUS_SUCCESS;
4068
4069out_free:
4070 if (entry)
4072out:
4073#ifdef ENABLE_TIMINGS
4075 if ((params->DesiredAccess & FILE_READ_DATA) ||
4076 (params->DesiredAccess & FILE_WRITE_DATA) ||
4077 (params->DesiredAccess & FILE_APPEND_DATA) ||
4078 (params->DesiredAccess & FILE_EXECUTE)) {
4080 InterlockedAdd64(&open.ticks, t2.QuadPart - t1.QuadPart);
4081#ifdef ENABLE_INDV_TIMINGS
4082 DbgP("nfs41_Create open delta = %d op=%d sum=%d\n",
4083 t2.QuadPart - t1.QuadPart, open.tops, open.ticks);
4084#endif
4085 } else {
4087 InterlockedAdd64(&lookup.ticks, t2.QuadPart - t1.QuadPart);
4088#ifdef ENABLE_INDV_TIMINGS
4089 DbgP("nfs41_Create lookup delta = %d op=%d sum=%d\n",
4090 t2.QuadPart - t1.QuadPart, lookup.tops, lookup.ticks);
4091#endif
4092 }
4093#endif
4094#ifdef DEBUG_OPEN
4095 DbgEx();
4096#endif
4097 return status;
4098}
4099
4100#ifdef __REACTOS__
4102#else
4104#endif
4105 IN OUT PRX_CONTEXT RxContext)
4106{
4108 DbgEn();
4109 DbgEx();
4110 return status;
4111}
4112
4113#ifdef __REACTOS__
4115#else
4117#endif
4118 IN OUT PRX_CONTEXT RxContext)
4119{
4120 if (RxContext->pRelevantSrvOpen == NULL)
4121 return STATUS_SUCCESS;
4123}
4124
4125#ifdef __REACTOS__
4127#else
4129#endif
4130 IN OUT PRX_CONTEXT RxContext,
4131 IN PLARGE_INTEGER pNewFileSize,
4132 OUT PLARGE_INTEGER pNewAllocationSize)
4133{
4135 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
4136#ifdef DEBUG_CACHE
4137 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
4138 DbgEn();
4139 print_debug_header(RxContext);
4140 DbgP("input: byte count 0x%x filesize 0x%x alloc size 0x%x\n",
4141 LowIoContext->ParamsFor.ReadWrite.ByteCount, *pNewFileSize,
4142 *pNewAllocationSize);
4143#endif
4144 pNewAllocationSize->QuadPart = pNewFileSize->QuadPart + 8192;
4145 nfs41_fcb->StandardInfo.AllocationSize.QuadPart =
4146 pNewAllocationSize->QuadPart;
4147 nfs41_fcb->StandardInfo.EndOfFile.QuadPart = pNewFileSize->QuadPart;
4148#ifdef DEBUG_CACHE
4149 DbgP("new filesize 0x%x new allocation size 0x%x\n", *pNewFileSize,
4150 *pNewAllocationSize);
4151#endif
4152#ifdef DEBUG_CACHE
4153 DbgEx();
4154#endif
4155 return status;
4156}
4157
4159 PMRX_FCB fcb)
4160{
4164
4166 while (!IsListEmpty(&openlist.head)) {
4169 if (cur->fcb == fcb) {
4170#ifdef DEBUG_CLOSE
4171 DbgP("nfs41_remove_srvopen_entry: Found match for fcb=%p\n", fcb);
4172#endif
4174 RxFreePool(cur);
4175 break;
4176 }
4177 if (pEntry->Flink == &openlist.head) {
4178#ifdef DEBUG_CLOSE
4179 DbgP("nfs41_remove_srvopen_entry: reached EOL looking for fcb "
4180 "%p\n", fcb);
4181#endif
4182 break;
4183 }
4184 pEntry = pEntry->Flink;
4185 }
4187}
4188
4190 DWORD status)
4191{
4192 switch (status) {
4193 case NO_ERROR: return STATUS_SUCCESS;
4197 default:
4198 print_error("failed to map windows error %d to NTSTATUS; "
4199 "defaulting to STATUS_INTERNAL_ERROR\n", status);
4201 }
4202}
4203
4204#ifdef __REACTOS__
4206#else
4208#endif
4209 IN OUT PRX_CONTEXT RxContext)
4210{
4213 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
4214 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
4215 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
4216 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
4217 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
4218 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
4219 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
4220#ifdef ENABLE_TIMINGS
4221 LARGE_INTEGER t1, t2;
4223#endif
4224
4225#ifdef DEBUG_CLOSE
4226 DbgEn();
4227 print_debug_header(RxContext);
4228#endif
4229
4230 if (!nfs41_fobx->deleg_type && !nfs41_fcb->StandardInfo.Directory &&
4231 !RxContext->pFcb->OpenCount) {
4232 nfs41_remove_fcb_entry(RxContext->pFcb);
4233 }
4234
4235 status = nfs41_UpcallCreate(NFS41_CLOSE, &nfs41_fobx->sec_ctx,
4236 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
4237 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
4238 if (status) goto out;
4239
4240 entry->u.Close.srv_open = SrvOpen;
4241 if (nfs41_fcb->StandardInfo.DeletePending)
4242 nfs41_fcb->DeletePending = TRUE;
4243 if (!RxContext->pFcb->OpenCount ||
4244 (nfs41_fcb->StandardInfo.DeletePending &&
4245 nfs41_fcb->StandardInfo.Directory))
4246 entry->u.Close.remove = nfs41_fcb->StandardInfo.DeletePending;
4247 if (!RxContext->pFcb->OpenCount)
4248 entry->u.Close.renamed = nfs41_fcb->Renamed;
4249
4250 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
4251#ifndef USE_MOUNT_SEC_CONTEXT
4252 SeDeleteClientSecurity(&nfs41_fobx->sec_ctx);
4253#endif
4254 if (status) goto out;
4255
4256 /* map windows ERRORs to NTSTATUS */
4257 status = map_close_errors(entry->status);
4259out:
4260#ifdef ENABLE_TIMINGS
4263 InterlockedAdd64(&close.ticks, t2.QuadPart - t1.QuadPart);
4264#ifdef ENABLE_INDV_TIMINGS
4265 DbgP("nfs41_CloseSrvOpen delta = %d op=%d sum=%d\n",
4266 t2.QuadPart - t1.QuadPart, close.tops, close.ticks);
4267#endif
4268#endif
4269#ifdef DEBUG_CLOSE
4270 DbgEx();
4271#endif
4272 return status;
4273}
4274
4275#ifdef __REACTOS__
4277#else
4279#endif
4280 IN OUT PRX_CONTEXT RxContext)
4281{
4282 return STATUS_SUCCESS;
4283}
4284
4285#ifdef __REACTOS__
4287#else
4289#endif
4290 IN OUT PMRX_FCB pFcb)
4291{
4292 return STATUS_SUCCESS;
4293}
4294
4295#ifdef __REACTOS__
4297#else
4299#endif
4300 IN OUT PMRX_FOBX pFobx)
4301{
4302 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(pFobx);
4303 if (nfs41_fobx->acl)
4304 RxFreePool(nfs41_fobx->acl);
4305 return STATUS_SUCCESS;
4306}
4307
4309 PRX_CONTEXT RxContext)
4310{
4311 print_debug_header(RxContext);
4312 DbgP("FileName='%wZ', InfoClass = %s\n",
4314 print_file_information_class(RxContext->Info.FileInformationClass));
4315}
4316
4318 PRX_CONTEXT RxContext)
4319{
4321 DbgP("Filter='%wZ', Index=%d, Restart/Single/Specified/Init=%d/%d/%d/%d\n",
4322 &RxContext->pFobx->UnicodeQueryTemplate,
4323 RxContext->QueryDirectory.FileIndex,
4324 RxContext->QueryDirectory.RestartScan,
4325 RxContext->QueryDirectory.ReturnSingleEntry,
4326 RxContext->QueryDirectory.IndexSpecified,
4327 RxContext->QueryDirectory.InitialQuery);
4328}
4329
4331 DWORD status)
4332{
4333 switch (status) {
4342 default:
4343 print_error("failed to map windows error %d to NTSTATUS; "
4344 "defaulting to STATUS_INVALID_NETWORK_RESPONSE\n", status);
4346 }
4347}
4348
4350 IN PRX_CONTEXT RxContext)
4351{
4352 if (RxContext->Info.Buffer == NULL)
4354 return STATUS_SUCCESS;
4355}
4356
4357#ifdef __REACTOS__
4359#else
4361#endif
4362 IN OUT PRX_CONTEXT RxContext)
4363{
4366 FILE_INFORMATION_CLASS InfoClass = RxContext->Info.FileInformationClass;
4367 PUNICODE_STRING Filter = &RxContext->pFobx->UnicodeQueryTemplate;
4368 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
4369 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
4370 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
4371 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
4372 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
4373 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
4374#ifdef ENABLE_TIMINGS
4375 LARGE_INTEGER t1, t2;
4377#endif
4378
4379#ifdef DEBUG_DIR_QUERY
4380 DbgEn();
4381 print_querydir_args(RxContext);
4382#endif
4383
4384 status = check_nfs41_dirquery_args(RxContext);
4385 if (status) goto out;
4386
4387 switch (InfoClass) {
4388 /* classes handled in readdir_copy_entry() and readdir_size_for_entry() */
4395 break;
4396 default:
4397 print_error("nfs41_QueryDirectory: unhandled dir query class %d\n",
4398 InfoClass);
4400 goto out;
4401 }
4402 status = nfs41_UpcallCreate(NFS41_DIR_QUERY, &nfs41_fobx->sec_ctx,
4403 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
4404 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
4405 if (status) goto out;
4406
4407 entry->u.QueryFile.InfoClass = InfoClass;
4408 entry->buf_len = RxContext->Info.LengthRemaining;
4409 entry->buf = RxContext->Info.Buffer;
4410 entry->u.QueryFile.mdl = IoAllocateMdl(RxContext->Info.Buffer,
4411 RxContext->Info.LengthRemaining, FALSE, FALSE, NULL);
4412 if (entry->u.QueryFile.mdl == NULL) {
4415 goto out;
4416 }
4417 entry->u.QueryFile.mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
4419
4420 entry->u.QueryFile.filter = Filter;
4421 entry->u.QueryFile.initial_query = RxContext->QueryDirectory.InitialQuery;
4422 entry->u.QueryFile.restart_scan = RxContext->QueryDirectory.RestartScan;
4423 entry->u.QueryFile.return_single = RxContext->QueryDirectory.ReturnSingleEntry;
4424
4425 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
4426 if (status) goto out;
4427 MmUnlockPages(entry->u.QueryFile.mdl);
4428
4429 if (entry->status == STATUS_BUFFER_TOO_SMALL) {
4430 DbgP("nfs41_QueryDirectory: buffer too small provided %d need %lu\n",
4431 RxContext->Info.LengthRemaining, entry->buf_len);
4432 RxContext->InformationToReturn = entry->buf_len;
4434 } else if (entry->status == STATUS_SUCCESS) {
4435#ifdef ENABLE_TIMINGS
4437 InterlockedAdd64(&readdir.size, entry->u.QueryFile.buf_len);
4438#endif
4439 RxContext->Info.LengthRemaining -= entry->buf_len;
4441 } else {
4442 /* map windows ERRORs to NTSTATUS */
4443 status = map_querydir_errors(entry->status);
4444 }
4445 IoFreeMdl(entry->u.QueryFile.mdl);
4447out:
4448#ifdef ENABLE_TIMINGS
4451 InterlockedAdd64(&readdir.ticks, t2.QuadPart - t1.QuadPart);
4452#ifdef ENABLE_INDV_TIMINGS
4453 DbgP("nfs41_QueryDirectory delta = %d ops=%d sum=%d\n",
4454 t2.QuadPart - t1.QuadPart, readdir.tops, readdir.ticks);
4455#endif
4456#endif
4457#ifdef DEBUG_DIR_QUERY
4458 DbgEx();
4459#endif
4460 return status;
4461}
4462
4464 PRX_CONTEXT RxContext)
4465{
4466 print_debug_header(RxContext);
4467 DbgP("FileName='%wZ', InfoClass = %s BufferLen = %d\n",
4469 print_fs_information_class(RxContext->Info.FileInformationClass),
4470 RxContext->Info.LengthRemaining);
4471}
4472
4474 DWORD status)
4475{
4476 switch (status) {
4482 default:
4483 print_error("failed to map windows error %d to NTSTATUS; "
4484 "defaulting to STATUS_INVALID_NETWORK_RESPONSE\n", status);
4486 }
4487}
4488
4490{
4492
4493 RtlZeroMemory(pVolInfo, sizeof(FILE_FS_VOLUME_INFORMATION));
4494 pVolInfo->VolumeSerialNumber = 0xBABAFACE;
4495 pVolInfo->VolumeLabelLength = VolName.Length;
4496 RtlCopyMemory(&pVolInfo->VolumeLabel[0], (PVOID)VolName.Buffer,
4497 VolName.MaximumLength);
4498 *len = sizeof(FILE_FS_VOLUME_INFORMATION) + VolName.Length;
4499}
4500
4502 PRX_CONTEXT RxContext)
4503{
4504 __notnull PV_NET_ROOT VNetRoot = (PV_NET_ROOT)
4505 RxContext->pRelevantSrvOpen->pVNetRoot;
4506 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
4508
4509 /* calculate the root directory's length, including vnetroot prefix,
4510 * mount path, and a trailing \ */
4511 const USHORT RootPathLen = VNetRoot->PrefixEntry.Prefix.Length +
4512 pVNetRootContext->MountPathLen + sizeof(WCHAR);
4513
4514 return RxContext->CurrentIrpSp->FileObject->FileName.Length <= RootPathLen;
4515}
4516
4517#ifdef __REACTOS__
4519#else
4521#endif
4522 IN OUT PRX_CONTEXT RxContext)
4523{
4526 ULONG RemainingLength = RxContext->Info.LengthRemaining, SizeUsed;
4527 FS_INFORMATION_CLASS InfoClass = RxContext->Info.FsInformationClass;
4528 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
4529 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
4530 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
4531 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
4532 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
4533 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
4534 NFS41GetDeviceExtension(RxContext, DevExt);
4535
4536#ifdef ENABLE_TIMINGS
4537 LARGE_INTEGER t1, t2;
4539#endif
4540
4541#ifdef DEBUG_VOLUME_QUERY
4542 DbgEn();
4543 print_queryvolume_args(RxContext);
4544#endif
4545
4546 status = check_nfs41_dirquery_args(RxContext);
4547 if (status) goto out;
4548
4549#ifdef __REACTOS__
4550 RtlZeroMemory(RxContext->Info.Buffer, RxContext->Info.LengthRemaining);
4551#endif // __REACTOS__
4552
4553 switch (InfoClass) {
4555 if ((ULONG)RxContext->Info.LengthRemaining >= DevExt->VolAttrsLen) {
4556 RtlCopyMemory(RxContext->Info.Buffer, DevExt->VolAttrs,
4557 DevExt->VolAttrsLen);
4558 RxContext->Info.LengthRemaining -= DevExt->VolAttrsLen;
4560 } else {
4561 RtlCopyMemory(RxContext->Info.Buffer, DevExt->VolAttrs,
4562 RxContext->Info.LengthRemaining);
4564 }
4565 goto out;
4567 {
4568 PFILE_FS_DEVICE_INFORMATION pDevInfo = RxContext->Info.Buffer;
4569
4570 SizeUsed = sizeof(FILE_FS_DEVICE_INFORMATION);
4571 if (RemainingLength < SizeUsed) {
4573 RxContext->InformationToReturn = SizeUsed;
4574 goto out;
4575 }
4576 pDevInfo->DeviceType = RxContext->pFcb->pNetRoot->DeviceType;
4578 RxContext->Info.LengthRemaining -= SizeUsed;
4580 goto out;
4581 }
4584 goto out;
4585
4587 if (RxContext->Info.LengthRemaining < FS_ATTR_LEN) {
4588 RxContext->InformationToReturn = FS_ATTR_LEN;
4590 goto out;
4591 }
4592
4593 /* on attribute queries for the root directory,
4594 * use cached volume attributes from mount */
4595 if (is_root_directory(RxContext)) {
4597 (PFILE_FS_ATTRIBUTE_INFORMATION)RxContext->Info.Buffer;
4599
4600 RtlCopyMemory(attrs, &pVNetRootContext->FsAttrs,
4601 sizeof(pVNetRootContext->FsAttrs));
4602
4603 /* fill in the FileSystemName */
4604 RtlCopyMemory(attrs->FileSystemName, FsName.Buffer,
4605 FsName.MaximumLength); /* 'MaximumLength' to include null */
4606 attrs->FileSystemNameLength = FsName.Length;
4607
4608 RxContext->Info.LengthRemaining -= FS_ATTR_LEN;
4609 goto out;
4610 }
4611 /* else fall through and send the upcall */
4614 break;
4615
4616 default:
4617 print_error("nfs41_QueryVolumeInformation: unhandled class %d\n", InfoClass);
4619 goto out;
4620 }
4621 status = nfs41_UpcallCreate(NFS41_VOLUME_QUERY, &nfs41_fobx->sec_ctx,
4622 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
4623 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
4624 if (status) goto out;
4625
4626 entry->u.Volume.query = InfoClass;
4627 entry->buf = RxContext->Info.Buffer;
4628 entry->buf_len = RxContext->Info.LengthRemaining;
4629
4630 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
4631 if (status) goto out;
4632
4633 if (entry->status == STATUS_BUFFER_TOO_SMALL) {
4634 RxContext->InformationToReturn = entry->buf_len;
4636 } else if (entry->status == STATUS_SUCCESS) {
4637 if (InfoClass == FileFsAttributeInformation) {
4638 /* fill in the FileSystemName */
4640 (PFILE_FS_ATTRIBUTE_INFORMATION)RxContext->Info.Buffer;
4642
4643 RtlCopyMemory(attrs->FileSystemName, FsName.Buffer,
4644 FsName.MaximumLength); /* 'MaximumLength' to include null */
4645 attrs->FileSystemNameLength = FsName.Length;
4646
4647 entry->buf_len = FS_ATTR_LEN;
4648 }
4649#ifdef ENABLE_TIMINGS
4651 InterlockedAdd64(&volume.size, entry->u.Volume.buf_len);
4652#endif
4653 RxContext->Info.LengthRemaining -= entry->buf_len;
4655 } else {
4656 status = map_volume_errors(entry->status);
4657 }
4659out:
4660#ifdef ENABLE_TIMINGS
4663 InterlockedAdd64(&volume.ticks, t2.QuadPart - t1.QuadPart);
4664#ifdef ENABLE_INDV_TIMINGS
4665 DbgP("nfs41_QueryVolumeInformation delta = %d op=%d sum=%d\n",
4666 t2.QuadPart - t1.QuadPart, volume.tops, volume.ticks);
4667#endif
4668#endif
4669#ifdef DEBUG_VOLUME_QUERY
4670 DbgEx();
4671#endif
4672 return status;
4673}
4674
4676 PMRX_FCB fcb,
4677 ULONGLONG ChangeTime)
4678{
4683 while (!IsListEmpty(&openlist.head)) {
4686 if (cur->fcb == fcb &&
4687 cur->ChangeTime != ChangeTime) {
4688#if defined(DEBUG_FILE_SET) || defined(DEBUG_ACL_SET) || \
4689 defined(DEBUG_WRITE) || defined(DEBUG_EA_SET)
4690 DbgP("nfs41_update_fcb_list: Found match for fcb %p: updating "
4691 "%llu to %llu\n", fcb, cur->ChangeTime, ChangeTime);
4692#endif
4693 cur->ChangeTime = ChangeTime;
4694 break;
4695 }
4696 /* place an upcall for this srv_open */
4697 if (pEntry->Flink == &openlist.head) {
4698#if defined(DEBUG_FILE_SET) || defined(DEBUG_ACL_SET) || \
4699 defined(DEBUG_WRITE) || defined(DEBUG_EA_SET)
4700 DbgP("nfs41_update_fcb_list: reached EOL loooking for "
4701 "fcb=%p\n", fcb);
4702#endif
4703 break;
4704 }
4705 pEntry = pEntry->Flink;
4706 }
4708}
4709
4711 nfs3_attrs *attrs)
4712{
4713 DbgP("type=%d mode=%o nlink=%d size=%d atime=%x mtime=%x ctime=%x\n",
4714 attrs->type, attrs->mode, attrs->nlink, attrs->size, attrs->atime,
4715 attrs->mtime, attrs->ctime);
4716}
4717
4719 IN const PLARGE_INTEGER file_time,
4720 OUT LONGLONG *nfs_time)
4721{
4723 diff.QuadPart = file_time->QuadPart - diff.QuadPart;
4724 *nfs_time = diff.QuadPart / 10000000;
4725}
4726
4728 nfs3_attrs *attrs,
4729 PNFS41_FCB nfs41_fcb)
4730{
4731 RtlZeroMemory(attrs, sizeof(nfs3_attrs));
4733 attrs->type = NF3LNK;
4734 else if (nfs41_fcb->StandardInfo.Directory)
4735 attrs->type = NF3DIR;
4736 else
4737 attrs->type = NF3REG;
4738 attrs->mode = nfs41_fcb->mode;
4739 attrs->nlink = nfs41_fcb->StandardInfo.NumberOfLinks;
4740 attrs->size.QuadPart = attrs->used.QuadPart =
4741 nfs41_fcb->StandardInfo.EndOfFile.QuadPart;
4743 file_time_to_nfs_time(&nfs41_fcb->BasicInfo.ChangeTime, &attrs->mtime);
4744 file_time_to_nfs_time(&nfs41_fcb->BasicInfo.CreationTime, &attrs->ctime);
4745}
4746
4747
4749 DWORD error)
4750{
4751 switch (error) {
4752 case NO_ERROR: return STATUS_SUCCESS;
4764 default:
4765 print_error("failed to map windows error %d to NTSTATUS; "
4766 "defaulting to STATUS_INVALID_PARAMETER\n", error);
4768 }
4769}
4770
4772 IN PRX_CONTEXT RxContext)
4773{
4775 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
4776 NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
4778 &pVNetRootContext->FsAttrs;
4780 (PFILE_FULL_EA_INFORMATION)RxContext->Info.Buffer;
4781
4782 status = check_nfs41_dirquery_args(RxContext);
4783 if (status) goto out;
4784
4785 if (ea == NULL) {
4787 goto out;
4788 }
4789 if (AnsiStrEq(&NfsActOnLink, ea->EaName, ea->EaNameLength) ||
4790 AnsiStrEq(&NfsSymlinkTargetName, ea->EaName, ea->EaNameLength)) {
4791 status = STATUS_INVALID_PARAMETER; /* only allowed on create */
4792 goto out;
4793 }
4794 /* ignore cygwin EAs when checking support */
4795 if (!(FsAttrs->FileSystemAttributes & FILE_SUPPORTS_EXTENDED_ATTRIBUTES)
4796 && !AnsiStrEq(&NfsV3Attributes, ea->EaName, ea->EaNameLength)) {
4798 goto out;
4799 }
4800 if ((RxContext->pRelevantSrvOpen->DesiredAccess & FILE_WRITE_EA) == 0) {
4802 goto out;
4803 }
4804 if (pVNetRootContext->read_only) {
4805 print_error("check_nfs41_setattr_args: Read-only mount\n");
4807 goto out;
4808 }
4809out:
4810 return status;
4811}
4812
4813#ifdef __REACTOS__
4815#else
4817#endif
4818 IN OUT PRX_CONTEXT RxContext)
4819{
4823 (PFILE_FULL_EA_INFORMATION)RxContext->Info.Buffer;
4824 nfs3_attrs *attrs = NULL;
4825 ULONG buflen = RxContext->CurrentIrpSp->Parameters.SetEa.Length, error_offset;
4826 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
4827 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
4828 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
4829 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
4830 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
4831 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
4832 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
4833#ifdef ENABLE_TIMINGS
4834 LARGE_INTEGER t1, t2;
4836#endif
4837
4838#ifdef DEBUG_EA_SET
4839 DbgEn();
4840 print_debug_header(RxContext);
4841 print_ea_info(1, eainfo);
4842#endif
4843
4844 status = check_nfs41_setea_args(RxContext);
4845 if (status) goto out;
4846
4847 status = nfs41_UpcallCreate(NFS41_EA_SET, &nfs41_fobx->sec_ctx,
4848 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
4849 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
4850 if (status) goto out;
4851
4852 if (AnsiStrEq(&NfsV3Attributes, eainfo->EaName, eainfo->EaNameLength)) {
4853 attrs = (nfs3_attrs *)(eainfo->EaName + eainfo->EaNameLength + 1);
4854#ifdef DEBUG_EA_SET
4855 print_nfs3_attrs(attrs);
4856 DbgP("old mode is %o new mode is %o\n", nfs41_fcb->mode, attrs->mode);
4857#endif
4858 entry->u.SetEa.mode = attrs->mode;
4859 } else {
4860 entry->u.SetEa.mode = 0;
4861 status = IoCheckEaBufferValidity(eainfo, buflen, &error_offset);
4862 if (status) {
4864 goto out;
4865 }
4866 }
4867 entry->buf = eainfo;
4868 entry->buf_len = buflen;
4869
4870 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
4871 if (status) goto out;
4872#ifdef ENABLE_TIMINGS
4873 if (entry->status == STATUS_SUCCESS) {
4874 InterlockedIncrement(&setexattr.sops);
4875 InterlockedAdd64(&setexattr.size, entry->u.SetEa.buf_len);
4876 }
4877#endif
4878 status = map_setea_error(entry->status);
4879 if (!status) {
4880 if (!nfs41_fobx->deleg_type && entry->ChangeTime &&
4881 (SrvOpen->DesiredAccess &
4883 nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
4884 nfs41_fcb->changeattr = entry->ChangeTime;
4885 nfs41_fcb->mode = entry->u.SetEa.mode;
4886 }
4888out:
4889#ifdef ENABLE_TIMINGS
4891 InterlockedIncrement(&setexattr.tops);
4892 InterlockedAdd64(&setexattr.ticks, t2.QuadPart - t1.QuadPart);
4893#ifdef ENABLE_INDV_TIMINGS
4894 DbgP("nfs41_SetEaInformation delta = %d op=%d sum=%d\n",
4895 t2.QuadPart - t1.QuadPart, setexattr.tops, setexattr.ticks);
4896#endif
4897#endif
4898#ifdef DEBUG_EA_SET
4899 DbgEx();
4900#endif
4901 return status;
4902}
4903
4905 IN PRX_CONTEXT RxContext)
4906{
4908 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
4909 NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
4911 &pVNetRootContext->FsAttrs;
4913 RxContext->CurrentIrpSp->Parameters.QueryEa.EaList;
4914
4915 status = check_nfs41_dirquery_args(RxContext);
4916 if (status) goto out;
4917
4918 if (!(FsAttrs->FileSystemAttributes & FILE_SUPPORTS_EXTENDED_ATTRIBUTES)) {
4919 if (ea == NULL) {
4921 goto out;
4922 }
4923 /* ignore cygwin EAs when checking support */
4924 if (!AnsiStrEq(&NfsV3Attributes, ea->EaName, ea->EaNameLength) &&
4925 !AnsiStrEq(&NfsActOnLink, ea->EaName, ea->EaNameLength) &&
4926 !AnsiStrEq(&NfsSymlinkTargetName, ea->EaName, ea->EaNameLength)) {
4928 goto out;
4929 }
4930 }
4931 if ((RxContext->pRelevantSrvOpen->DesiredAccess & FILE_READ_EA) == 0) {
4933 goto out;
4934 }
4935out:
4936 return status;
4937}
4938
4940 IN OUT PRX_CONTEXT RxContext,
4943{
4944 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
4945 __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
4946 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
4947 __notnull PNFS41_NETROOT_EXTENSION NetRootContext =
4948 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
4949 __notnull PNFS41_FOBX Fobx = NFS41GetFobxExtension(RxContext->pFobx);
4952 const USHORT HeaderLen = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) +
4953 query->EaNameLength + 1;
4955
4956 if (RxContext->Info.LengthRemaining < HeaderLen) {
4958 RxContext->InformationToReturn = HeaderLen;
4959 goto out;
4960 }
4961
4962 TargetName.Buffer = (PWCH)(info->EaName + query->EaNameLength + 1);
4963 TargetName.MaximumLength = (USHORT)min(RxContext->Info.LengthRemaining -
4964 HeaderLen, 0xFFFF);
4965
4966 status = nfs41_UpcallCreate(NFS41_SYMLINK, &Fobx->sec_ctx,
4967 VNetRootContext->session, Fobx->nfs41_open_state,
4968 NetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
4969 if (status) goto out;
4970
4971 entry->u.Symlink.target = &TargetName;
4972 entry->u.Symlink.set = FALSE;
4973
4974 status = nfs41_UpcallWaitForReply(entry, VNetRootContext->timeout);
4975 if (status) goto out;
4976
4977 status = map_setea_error(entry->status);
4978 if (status == STATUS_SUCCESS) {
4979 info->NextEntryOffset = 0;
4980 info->Flags = 0;
4981 info->EaNameLength = query->EaNameLength;
4982 info->EaValueLength = TargetName.Length - sizeof(UNICODE_NULL);
4983 TargetName.Buffer[TargetName.Length/sizeof(WCHAR)] = UNICODE_NULL;
4984 RtlCopyMemory(info->EaName, query->EaName, query->EaNameLength);
4985 RxContext->Info.LengthRemaining = HeaderLen + info->EaValueLength;
4986 } else if (status == STATUS_BUFFER_TOO_SMALL) {
4987 RxContext->InformationToReturn = HeaderLen +
4988 entry->u.Symlink.target->Length;
4989 }
4991out:
4992 return status;
4993}
4994
4996 IN OUT PRX_CONTEXT RxContext,
4999{
5001
5002 if (query == NULL)
5003 goto out;
5004
5005 if (AnsiStrEq(&NfsSymlinkTargetName, query->EaName, query->EaNameLength)) {
5006 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
5007 if (nfs41_fcb->BasicInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
5008 status = QueryCygwinSymlink(RxContext, query, info);
5009 goto out;
5010 } else {
5011 const LONG LengthRequired = sizeof(FILE_FULL_EA_INFORMATION) +
5012 NfsSymlinkTargetName.Length - sizeof(CHAR);
5013 if (LengthRequired > RxContext->Info.LengthRemaining) {
5015 RxContext->InformationToReturn = LengthRequired;
5016 goto out;
5017 }
5018 info->NextEntryOffset = 0;
5019 info->Flags = 0;
5020 info->EaValueLength = 0;
5021 info->EaNameLength = (UCHAR)NfsActOnLink.Length;
5022 RtlCopyMemory(info->EaName, NfsSymlinkTargetName.Buffer,
5023 NfsSymlinkTargetName.Length);
5024 RxContext->Info.LengthRemaining = LengthRequired;
5026 goto out;
5027 }
5028 }
5029
5030 if (AnsiStrEq(&NfsV3Attributes, query->EaName, query->EaNameLength)) {
5031 nfs3_attrs attrs;
5032
5033 const LONG LengthRequired = sizeof(FILE_FULL_EA_INFORMATION) +
5034 NfsV3Attributes.Length + sizeof(nfs3_attrs) - sizeof(CHAR);
5035 if (LengthRequired > RxContext->Info.LengthRemaining) {
5037 RxContext->InformationToReturn = LengthRequired;
5038 goto out;
5039 }
5040
5041 create_nfs3_attrs(&attrs, NFS41GetFcbExtension(RxContext->pFcb));
5042#ifdef DEBUG_EA_QUERY
5043 print_nfs3_attrs(&attrs);
5044#endif
5045
5046 info->NextEntryOffset = 0;
5047 info->Flags = 0;
5048 info->EaNameLength = (UCHAR)NfsV3Attributes.Length;
5049 info->EaValueLength = sizeof(nfs3_attrs);
5050 RtlCopyMemory(info->EaName, NfsV3Attributes.Buffer,
5051 NfsV3Attributes.Length);
5052 RtlCopyMemory(info->EaName + info->EaNameLength + 1, &attrs,
5053 sizeof(nfs3_attrs));
5054 RxContext->Info.LengthRemaining = LengthRequired;
5056 goto out;
5057 }
5058
5059 if (AnsiStrEq(&NfsActOnLink, query->EaName, query->EaNameLength)) {
5060
5061 const LONG LengthRequired = sizeof(FILE_FULL_EA_INFORMATION) +
5062 query->EaNameLength - sizeof(CHAR);
5063 if (LengthRequired > RxContext->Info.LengthRemaining) {
5065 RxContext->InformationToReturn = LengthRequired;
5066 goto out;
5067 }
5068
5069 info->NextEntryOffset = 0;
5070 info->Flags = 0;
5071 info->EaNameLength = query->EaNameLength;
5072 info->EaValueLength = 0;
5073 RtlCopyMemory(info->EaName, query->EaName, query->EaNameLength);
5074 RxContext->Info.LengthRemaining = LengthRequired;
5076 goto out;
5077 }
5078out:
5079 return status;
5080}
5081
5082#ifdef __REACTOS__
5084#else
5086#endif
5087 IN OUT PRX_CONTEXT RxContext)
5088{
5092 RxContext->CurrentIrpSp->Parameters.QueryEa.EaList;
5093 ULONG buflen = RxContext->CurrentIrpSp->Parameters.QueryEa.Length;
5094 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
5095 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5096 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
5097 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
5098 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
5099 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
5100#ifdef ENABLE_TIMINGS
5101 LARGE_INTEGER t1, t2;
5103#endif
5104
5105#ifdef DEBUG_EA_QUERY
5106 DbgEn();
5107 print_debug_header(RxContext);
5108 print_get_ea(1, query);
5109#endif
5110 status = check_nfs41_queryea_args(RxContext);
5111 if (status) goto out;
5112
5113 /* handle queries for cygwin EAs */
5114 status = QueryCygwinEA(RxContext, query,
5115 (PFILE_FULL_EA_INFORMATION)RxContext->Info.Buffer);
5117 goto out;
5118
5119 status = nfs41_UpcallCreate(NFS41_EA_GET, &nfs41_fobx->sec_ctx,
5120 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
5121 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
5122 if (status) goto out;
5123
5124 entry->buf_len = buflen;
5125 entry->buf = RxContext->Info.Buffer;
5126 entry->u.QueryEa.EaList = query;
5127 entry->u.QueryEa.EaListLength = query == NULL ? 0 :
5128 RxContext->QueryEa.UserEaListLength;
5129 entry->u.QueryEa.EaIndex = RxContext->QueryEa.IndexSpecified ?
5130 RxContext->QueryEa.UserEaIndex : 0;
5131 entry->u.QueryEa.RestartScan = RxContext->QueryEa.RestartScan;
5132 entry->u.QueryEa.ReturnSingleEntry = RxContext->QueryEa.ReturnSingleEntry;
5133
5134 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
5135 if (status) goto out;
5136
5137 if (entry->status == STATUS_SUCCESS) {
5138 switch (entry->u.QueryEa.Overflow) {
5141 break;
5143 status = RxContext->IoStatusBlock.Status = STATUS_BUFFER_OVERFLOW;
5144 break;
5145 default:
5146 RxContext->IoStatusBlock.Status = STATUS_SUCCESS;
5147 break;
5148 }
5149 RxContext->InformationToReturn = entry->buf_len;
5150#ifdef ENABLE_TIMINGS
5151 InterlockedIncrement(&getexattr.sops);
5152 InterlockedAdd64(&getexattr.size, entry->u.QueryEa.buf_len);
5153#endif
5154 } else {
5155 status = map_setea_error(entry->status);
5156 }
5158out:
5159#ifdef ENABLE_TIMINGS
5161 InterlockedIncrement(&getexattr.tops);
5162 InterlockedAdd64(&getexattr.ticks, t2.QuadPart - t1.QuadPart);
5163#ifdef ENABLE_INDV_TIMINGS
5164 DbgP("nfs41_QueryEaInformation delta = %d op=%d sum=%d\n",
5165 t2.QuadPart - t1.QuadPart, getexattr.tops, getexattr.ticks);
5166#endif
5167#endif
5168#ifdef DEBUG_EA_QUERY
5169 DbgEx();
5170#endif
5171 return status;
5172}
5173
5175 DWORD error)
5176{
5177 switch (error) {
5178 case NO_ERROR: return STATUS_SUCCESS;
5183 default:
5184 print_error("failed to map windows error %d to NTSTATUS; "
5185 "defaulting to STATUS_INVALID_NETWORK_RESPONSE\n", error);
5187 }
5188}
5189
5191 PRX_CONTEXT RxContext)
5192{
5195 RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
5196
5197 /* we don't support sacls */
5201 goto out;
5202 }
5203 if (RxContext->CurrentIrp->UserBuffer == NULL &&
5204 RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length)
5206out:
5207 return status;
5208}
5209
5210#ifdef __REACTOS__
5212#else
5214#endif
5215 IN OUT PRX_CONTEXT RxContext)
5216{
5219 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
5220 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
5221 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5222 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
5223 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
5224 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
5226 RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
5227#ifdef ENABLE_TIMINGS
5228 LARGE_INTEGER t1, t2;
5230#endif
5231
5232#ifdef DEBUG_ACL_QUERY
5233 DbgEn();
5234 print_debug_header(RxContext);
5236#endif
5237
5238 status = check_nfs41_getacl_args(RxContext);
5239 if (status) goto out;
5240
5241 if (nfs41_fobx->acl && nfs41_fobx->acl_len) {
5242 LARGE_INTEGER current_time;
5243 KeQuerySystemTime(&current_time);
5244#ifdef DEBUG_ACL_QUERY
5245 DbgP("CurrentTime %lx Saved Acl time %lx\n",
5246 current_time.QuadPart, nfs41_fobx->time.QuadPart);
5247#endif
5248 if (current_time.QuadPart - nfs41_fobx->time.QuadPart <= 20*1000) {
5250 RxContext->CurrentIrp->UserBuffer;
5251 RtlCopyMemory(sec_desc, nfs41_fobx->acl, nfs41_fobx->acl_len);
5252 RxContext->IoStatusBlock.Information =
5253 RxContext->InformationToReturn = nfs41_fobx->acl_len;
5254 RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
5255#ifdef ENABLE_TIMINGS
5256 InterlockedIncrement(&getacl.sops);
5257 InterlockedAdd64(&getacl.size, nfs41_fobx->acl_len);
5258#endif
5259 } else status = 1;
5260 RxFreePool(nfs41_fobx->acl);
5261 nfs41_fobx->acl = NULL;
5262 nfs41_fobx->acl_len = 0;
5263 if (!status)
5264 goto out;
5265 }
5266
5267 status = nfs41_UpcallCreate(NFS41_ACL_QUERY, &nfs41_fobx->sec_ctx,
5268 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
5269 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
5270 if (status) goto out;
5271
5272 entry->u.Acl.query = info_class;
5273 /* we can't provide RxContext->CurrentIrp->UserBuffer to the upcall thread
5274 * because it becomes an invalid pointer with that execution context
5275 */
5276 entry->buf_len = RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length;
5277
5278 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
5279 if (status) goto out;
5280
5281 if (entry->status == STATUS_BUFFER_TOO_SMALL) {
5282#ifdef DEBUG_ACL_QUERY
5283 DbgP("nfs41_QuerySecurityInformation: provided buffer size=%d but we "
5284 "need %lu\n",
5285 RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length,
5286 entry->buf_len);
5287#endif
5289 RxContext->InformationToReturn = entry->buf_len;
5290
5291 /* Save ACL buffer */
5292 nfs41_fobx->acl = entry->buf;
5293 nfs41_fobx->acl_len = entry->buf_len;
5294 KeQuerySystemTime(&nfs41_fobx->time);
5295 } else if (entry->status == STATUS_SUCCESS) {
5297 RxContext->CurrentIrp->UserBuffer;
5298 RtlCopyMemory(sec_desc, entry->buf, entry->buf_len);
5299#ifdef ENABLE_TIMINGS
5300 InterlockedIncrement(&getacl.sops);
5301 InterlockedAdd64(&getacl.size, entry->u.Acl.buf_len);
5302#endif
5303 RxFreePool(entry->buf);
5304 nfs41_fobx->acl = NULL;
5305 nfs41_fobx->acl_len = 0;
5306 RxContext->IoStatusBlock.Information = RxContext->InformationToReturn =
5307 entry->buf_len;
5308 RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
5309 } else {
5310 status = map_query_acl_error(entry->status);
5311 }
5313out:
5314#ifdef ENABLE_TIMINGS
5316 /* only count getacl that we made an upcall for */
5318 InterlockedIncrement(&getacl.tops);
5319 InterlockedAdd64(&getacl.ticks, t2.QuadPart - t1.QuadPart);
5320 }
5321#ifdef ENABLE_INDV_TIMINGS
5322 DbgP("nfs41_QuerySecurityInformation: delta = %d op=%d sum=%d\n",
5323 t2.QuadPart - t1.QuadPart, getacl.tops, getacl.ticks);
5324#endif
5325#endif
5326#ifdef DEBUG_ACL_QUERY
5327 DbgEx();
5328#endif
5329 return status;
5330}
5331
5333 PRX_CONTEXT RxContext)
5334{
5336 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5339 RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityInformation;
5340
5341 if (pVNetRootContext->read_only) {
5342 print_error("check_nfs41_setacl_args: Read-only mount\n");
5344 goto out;
5345 }
5346 /* we don't support sacls */
5350 goto out;
5351 }
5352out:
5353 return status;
5354}
5355
5356#ifdef __REACTOS__
5358#else
5360#endif
5361 IN OUT PRX_CONTEXT RxContext)
5362{
5365 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
5366 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
5367 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5368 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
5369 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
5370 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
5372 RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityDescriptor;
5373 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
5375 RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityInformation;
5376#ifdef ENABLE_TIMINGS
5377 LARGE_INTEGER t1, t2;
5379#endif
5380
5381#ifdef DEBUG_ACL_SET
5382 DbgEn();
5383 print_debug_header(RxContext);
5385#endif
5386
5387 status = check_nfs41_setacl_args(RxContext);
5388 if (status) goto out;
5389
5390 /* check that ACL is present */
5392 PACL acl;
5393 BOOLEAN present, dacl_default;
5394 status = RtlGetDaclSecurityDescriptor(sec_desc, &present, &acl,
5395 &dacl_default);
5396 if (status) {
5397 DbgP("RtlGetDaclSecurityDescriptor failed %x\n", status);
5398 goto out;
5399 }
5400 if (present == FALSE) {
5401 DbgP("NO ACL present\n");
5402 goto out;
5403 }
5404 }
5405
5406 status = nfs41_UpcallCreate(NFS41_ACL_SET, &nfs41_fobx->sec_ctx,
5407 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
5408 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
5409 if (status) goto out;
5410
5411 entry->u.Acl.query = info_class;
5412 entry->buf = sec_desc;
5413 entry->buf_len = RtlLengthSecurityDescriptor(sec_desc);
5414#ifdef ENABLE_TIMINGS
5415 InterlockedIncrement(&setacl.sops);
5416 InterlockedAdd64(&setacl.size, entry->u.Acl.buf_len);
5417#endif
5418
5419 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
5420 if (status) goto out;
5421
5422 status = map_query_acl_error(entry->status);
5423 if (!status) {
5424 if (!nfs41_fobx->deleg_type && entry->ChangeTime &&
5425 (SrvOpen->DesiredAccess &
5427 nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
5428 nfs41_fcb->changeattr = entry->ChangeTime;
5429 }
5431out:
5432#ifdef ENABLE_TIMINGS
5434 InterlockedIncrement(&setacl.tops);
5435 InterlockedAdd64(&setacl.ticks, t2.QuadPart - t1.QuadPart);
5436#ifdef ENABLE_INDV_TIMINGS
5437 DbgP("nfs41_SetSecurityInformation delta = %d op=%d sum=%d\n",
5438 t2.QuadPart - t1.QuadPart, setacl.tops, setacl.ticks);
5439#endif
5440#endif
5441#ifdef DEBUG_ACL_SET
5442 DbgEx();
5443#endif
5444 return status;
5445}
5446
5448 DWORD error)
5449{
5450 switch (error) {
5454 default:
5455 print_error("failed to map windows error %d to NTSTATUS; "
5456 "defaulting to STATUS_INVALID_NETWORK_RESPONSE\n", error);
5458 }
5459}
5460
5461#ifdef __REACTOS__
5463#else
5465#endif
5466 IN OUT PRX_CONTEXT RxContext)
5467{
5469 FILE_INFORMATION_CLASS InfoClass = RxContext->Info.FileInformationClass;
5471 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
5472 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5473 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
5474 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
5475 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
5476 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
5477 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
5478#ifdef ENABLE_TIMINGS
5479 LARGE_INTEGER t1, t2;
5481#endif
5482
5483#ifdef DEBUG_FILE_QUERY
5484 DbgEn();
5486#endif
5487
5488 status = check_nfs41_dirquery_args(RxContext);
5489 if (status) goto out;
5490
5491 switch (InfoClass) {
5492 case FileEaInformation:
5493 {
5495 (PFILE_EA_INFORMATION)RxContext->Info.Buffer;
5496 info->EaSize = 0;
5497 RxContext->Info.LengthRemaining -= sizeof(FILE_EA_INFORMATION);
5499 goto out;
5500 }
5506 break;
5507 default:
5508 print_error("nfs41_QueryFileInformation: unhandled class %d\n", InfoClass);
5510 goto out;
5511 }
5512
5513 status = nfs41_UpcallCreate(NFS41_FILE_QUERY, &nfs41_fobx->sec_ctx,
5514 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
5515 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
5516 if (status) goto out;
5517
5518 entry->u.QueryFile.InfoClass = InfoClass;
5519 entry->buf = RxContext->Info.Buffer;
5520 entry->buf_len = RxContext->Info.LengthRemaining;
5521
5522 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
5523 if (status) goto out;
5524
5525 if (entry->status == STATUS_BUFFER_TOO_SMALL) {
5526 RxContext->InformationToReturn = entry->buf_len;
5528 } else if (entry->status == STATUS_SUCCESS) {
5529 BOOLEAN DeletePending = FALSE;
5530#ifdef ENABLE_TIMINGS
5531 InterlockedIncrement(&getattr.sops);
5532 InterlockedAdd64(&getattr.size, entry->u.QueryFile.buf_len);
5533#endif
5534 RxContext->Info.LengthRemaining -= entry->buf_len;
5536
5537 switch (InfoClass) {
5539 RtlCopyMemory(&nfs41_fcb->BasicInfo, RxContext->Info.Buffer,
5540 sizeof(nfs41_fcb->BasicInfo));
5541#ifdef DEBUG_FILE_QUERY
5542 print_basic_info(1, &nfs41_fcb->BasicInfo);
5543#endif
5544 break;
5546 /* this a fix for RDBSS behaviour when it first calls ExtendForCache,
5547 * then it sends a file query irp for standard attributes and
5548 * expects to receive EndOfFile of value set by the ExtendForCache.
5549 * It seems to cache the filesize based on that instead of sending
5550 * a file size query for after doing the write.
5551 */
5552 {
5554 std_info = (PFILE_STANDARD_INFORMATION)RxContext->Info.Buffer;
5555 if (nfs41_fcb->StandardInfo.AllocationSize.QuadPart >
5556 std_info->AllocationSize.QuadPart) {
5557#ifdef DEBUG_FILE_QUERY
5558 DbgP("Old AllocationSize is bigger: saving %x\n",
5559 nfs41_fcb->StandardInfo.AllocationSize.QuadPart);
5560#endif
5561 std_info->AllocationSize.QuadPart =
5562 nfs41_fcb->StandardInfo.AllocationSize.QuadPart;
5563 }
5564 if (nfs41_fcb->StandardInfo.EndOfFile.QuadPart >
5565 std_info->EndOfFile.QuadPart) {
5566#ifdef DEBUG_FILE_QUERY
5567 DbgP("Old EndOfFile is bigger: saving %x\n",
5568 nfs41_fcb->StandardInfo.EndOfFile);
5569#endif
5570 std_info->EndOfFile.QuadPart =
5571 nfs41_fcb->StandardInfo.EndOfFile.QuadPart;
5572 }
5573 std_info->DeletePending = nfs41_fcb->DeletePending;
5574 }
5575 if (nfs41_fcb->StandardInfo.DeletePending)
5576 DeletePending = TRUE;
5577 RtlCopyMemory(&nfs41_fcb->StandardInfo, RxContext->Info.Buffer,
5578 sizeof(nfs41_fcb->StandardInfo));
5579 nfs41_fcb->StandardInfo.DeletePending = DeletePending;
5580#ifdef DEBUG_FILE_QUERY
5581 print_std_info(1, &nfs41_fcb->StandardInfo);
5582#endif
5583 break;
5584 }
5585 } else {
5586 status = map_queryfile_error(entry->status);
5587 }
5589out:
5590#ifdef ENABLE_TIMINGS
5592 InterlockedIncrement(&getattr.tops);
5593 InterlockedAdd64(&getattr.ticks, t2.QuadPart - t1.QuadPart);
5594#ifdef ENABLE_INDV_TIMINGS
5595 DbgP("nfs41_QueryFileInformation delta = %d op=%d sum=%d\n",
5596 t2.QuadPart - t1.QuadPart, getattr.tops, getattr.ticks);
5597#endif
5598#endif
5599#ifdef DEBUG_FILE_QUERY
5600 DbgEx();
5601#endif
5602 return status;
5603}
5604
5606 DWORD error)
5607{
5608 switch (error) {
5609 case NO_ERROR: return STATUS_SUCCESS;
5621 default:
5622 print_error("failed to map windows error %d to NTSTATUS; "
5623 "defaulting to STATUS_INVALID_PARAMETER\n", error);
5625 }
5626}
5627
5629 IN PRX_CONTEXT RxContext)
5630{
5632 FILE_INFORMATION_CLASS InfoClass = RxContext->Info.FileInformationClass;
5633 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5634 NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
5635
5636 if (pVNetRootContext->read_only) {
5637 print_error("check_nfs41_setattr_args: Read-only mount\n");
5639 goto out;
5640 }
5641
5642 /* http://msdn.microsoft.com/en-us/library/ff469355(v=PROT.10).aspx
5643 * http://msdn.microsoft.com/en-us/library/ff469424(v=PROT.10).aspx
5644 * If Open.GrantedAccess does not contain FILE_WRITE_DATA, the operation
5645 * MUST be failed with STATUS_ACCESS_DENIED.
5646 */
5647 if (InfoClass == FileAllocationInformation ||
5648 InfoClass == FileEndOfFileInformation) {
5649 if (!(RxContext->pRelevantSrvOpen->DesiredAccess & FILE_WRITE_DATA)) {
5651 goto out;
5652 }
5653 }
5654 status = check_nfs41_dirquery_args(RxContext);
5655 if (status) goto out;
5656
5657 switch (InfoClass) {
5659 {
5661 (PFILE_RENAME_INFORMATION)RxContext->Info.Buffer;
5663 (USHORT)rinfo->FileNameLength, rinfo->FileName };
5664#ifdef DEBUG_FILE_SET
5665 DbgP("Attempting to rename to '%wZ'\n", &dst);
5666#endif
5667 if (isFilenameTooLong(&dst, pVNetRootContext)) {
5669 goto out;
5670 }
5671 if (rinfo->RootDirectory) {
5673 goto out;
5674 }
5675 break;
5676 }
5678 {
5680 (PFILE_LINK_INFORMATION)RxContext->Info.Buffer;
5682 (USHORT)linfo->FileNameLength, linfo->FileName };
5683#ifdef DEBUG_FILE_SET
5684 DbgP("Attempting to add link as '%wZ'\n", &dst);
5685#endif
5686 if (isFilenameTooLong(&dst, pVNetRootContext)) {
5688 goto out;
5689 }
5690 if (linfo->RootDirectory) {
5692 goto out;
5693 }
5694 break;
5695 }
5697 {
5699 (PFILE_DISPOSITION_INFORMATION)RxContext->Info.Buffer;
5700 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
5701 if (dinfo->DeleteFile && nfs41_fcb->DeletePending) {
5703 goto out;
5704 }
5705 break;
5706 }
5710 break;
5711 default:
5712 print_error("nfs41_SetFileInformation: unhandled class %d\n", InfoClass);
5714 }
5715
5716out:
5717 return status;
5718}
5719
5720#ifdef __REACTOS__
5722#else
5724#endif
5725 IN OUT PRX_CONTEXT RxContext)
5726{
5729 FILE_INFORMATION_CLASS InfoClass = RxContext->Info.FileInformationClass;
5731 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
5732 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5733 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
5734 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
5735 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
5736 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
5737 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
5738#ifdef ENABLE_TIMINGS
5739 LARGE_INTEGER t1, t2;
5741#endif
5742
5743#ifdef DEBUG_FILE_SET
5744 DbgEn();
5746#endif
5747
5748 status = check_nfs41_setattr_args(RxContext);
5749 if (status) goto out;
5750
5751 switch (InfoClass) {
5753 {
5755 (PFILE_DISPOSITION_INFORMATION)RxContext->Info.Buffer;
5756 if (dinfo->DeleteFile) {
5757 nfs41_fcb->DeletePending = TRUE;
5758 // we can delete directories right away
5759 if (nfs41_fcb->StandardInfo.Directory)
5760 break;
5761 nfs41_fcb->StandardInfo.DeletePending = TRUE;
5762 if (RxContext->pFcb->OpenCount > 1) {
5763 rinfo.ReplaceIfExists = 0;
5765 rinfo.FileNameLength = 0;
5766 rinfo.FileName[0] = L'\0';
5767 InfoClass = FileRenameInformation;
5768 nfs41_fcb->Renamed = TRUE;
5769 break;
5770 }
5771 } else {
5772 /* section 4.3.3 of [FSBO]
5773 * "file system behavior in the microsoft windows environment"
5774 */
5775 if (nfs41_fcb->DeletePending) {
5776 nfs41_fcb->DeletePending = 0;
5777 nfs41_fcb->StandardInfo.DeletePending = 0;
5778 }
5779 }
5781 goto out;
5782 }
5784 {
5786 (PFILE_END_OF_FILE_INFORMATION)RxContext->Info.Buffer;
5787 nfs41_fcb->StandardInfo.AllocationSize =
5788 nfs41_fcb->StandardInfo.EndOfFile = info->EndOfFile;
5789 break;
5790 }
5792 {
5793 /* noop if filename and destination are the same */
5795 (PFILE_RENAME_INFORMATION)RxContext->Info.Buffer;
5796 const UNICODE_STRING dst = { (USHORT)prinfo->FileNameLength,
5797 (USHORT)prinfo->FileNameLength, prinfo->FileName };
5799 SrvOpen->pAlreadyPrefixedName, FALSE) == 0) {
5801 goto out;
5802 }
5803 }
5804 }
5805
5806 status = nfs41_UpcallCreate(NFS41_FILE_SET, &nfs41_fobx->sec_ctx,
5807 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
5808 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
5809 if (status) goto out;
5810
5811 entry->u.SetFile.InfoClass = InfoClass;
5812
5813 /* original irp has infoclass for remove but we need to rename instead,
5814 * thus we changed the local variable infoclass */
5815 if (RxContext->Info.FileInformationClass == FileDispositionInformation &&
5816 InfoClass == FileRenameInformation) {
5817 entry->buf = &rinfo;
5818 entry->buf_len = sizeof(rinfo);
5819 } else {
5820 entry->buf = RxContext->Info.Buffer;
5821 entry->buf_len = RxContext->Info.Length;
5822 }
5823#ifdef ENABLE_TIMINGS
5824 InterlockedIncrement(&setattr.sops);
5825 InterlockedAdd64(&setattr.size, entry->u.SetFile.buf_len);
5826#endif
5827
5828 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
5829 if (status) goto out;
5830
5831 status = map_setfile_error(entry->status);
5832 if (!status) {
5833 if (!nfs41_fobx->deleg_type && entry->ChangeTime &&
5834 (SrvOpen->DesiredAccess &
5836 nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
5837 nfs41_fcb->changeattr = entry->ChangeTime;
5838 }
5840out:
5841#ifdef ENABLE_TIMINGS
5843 InterlockedIncrement(&setattr.tops);
5844 InterlockedAdd64(&setattr.ticks, t2.QuadPart - t1.QuadPart);
5845#ifdef ENABLE_INDV_TIMINGS
5846 DbgP("nfs41_SetFileInformation delta = %d op=%d sum=%d\n",
5847 t2.QuadPart - t1.QuadPart, setattr.tops, setattr.ticks);
5848#endif
5849#endif
5850#ifdef DEBUG_FILE_SET
5851 DbgEx();
5852#endif
5853 return status;
5854}
5855
5857 IN OUT PRX_CONTEXT RxContext)
5858{
5860 DbgEn();
5861 status = nfs41_SetFileInformation(RxContext);
5862 DbgEx();
5863 return status;
5864}
5865
5866#ifdef __REACTOS__
5868#else
5870#endif
5871 IN OUT PRX_CONTEXT RxContext,
5872 IN PUNICODE_STRING DirectoryName)
5873{
5874 return STATUS_SUCCESS;
5875}
5876
5877#ifdef __REACTOS__
5879#else
5881#endif
5882 IN OUT PMRX_SRV_OPEN pSrvOpen,
5883 IN PVOID pMRxContext,
5884 OUT ULONG *pNewBufferingState)
5885{
5887 ULONG flag = PtrToUlong(pMRxContext), oldFlags = pSrvOpen->BufferingFlags;
5888
5889 switch(flag) {
5890 case DISABLE_CACHING:
5891 if (pSrvOpen->BufferingFlags &
5893 pSrvOpen->BufferingFlags &=
5896 if (pSrvOpen->BufferingFlags &
5898 pSrvOpen->BufferingFlags &=
5901 pSrvOpen->BufferingFlags |= FCB_STATE_DISABLE_LOCAL_BUFFERING;
5902 break;
5904 pSrvOpen->BufferingFlags |=
5906 break;
5908 pSrvOpen->BufferingFlags |=
5910 break;
5912 pSrvOpen->BufferingFlags =
5915 }
5916#ifdef DEBUG_TIME_BASED_COHERENCY
5917 DbgP("nfs41_ComputeNewBufferingState: %wZ pSrvOpen %p Old %08x New %08x\n",
5918 pSrvOpen->pAlreadyPrefixedName, pSrvOpen, oldFlags,
5919 pSrvOpen->BufferingFlags);
5920 *pNewBufferingState = pSrvOpen->BufferingFlags;
5921#endif
5922 return status;
5923}
5924
5926 PRX_CONTEXT RxContext)
5927{
5928 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
5929
5930 print_debug_header(RxContext);
5931 DbgP("Bytecount 0x%x Byteoffset 0x%x Buffer %p\n",
5932 LowIoContext->ParamsFor.ReadWrite.ByteCount,
5933 LowIoContext->ParamsFor.ReadWrite.ByteOffset,
5934 LowIoContext->ParamsFor.ReadWrite.Buffer);
5935}
5936
5938 PMRX_SRV_OPEN SrvOpen,
5939 PNFS41_FOBX nfs41_fobx,
5940 ULONGLONG ChangeTime,
5942{
5943 ULONG flag = 0;
5946 BOOLEAN found = FALSE;
5947
5948 if (SrvOpen->DesiredAccess & FILE_READ_DATA)
5950 if ((SrvOpen->DesiredAccess & FILE_WRITE_DATA) &&
5951 !nfs41_fobx->write_thru)
5953 if ((SrvOpen->DesiredAccess & FILE_READ_DATA) &&
5954 (SrvOpen->DesiredAccess & FILE_WRITE_DATA) &&
5955 !nfs41_fobx->write_thru)
5957
5958#if defined(DEBUG_TIME_BASED_COHERENCY) || \
5959 defined(DEBUG_WRITE) || defined(DEBUG_READ)
5961#endif
5962
5963 if (!flag)
5964 return;
5965
5967
5970 while (!IsListEmpty(&openlist.head)) {
5973 if (cur->fcb == SrvOpen->pFcb) {
5974#ifdef DEBUG_TIME_BASED_COHERENCY
5975 DbgP("enable_caching: Looked&Found match for fcb=%p %wZ\n",
5976 SrvOpen->pFcb, SrvOpen->pAlreadyPrefixedName);
5977#endif
5978 cur->skip = FALSE;
5979 found = TRUE;
5980 break;
5981 }
5982 if (pEntry->Flink == &openlist.head) {
5983#ifdef DEBUG_TIME_BASED_COHERENCY
5984 DbgP("enable_caching: reached EOL looking for fcb=%p %wZ\n",
5985 SrvOpen->pFcb, SrvOpen->pAlreadyPrefixedName);
5986#endif
5987 break;
5988 }
5989 pEntry = pEntry->Flink;
5990 }
5991 if (!found && nfs41_fobx->deleg_type) {
5992 nfs41_fcb_list_entry *oentry;
5993#ifdef DEBUG_TIME_BASED_COHERENCY
5994 DbgP("enable_caching: delegation recalled: srv_open=%p\n", SrvOpen);
5995#endif
5998 if (oentry == NULL) return;
5999 oentry->fcb = SrvOpen->pFcb;
6000 oentry->session = session;
6001 oentry->nfs41_fobx = nfs41_fobx;
6002 oentry->ChangeTime = ChangeTime;
6003 oentry->skip = FALSE;
6004 InsertTailList(&openlist.head, &oentry->next);
6005 nfs41_fobx->deleg_type = 0;
6006 }
6008}
6009
6011 DWORD status)
6012{
6013 switch (status) {
6021 default:
6022 print_error("failed to map windows error %d to NTSTATUS; "
6023 "defaulting to STATUS_NET_WRITE_FAULT\n", status);
6025 }
6026}
6027
6029 IN PRX_CONTEXT RxContext)
6030{
6031 if (!RxContext->LowIoContext.ParamsFor.ReadWrite.Buffer)
6033 return STATUS_SUCCESS;
6034}
6035
6036#ifdef __REACTOS__
6038#else
6040#endif
6041 IN OUT PRX_CONTEXT RxContext)
6042{
6045 BOOLEAN async = FALSE;
6046 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6047 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6048 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
6049 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6050 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6051 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6052 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
6053 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
6054 DWORD io_delay;
6055#ifdef ENABLE_TIMINGS
6056 LARGE_INTEGER t1, t2;
6058#endif
6059
6060#ifdef DEBUG_READ
6061 DbgEn();
6062 print_readwrite_args(RxContext);
6063#endif
6064 status = check_nfs41_read_args(RxContext);
6065 if (status) goto out;
6066
6067 status = nfs41_UpcallCreate(NFS41_READ, &nfs41_fobx->sec_ctx,
6068 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
6069 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6070 if (status) goto out;
6071
6072 entry->u.ReadWrite.MdlAddress = LowIoContext->ParamsFor.ReadWrite.Buffer;
6073 entry->buf_len = LowIoContext->ParamsFor.ReadWrite.ByteCount;
6074 entry->u.ReadWrite.offset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
6075 if (FlagOn(RxContext->CurrentIrpSp->FileObject->Flags,
6077 entry->u.ReadWrite.rxcontext = RxContext;
6078 async = entry->async_op = TRUE;
6079 }
6080
6081 /* assume network speed is 100MB/s and disk speed is 100MB/s so add
6082 * time to transfer requested bytes over the network and read from disk
6083 */
6084 io_delay = pVNetRootContext->timeout + 2 * entry->buf_len / 104857600;
6086 if (status) goto out;
6087
6088 if (async) {
6089#ifdef DEBUG_READ
6090 DbgP("This is asynchronous read, returning control back to the user\n");
6091#endif
6093 goto out;
6094 }
6095
6096 if (entry->status == NO_ERROR) {
6097#ifdef ENABLE_TIMINGS
6099 InterlockedAdd64(&read.size, entry->u.ReadWrite.len);
6100#endif
6101 status = RxContext->CurrentIrp->IoStatus.Status = STATUS_SUCCESS;
6102 RxContext->IoStatusBlock.Information = entry->buf_len;
6103
6104 if ((!BooleanFlagOn(LowIoContext->ParamsFor.ReadWrite.Flags,
6106 (SrvOpen->DesiredAccess & FILE_READ_DATA) &&
6107 !pVNetRootContext->nocache && !nfs41_fobx->nocache &&
6108 !(SrvOpen->BufferingFlags &
6111 enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr,
6112 pVNetRootContext->session);
6113 }
6114 } else {
6116 RxContext->CurrentIrp->IoStatus.Status = status;
6117 RxContext->IoStatusBlock.Information = 0;
6118 }
6120out:
6121#ifdef ENABLE_TIMINGS
6124 InterlockedAdd64(&read.ticks, t2.QuadPart - t1.QuadPart);
6125#ifdef ENABLE_INDV_TIMINGS
6126 DbgP("nfs41_Read delta = %d op=%d sum=%d\n", t2.QuadPart - t1.QuadPart,
6127 read.tops, read.ticks);
6128#endif
6129#endif
6130#ifdef DEBUG_READ
6131 DbgEx();
6132#endif
6133 return status;
6134}
6135
6137 IN PRX_CONTEXT RxContext)
6138{
6140 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
6141 NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
6142
6143 if (!RxContext->LowIoContext.ParamsFor.ReadWrite.Buffer) {
6145 goto out;
6146 }
6147
6148 if (pVNetRootContext->read_only) {
6149 print_error("check_nfs41_write_args: Read-only mount\n");
6151 goto out;
6152 }
6153out:
6154 return status;
6155}
6156
6157#ifdef __REACTOS__
6159#else
6161#endif
6162 IN OUT PRX_CONTEXT RxContext)
6163{
6166 BOOLEAN async = FALSE;
6167 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6168 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6169 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
6170 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6171 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6172 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6173 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
6174 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
6175 DWORD io_delay;
6176#ifdef ENABLE_TIMINGS
6177 LARGE_INTEGER t1, t2;
6179#endif
6180
6181#ifdef DEBUG_WRITE
6182 DbgEn();
6183 print_readwrite_args(RxContext);
6184#endif
6185
6186 status = check_nfs41_write_args(RxContext);
6187 if (status) goto out;
6188
6189 status = nfs41_UpcallCreate(NFS41_WRITE, &nfs41_fobx->sec_ctx,
6190 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
6191 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6192 if (status) goto out;
6193
6194 entry->u.ReadWrite.MdlAddress = LowIoContext->ParamsFor.ReadWrite.Buffer;
6195 entry->buf_len = LowIoContext->ParamsFor.ReadWrite.ByteCount;
6196 entry->u.ReadWrite.offset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
6197
6198 if (FlagOn(RxContext->CurrentIrpSp->FileObject->Flags,
6200 entry->u.ReadWrite.rxcontext = RxContext;
6201 async = entry->async_op = TRUE;
6202 }
6203
6204 /* assume network speed is 100MB/s and disk speed is 100MB/s so add
6205 * time to transfer requested bytes over the network and write to disk
6206 */
6207 io_delay = pVNetRootContext->timeout + 2 * entry->buf_len / 104857600;
6209 if (status) goto out;
6210
6211 if (async) {
6212#ifdef DEBUG_WRITE
6213 DbgP("This is asynchronous write, returning control back to the user\n");
6214#endif
6216 goto out;
6217 }
6218
6219 if (entry->status == NO_ERROR) {
6220 //update cached file attributes
6221#ifdef ENABLE_TIMINGS
6223 InterlockedAdd64(&write.size, entry->u.ReadWrite.len);
6224#endif
6225 nfs41_fcb->StandardInfo.EndOfFile.QuadPart = entry->buf_len +
6226 entry->u.ReadWrite.offset;
6227 status = RxContext->CurrentIrp->IoStatus.Status = STATUS_SUCCESS;
6228 RxContext->IoStatusBlock.Information = entry->buf_len;
6229 nfs41_fcb->changeattr = entry->ChangeTime;
6230
6231 //re-enable write buffering
6232 if (!BooleanFlagOn(LowIoContext->ParamsFor.ReadWrite.Flags,
6234 (SrvOpen->DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) &&
6235 !pVNetRootContext->write_thru &&
6236 !pVNetRootContext->nocache &&
6237 !nfs41_fobx->write_thru && !nfs41_fobx->nocache &&
6238 !(SrvOpen->BufferingFlags &
6241 enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr,
6242 pVNetRootContext->session);
6243 } else if (!nfs41_fobx->deleg_type)
6244 nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
6245
6246 } else {
6248 RxContext->CurrentIrp->IoStatus.Status = status;
6249 RxContext->IoStatusBlock.Information = 0;
6250 }
6252out:
6253#ifdef ENABLE_TIMINGS
6256 InterlockedAdd64(&write.ticks, t2.QuadPart - t1.QuadPart);
6257#ifdef ENABLE_INDV_TIMINGS
6258 DbgP("nfs41_Write delta = %d op=%d sum=%d\n", t2.QuadPart - t1.QuadPart,
6259 write.tops, write.ticks);
6260#endif
6261#endif
6262#ifdef DEBUG_WRITE
6263 DbgEx();
6264#endif
6265 return status;
6266}
6267
6268#ifdef __REACTOS__
6270#else
6272#endif
6273 IN OUT PMRX_FCB pFcb,
6276 IN ULONG LowIoLockFlags)
6277{
6279#ifdef DEBUG_LOCK
6280 DbgEn();
6281 DbgP("offset 0x%llx, length 0x%llx, exclusive=%u, blocking=%u\n",
6282 ByteOffset->QuadPart,Length->QuadPart,
6283 BooleanFlagOn(LowIoLockFlags, SL_EXCLUSIVE_LOCK),
6284 !BooleanFlagOn(LowIoLockFlags, SL_FAIL_IMMEDIATELY));
6285#endif
6286
6287 /* NFS lock operations with length=0 MUST fail with NFS4ERR_INVAL */
6288 if (Length->QuadPart == 0)
6290
6291#ifdef DEBUG_LOCK
6292 DbgEx();
6293#endif
6294 return status;
6295}
6296
6298 DWORD status)
6299{
6300 switch (status) {
6301 case NO_ERROR: return STATUS_SUCCESS;
6309 /* if we return ERROR_INVALID_PARAMETER, Windows translates that to
6310 * success!! */
6312 default:
6313 print_error("failed to map windows error %d to NTSTATUS; "
6314 "defaulting to STATUS_INVALID_NETWORK_RESPONSE\n", status);
6316 }
6317}
6318
6320 PRX_CONTEXT RxContext)
6321{
6322 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6323 const ULONG flags = LowIoContext->ParamsFor.Locks.Flags;
6324 print_debug_header(RxContext);
6325 DbgP("offset 0x%llx, length 0x%llx, exclusive=%u, blocking=%u\n",
6326 LowIoContext->ParamsFor.Locks.ByteOffset,
6327 LowIoContext->ParamsFor.Locks.Length,
6330}
6331
6332
6333/* use exponential backoff between polls for blocking locks */
6334#define MSEC_TO_RELATIVE_WAIT (-10000)
6335#define MIN_LOCK_POLL_WAIT (500 * MSEC_TO_RELATIVE_WAIT) /* 500ms */
6336#define MAX_LOCK_POLL_WAIT (30000 * MSEC_TO_RELATIVE_WAIT) /* 30s */
6337
6339 IN OUT PLARGE_INTEGER delay)
6340{
6341 if (delay->QuadPart == 0)
6342 delay->QuadPart = MIN_LOCK_POLL_WAIT;
6343 else
6344 delay->QuadPart <<= 1;
6345
6346 if (delay->QuadPart < MAX_LOCK_POLL_WAIT)
6347 delay->QuadPart = MAX_LOCK_POLL_WAIT;
6348}
6349
6350#ifdef __REACTOS__
6352#else
6354#endif
6355 IN OUT PRX_CONTEXT RxContext)
6356{
6359 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6360 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
6361 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6362 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
6363 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6364 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6365 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6366 const ULONG flags = LowIoContext->ParamsFor.Locks.Flags;
6367#ifdef _MSC_VER
6368 LARGE_INTEGER poll_delay = {0};
6369#else
6370 LARGE_INTEGER poll_delay;
6371#endif
6372#ifdef ENABLE_TIMINGS
6373 LARGE_INTEGER t1, t2;
6375#endif
6376
6377#ifndef _MSC_VER
6378 poll_delay.QuadPart = 0;
6379#endif
6380
6381#ifdef DEBUG_LOCK
6382 DbgEn();
6383 print_lock_args(RxContext);
6384#endif
6385
6386/* RxReleaseFcbResourceForThreadInMRx(RxContext, RxContext->pFcb,
6387 LowIoContext->ResourceThreadId); */
6388
6389 status = nfs41_UpcallCreate(NFS41_LOCK, &nfs41_fobx->sec_ctx,
6390 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
6391 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6392 if (status) goto out;
6393
6394 entry->u.Lock.offset = LowIoContext->ParamsFor.Locks.ByteOffset;
6395 entry->u.Lock.length = LowIoContext->ParamsFor.Locks.Length;
6396 entry->u.Lock.exclusive = BooleanFlagOn(flags, SL_EXCLUSIVE_LOCK);
6397 entry->u.Lock.blocking = !BooleanFlagOn(flags, SL_FAIL_IMMEDIATELY);
6398
6399retry_upcall:
6400 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
6401 if (status) goto out;
6402
6403 /* blocking locks keep trying until it succeeds */
6404 if (entry->status == ERROR_LOCK_FAILED && entry->u.Lock.blocking) {
6405 denied_lock_backoff(&poll_delay);
6406 DbgP("returned ERROR_LOCK_FAILED; retrying in %llums\n",
6407 poll_delay.QuadPart / MSEC_TO_RELATIVE_WAIT);
6410 goto retry_upcall;
6411 }
6412
6413 status = map_lock_errors(entry->status);
6414 RxContext->CurrentIrp->IoStatus.Status = status;
6415
6417out:
6418#ifdef ENABLE_TIMINGS
6421 InterlockedAdd64(&lock.ticks, t2.QuadPart - t1.QuadPart);
6422#ifdef ENABLE_INDV_TIMINGS
6423 DbgP("nfs41_Lock delta = %d op=%d sum=%d\n", t2.QuadPart - t1.QuadPart,
6424 lock.tops, lock.ticks);
6425#endif
6426#endif
6427#ifdef DEBUG_LOCK
6428 DbgEx();
6429#endif
6430 return status;
6431}
6432
6434 PRX_CONTEXT RxContext)
6435{
6436 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6437 print_debug_header(RxContext);
6438 if (LowIoContext->Operation == LOWIO_OP_UNLOCK_MULTIPLE) {
6439 PLOWIO_LOCK_LIST lock = LowIoContext->ParamsFor.Locks.LockList;
6440 DbgP("LOWIO_OP_UNLOCK_MULTIPLE:");
6441 while (lock) {
6442 DbgP(" (offset=%llu, length=%llu)", lock->ByteOffset, lock->Length);
6443 lock = lock->Next;
6444 }
6445 DbgP("\n");
6446 } else {
6447 DbgP("LOWIO_OP_UNLOCK: offset=%llu, length=%llu\n",
6448 LowIoContext->ParamsFor.Locks.ByteOffset,
6449 LowIoContext->ParamsFor.Locks.Length);
6450 }
6451}
6452
6455{
6456 ULONG count = 0;
6457 while (lock) {
6458 count++;
6459 lock = lock->Next;
6460 }
6461 return count;
6462}
6463
6464#ifdef __REACTOS__
6466#else
6468#endif
6469 IN OUT PRX_CONTEXT RxContext)
6470{
6473 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6474 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
6475 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6476 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
6477 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6478 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6479 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6480#ifdef ENABLE_TIMINGS
6481 LARGE_INTEGER t1, t2;
6483#endif
6484#ifdef DEBUG_LOCK
6485 DbgEn();
6486 print_lock_args(RxContext);
6487#endif
6488
6489/* RxReleaseFcbResourceForThreadInMRx(RxContext, RxContext->pFcb,
6490 LowIoContext->ResourceThreadId); */
6491
6492 status = nfs41_UpcallCreate(NFS41_UNLOCK, &nfs41_fobx->sec_ctx,
6493 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
6494 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6495 if (status) goto out;
6496
6497 if (LowIoContext->Operation == LOWIO_OP_UNLOCK_MULTIPLE) {
6498 entry->u.Unlock.count = unlock_list_count(
6499 LowIoContext->ParamsFor.Locks.LockList);
6500 RtlCopyMemory(&entry->u.Unlock.locks,
6501 LowIoContext->ParamsFor.Locks.LockList,
6502 sizeof(LOWIO_LOCK_LIST));
6503 } else {
6504 entry->u.Unlock.count = 1;
6505 entry->u.Unlock.locks.ByteOffset =
6506 LowIoContext->ParamsFor.Locks.ByteOffset;
6507 entry->u.Unlock.locks.Length =
6508 LowIoContext->ParamsFor.Locks.Length;
6509 }
6510
6511 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
6512 if (status) goto out;
6513
6514 status = map_lock_errors(entry->status);
6515 RxContext->CurrentIrp->IoStatus.Status = status;
6517out:
6518#ifdef ENABLE_TIMINGS
6520 InterlockedIncrement(&unlock.tops);
6521 InterlockedAdd64(&unlock.ticks, t2.QuadPart - t1.QuadPart);
6522#ifdef ENABLE_INDV_TIMINGS
6523 DbgP("nfs41_Unlock delta = %d op=%d sum=%d\n", t2.QuadPart - t1.QuadPart,
6524 unlock.tops, unlock.ticks);
6525#endif
6526#endif
6527#ifdef DEBUG_LOCK
6528 DbgEx();
6529#endif
6530 return status;
6531}
6532
6535{
6536 switch (status) {
6537 case NO_ERROR: return STATUS_SUCCESS;
6546 default:
6547 print_error("failed to map windows error %d to NTSTATUS; "
6548 "defaulting to STATUS_INVALID_NETWORK_RESPONSE\n", status);
6550 }
6551}
6552
6554 PREPARSE_DATA_BUFFER Reparse)
6555{
6557 DbgP("ReparseTag: %08X\n", Reparse->ReparseTag);
6558 DbgP("ReparseDataLength: %8u\n", Reparse->ReparseDataLength);
6559 DbgP("Reserved: %8u\n", Reparse->Reserved);
6560 DbgP("SubstituteNameOffset: %8u\n",
6561 Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset);
6562 DbgP("SubstituteNameLength: %8u\n",
6563 Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength);
6564 DbgP("PrintNameOffset: %8u\n",
6565 Reparse->SymbolicLinkReparseBuffer.PrintNameOffset);
6566 DbgP("PrintNameLength: %8u\n",
6567 Reparse->SymbolicLinkReparseBuffer.PrintNameLength);
6568 DbgP("Flags: %08X\n",
6569 Reparse->SymbolicLinkReparseBuffer.Flags);
6570
6571 name.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
6572 Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
6573 name.MaximumLength = name.Length =
6574 Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength;
6575 DbgP("SubstituteName: %wZ\n", &name);
6576
6577 name.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
6578 Reparse->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
6579 name.MaximumLength = name.Length =
6580 Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
6581 DbgP("PrintName: %wZ\n", &name);
6582}
6583
6585 IN PRX_CONTEXT RxContext)
6586{
6588 __notnull XXCTL_LOWIO_COMPONENT *FsCtl = &RxContext->LowIoContext.ParamsFor.FsCtl;
6589 __notnull PREPARSE_DATA_BUFFER Reparse = (PREPARSE_DATA_BUFFER)FsCtl->pInputBuffer;
6590 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6591 __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
6592 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6593 const ULONG HeaderLen = REPARSE_DATA_BUFFER_HEADER_SIZE;
6594
6595 /* access checks */
6596 if (VNetRootContext->read_only) {
6598 goto out;
6599 }
6600 if (!(SrvOpen->DesiredAccess & (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES))) {
6602 goto out;
6603 }
6604
6605 /* must have a filename longer than vnetroot name,
6606 * or it's trying to operate on the volume itself */
6607 if (is_root_directory(RxContext)) {
6609 goto out;
6610 }
6611 if (FsCtl->pOutputBuffer != NULL) {
6613 goto out;
6614 }
6615
6616 /* validate input buffer and length */
6617 if (!Reparse) {
6619 goto out;
6620 }
6621
6622 if (FsCtl->InputBufferLength < HeaderLen ||
6623 FsCtl->InputBufferLength > MAXIMUM_REPARSE_DATA_BUFFER_SIZE) {
6625 goto out;
6626 }
6627 if (FsCtl->InputBufferLength != HeaderLen + Reparse->ReparseDataLength) {
6629 goto out;
6630 }
6631
6632 /* validate reparse tag */
6633 if (!IsReparseTagValid(Reparse->ReparseTag)) {
6635 goto out;
6636 }
6637 if (Reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
6639 goto out;
6640 }
6641out:
6642 return status;
6643}
6644
6646 IN OUT PRX_CONTEXT RxContext)
6647{
6650 __notnull XXCTL_LOWIO_COMPONENT *FsCtl = &RxContext->LowIoContext.ParamsFor.FsCtl;
6651 __notnull PREPARSE_DATA_BUFFER Reparse = (PREPARSE_DATA_BUFFER)FsCtl->pInputBuffer;
6652 __notnull PNFS41_FOBX Fobx = NFS41GetFobxExtension(RxContext->pFobx);
6653 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6654 __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
6655 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6656 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6657 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6659
6660#ifdef DEBUG_SYMLINK
6661 DbgEn();
6662 print_debug_header(RxContext);
6663 print_reparse_buffer(Reparse);
6664#endif
6666 if (status) goto out;
6667
6668 TargetName.MaximumLength = TargetName.Length =
6669 Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
6670 TargetName.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
6671 Reparse->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
6672
6673 status = nfs41_UpcallCreate(NFS41_SYMLINK, &Fobx->sec_ctx,
6674 VNetRootContext->session, Fobx->nfs41_open_state,
6675 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6676 if (status) goto out;
6677
6678 entry->u.Symlink.target = &TargetName;
6679 entry->u.Symlink.set = TRUE;
6680
6681 status = nfs41_UpcallWaitForReply(entry, VNetRootContext->timeout);
6682 if (status) goto out;
6683
6684 status = map_symlink_errors(entry->status);
6686out:
6687#ifdef DEBUG_SYMLINK
6688 DbgEx();
6689#endif
6690 return status;
6691}
6692
6694 PRX_CONTEXT RxContext)
6695{
6698 const USHORT HeaderLen = FIELD_OFFSET(REPARSE_DATA_BUFFER,
6699 SymbolicLinkReparseBuffer.PathBuffer);
6700
6701 /* must have a filename longer than vnetroot name,
6702 * or it's trying to operate on the volume itself */
6703 if (is_root_directory(RxContext)) {
6705 goto out;
6706 }
6707 /* ifs reparse tests expect STATUS_INVALID_PARAMETER,
6708 * but 'dir' passes a buffer here when querying symlinks
6709 if (FsCtl->pInputBuffer != NULL) {
6710 status = STATUS_INVALID_PARAMETER;
6711 goto out;
6712 } */
6713 if (!FsCtl->pOutputBuffer) {
6715 goto out;
6716 }
6717 if (!BooleanFlagOn(RxContext->pFcb->Attributes,
6720 DbgP("FILE_ATTRIBUTE_REPARSE_POINT is not set!\n");
6721 goto out;
6722 }
6723
6724 if (FsCtl->OutputBufferLength < HeaderLen) {
6725 RxContext->InformationToReturn = HeaderLen;
6727 goto out;
6728 }
6729out:
6730 return status;
6731}
6732
6734 IN OUT PRX_CONTEXT RxContext)
6735{
6738 XXCTL_LOWIO_COMPONENT *FsCtl = &RxContext->LowIoContext.ParamsFor.FsCtl;
6739 __notnull PNFS41_FOBX Fobx = NFS41GetFobxExtension(RxContext->pFobx);
6740 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6741 __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
6742 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6743 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6744 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6746 const USHORT HeaderLen = FIELD_OFFSET(REPARSE_DATA_BUFFER,
6747 SymbolicLinkReparseBuffer.PathBuffer);
6748
6749#ifdef DEBUG_SYMLINK
6750 DbgEn();
6751#endif
6753 if (status) goto out;
6754
6755 TargetName.Buffer = (PWCH)((PBYTE)FsCtl->pOutputBuffer + HeaderLen);
6756 TargetName.MaximumLength = (USHORT)min(FsCtl->OutputBufferLength -
6757 HeaderLen, 0xFFFF);
6758
6759 status = nfs41_UpcallCreate(NFS41_SYMLINK, &Fobx->sec_ctx,
6760 VNetRootContext->session, Fobx->nfs41_open_state,
6761 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6762 if (status) goto out;
6763
6764 entry->u.Symlink.target = &TargetName;
6765 entry->u.Symlink.set = FALSE;
6766
6767 status = nfs41_UpcallWaitForReply(entry, VNetRootContext->timeout);
6768 if (status) goto out;
6769
6770 status = map_symlink_errors(entry->status);
6771 if (status == STATUS_SUCCESS) {
6772 /* fill in the output buffer */
6774 FsCtl->pOutputBuffer;
6776 Reparse->ReparseDataLength = HeaderLen + TargetName.Length -
6778 Reparse->Reserved = 0;
6780 /* PrintName and SubstituteName point to the same string */
6781 Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
6782 Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength =
6783 TargetName.Length;
6784 Reparse->SymbolicLinkReparseBuffer.PrintNameOffset = 0;
6785 Reparse->SymbolicLinkReparseBuffer.PrintNameLength = TargetName.Length;
6786 print_reparse_buffer(Reparse);
6787
6788 RxContext->IoStatusBlock.Information = HeaderLen + TargetName.Length;
6789 } else if (status == STATUS_BUFFER_TOO_SMALL) {
6790 RxContext->InformationToReturn = HeaderLen + TargetName.Length;
6791 }
6793out:
6794#ifdef DEBUG_SYMLINK
6795 DbgEx();
6796#endif
6797 return status;
6798}
6799
6800#ifdef __REACTOS__
6802#else
6804#endif
6805 IN OUT PRX_CONTEXT RxContext)
6806{
6808#ifdef DEBUG_MISC
6809 DbgEn();
6810 print_debug_header(RxContext);
6811#endif
6812 switch (RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode) {
6814 status = nfs41_SetReparsePoint(RxContext);
6815 break;
6816
6818 status = nfs41_GetReparsePoint(RxContext);
6819 break;
6820#ifdef DEBUG_MISC
6821 default:
6822 DbgP("FsControlCode: %d\n",
6823 RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode);
6824#endif
6825 }
6826#ifdef DEBUG_MISC
6827 DbgEx();
6828#endif
6829 return status;
6830}
6831
6832#ifdef __REACTOS__
6834#else
6836#endif
6837 IN OUT PRX_CONTEXT RxContext,
6838 IN OUT PMRX_SRV_OPEN SrvOpen,
6839 IN PVOID pContext)
6840{
6841 return STATUS_SUCCESS;
6842}
6843
6844#ifdef __REACTOS__
6846#else
6848#endif
6850 IN PIRP Irp)
6851{
6852#ifdef DEBUG_FSDDISPATCH
6854#endif
6856
6857#ifdef DEBUG_FSDDISPATCH
6858 DbgEn();
6859 DbgP("CURRENT IRP = %d.%d\n", IrpSp->MajorFunction, IrpSp->MinorFunction);
6860 if(IrpSp->FileObject)
6861 DbgP("FileOject %p Filename %wZ\n", IrpSp->FileObject,
6862 &IrpSp->FileObject->FileName);
6863#endif
6864
6865 if (dev != (PDEVICE_OBJECT)nfs41_dev) {
6866 print_error("*** not ours ***\n");
6867 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
6868 Irp->IoStatus.Information = 0;
6871 goto out;
6872 }
6873
6875 /* AGLO: 08/05/2009 - looks like RxFsdDispatch frees IrpSp */
6876
6877out:
6878#ifdef DEBUG_FSDDISPATCH
6879 DbgP("IoStatus status = 0x%x info = 0x%x\n", Irp->IoStatus.Status,
6880 Irp->IoStatus.Information);
6881 DbgEx();
6882#endif
6883 return status;
6884}
6885
6886#ifdef __REACTOS__
6888#else
6890#endif
6891 PRX_CONTEXT RxContext)
6892{
6894}
6895
6896#ifdef __REACTOS__
6898#else
6900#endif
6901 PFCB a,
6902 PFCB b)
6903{
6905}
6906
6908{
6909 DbgEn();
6910
6912 sizeof(MINIRDR_DISPATCH));
6913
6918
6919 nfs41_ops.MRxSrvCallSize = 0; // srvcall extension is not handled in rdbss
6920 nfs41_ops.MRxNetRootSize = sizeof(NFS41_NETROOT_EXTENSION);
6921 nfs41_ops.MRxVNetRootSize = sizeof(NFS41_V_NET_ROOT_EXTENSION);
6922 nfs41_ops.MRxFcbSize = sizeof(NFS41_FCB);
6923 nfs41_ops.MRxFobxSize = sizeof(NFS41_FOBX);
6924
6925 // Mini redirector cancel routine ..
6926
6927 nfs41_ops.MRxCancel = NULL;
6928
6929 //
6930 // Mini redirector Start/Stop. Each mini-rdr can be started or stopped
6931 // while the others continue to operate.
6932 //
6933
6934 nfs41_ops.MRxStart = nfs41_Start;
6935 nfs41_ops.MRxStop = nfs41_Stop;
6936 nfs41_ops.MRxDevFcbXXXControlFile = nfs41_DevFcbXXXControlFile;
6937
6938 //
6939 // Mini redirector name resolution.
6940 //
6941
6942 nfs41_ops.MRxCreateSrvCall = nfs41_CreateSrvCall;
6943 nfs41_ops.MRxSrvCallWinnerNotify = nfs41_SrvCallWinnerNotify;
6944 nfs41_ops.MRxCreateVNetRoot = nfs41_CreateVNetRoot;
6945 nfs41_ops.MRxExtractNetRootName = nfs41_ExtractNetRootName;
6946 nfs41_ops.MRxFinalizeSrvCall = nfs41_FinalizeSrvCall;
6947 nfs41_ops.MRxFinalizeNetRoot = nfs41_FinalizeNetRoot;
6948 nfs41_ops.MRxFinalizeVNetRoot = nfs41_FinalizeVNetRoot;
6949
6950 //
6951 // File System Object Creation/Deletion.
6952 //
6953
6954 nfs41_ops.MRxCreate = nfs41_Create;
6955 nfs41_ops.MRxCollapseOpen = nfs41_CollapseOpen;
6956 nfs41_ops.MRxShouldTryToCollapseThisOpen = nfs41_ShouldTryToCollapseThisOpen;
6957 nfs41_ops.MRxExtendForCache = nfs41_ExtendForCache;
6958 nfs41_ops.MRxExtendForNonCache = nfs41_ExtendForCache;
6959 nfs41_ops.MRxCloseSrvOpen = nfs41_CloseSrvOpen;
6960 nfs41_ops.MRxFlush = nfs41_Flush;
6961 nfs41_ops.MRxDeallocateForFcb = nfs41_DeallocateForFcb;
6962 nfs41_ops.MRxDeallocateForFobx = nfs41_DeallocateForFobx;
6963 nfs41_ops.MRxIsLockRealizable = nfs41_IsLockRealizable;
6964
6965 //
6966 // File System Objects query/Set
6967 //
6968
6969 nfs41_ops.MRxQueryDirectory = nfs41_QueryDirectory;
6970 nfs41_ops.MRxQueryVolumeInfo = nfs41_QueryVolumeInformation;
6971 nfs41_ops.MRxQueryEaInfo = nfs41_QueryEaInformation;
6972 nfs41_ops.MRxSetEaInfo = nfs41_SetEaInformation;
6975 nfs41_ops.MRxQueryFileInfo = nfs41_QueryFileInformation;
6976 nfs41_ops.MRxSetFileInfo = nfs41_SetFileInformation;
6977
6978 //
6979 // Buffering state change
6980 //
6981
6982 nfs41_ops.MRxComputeNewBufferingState = nfs41_ComputeNewBufferingState;
6983
6984 //
6985 // File System Object I/O
6986 //
6987
6988 nfs41_ops.MRxLowIOSubmit[LOWIO_OP_READ] = nfs41_Read;
6989 nfs41_ops.MRxLowIOSubmit[LOWIO_OP_WRITE] = nfs41_Write;
6990 nfs41_ops.MRxLowIOSubmit[LOWIO_OP_SHAREDLOCK] = nfs41_Lock;
6992 nfs41_ops.MRxLowIOSubmit[LOWIO_OP_UNLOCK] = nfs41_Unlock;
6994 nfs41_ops.MRxLowIOSubmit[LOWIO_OP_FSCTL] = nfs41_FsCtl;
6995
6996 //
6997 // Miscellanous
6998 //
6999
7000 nfs41_ops.MRxCompleteBufferingStateChangeRequest =
7002 nfs41_ops.MRxIsValidDirectory = nfs41_IsValidDirectory;
7003
7004 nfs41_ops.MRxTruncate = nfs41_Unimplemented;
7005 nfs41_ops.MRxZeroExtend = nfs41_Unimplemented;
7006 nfs41_ops.MRxAreFilesAliased = nfs41_AreFilesAliased;
7007 nfs41_ops.MRxQueryQuotaInfo = nfs41_Unimplemented;
7008 nfs41_ops.MRxSetQuotaInfo = nfs41_Unimplemented;
7009 nfs41_ops.MRxSetVolumeInfo = nfs41_Unimplemented;
7010
7011 DbgR();
7012 return(STATUS_SUCCESS);
7013}
7014
7015KSTART_ROUTINE fcbopen_main;
7016#ifdef __REACTOS__
7018#else
7020#endif
7021{
7024
7025 DbgEn();
7026 timeout.QuadPart = RELATIVE(SECONDS(30));
7027 while(1) {
7033 while (!IsListEmpty(&openlist.head)) {
7034 PNFS41_NETROOT_EXTENSION pNetRootContext;
7037 PNFS41_FCB nfs41_fcb;
7040
7041#ifdef DEBUG_TIME_BASED_COHERENCY
7042 DbgP("fcbopen_main: Checking attributes for fcb=%p "
7043 "change_time=%llu skipping=%d\n", cur->fcb,
7044 cur->ChangeTime, cur->skip);
7045#endif
7046 if (cur->skip) goto out;
7047 pNetRootContext =
7048 NFS41GetNetRootExtension(cur->fcb->pNetRoot);
7049 /* place an upcall for this srv_open */
7051 &cur->nfs41_fobx->sec_ctx, cur->session,
7052 cur->nfs41_fobx->nfs41_open_state,
7053 pNetRootContext->nfs41d_version, NULL, &entry);
7054 if (status) goto out;
7055
7056 entry->u.QueryFile.InfoClass = FileBasicInformation;
7057 entry->buf = &binfo;
7058 entry->buf_len = sizeof(binfo);
7059
7061 if (status) goto out;
7062
7063 if (cur->ChangeTime != entry->ChangeTime) {
7065 PMRX_SRV_OPEN srv_open;
7066 PLIST_ENTRY psrvEntry;
7067#ifdef DEBUG_TIME_BASED_COHERENCY
7068 DbgP("fcbopen_main: old ctime=%llu new_ctime=%llu\n",
7069 cur->ChangeTime, entry->ChangeTime);
7070#endif
7071 cur->ChangeTime = entry->ChangeTime;
7072 cur->skip = TRUE;
7073 psrvEntry = &cur->fcb->SrvOpenList;
7074 psrvEntry = psrvEntry->Flink;
7075 while (!IsListEmpty(&cur->fcb->SrvOpenList)) {
7076 srv_open = (PMRX_SRV_OPEN)CONTAINING_RECORD(psrvEntry,
7077 MRX_SRV_OPEN, SrvOpenQLinks);
7078 if (srv_open->DesiredAccess &
7080#ifdef DEBUG_TIME_BASED_COHERENCY
7081 DbgP("fcbopen_main: ************ Invalidate the cache %wZ"
7082 "************\n", srv_open->pAlreadyPrefixedName);
7083#endif
7085 cur->fcb->pNetRoot->pSrvCall, srv_open,
7086 srv_open->Key, ULongToPtr(flag));
7087 }
7088 if (psrvEntry->Flink == &cur->fcb->SrvOpenList) {
7089#ifdef DEBUG_TIME_BASED_COHERENCY
7090 DbgP("fcbopen_main: reached end of srvopen for fcb %p\n",
7091 cur->fcb);
7092#endif
7093 break;
7094 }
7095 psrvEntry = psrvEntry->Flink;
7096 };
7097 }
7098 nfs41_fcb = (PNFS41_FCB)cur->fcb->Context;
7099 nfs41_fcb->changeattr = entry->ChangeTime;
7101out:
7102 if (pEntry->Flink == &openlist.head) {
7103#ifdef DEBUG_TIME_BASED_COHERENCY
7104 DbgP("fcbopen_main: reached end of the fcb list\n");
7105#endif
7106 break;
7107 }
7108 pEntry = pEntry->Flink;
7109 }
7111 }
7112 DbgEx();
7113}
7114
7115#ifdef __REACTOS__
7117#else
7119#endif
7120 IN PDRIVER_OBJECT drv,
7122{
7124 ULONG flags = 0, i;
7125 UNICODE_STRING dev_name, user_dev_name;
7126 PNFS41_DEVICE_EXTENSION dev_exts;
7127 TIME_FIELDS jan_1_1970 = {1970, 1, 1, 0, 0, 0, 0, 0};
7128 ACCESS_MASK mask = 0;
7129 OBJECT_ATTRIBUTES oattrs;
7130
7131 DbgEn();
7132
7133 status = RxDriverEntry(drv, path);
7134 if (status != STATUS_SUCCESS) {
7135 print_error("RxDriverEntry failed: %08lx\n", status);
7136 goto out;
7137 }
7138
7141
7143 if (status != STATUS_SUCCESS) {
7144 print_error("nfs41_init_ops failed to initialize dispatch table\n");
7145 goto out;
7146 }
7147
7148 DbgP("calling RxRegisterMinirdr\n");
7150 sizeof(NFS41_DEVICE_EXTENSION),
7152 if (status != STATUS_SUCCESS) {
7153 print_error("RxRegisterMinirdr failed: %08lx\n", status);
7154 goto out;
7155 }
7156#ifndef __REACTOS__
7157 nfs41_dev->Flags |= DO_BUFFERED_IO;
7158#endif
7159
7160 dev_exts = (PNFS41_DEVICE_EXTENSION)
7161 ((PBYTE)(nfs41_dev) + sizeof(RDBSS_DEVICE_OBJECT));
7162
7164 dev_exts->DeviceObject = nfs41_dev;
7166 &dev_exts->VolAttrsLen);
7167
7169 DbgP("calling IoCreateSymbolicLink %wZ %wZ\n", &user_dev_name, &dev_name);
7170 status = IoCreateSymbolicLink(&user_dev_name, &dev_name);
7171 if (status != STATUS_SUCCESS) {
7172 print_error("Device name IoCreateSymbolicLink failed: %08lx\n", status);
7173 goto out_unregister;
7174 }
7175
7187 &oattrs, NULL, NULL, &fcbopen_main, NULL);
7188 if (status != STATUS_SUCCESS)
7189 goto out_unregister;
7190
7191 drv->DriverUnload = nfs41_driver_unload;
7192
7193 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
7194 drv->MajorFunction[i] = (PDRIVER_DISPATCH)nfs41_FsdDispatch;
7195
7196 RtlTimeFieldsToTime(&jan_1_1970, &unix_time_diff);
7197
7198out_unregister:
7199 if (status != STATUS_SUCCESS)
7201out:
7202 DbgEx();
7203 return status;
7204}
7205
7206#ifdef __REACTOS__
7208#else
7210#endif
7211{
7212 PRX_CONTEXT RxContext;
7214 UNICODE_STRING dev_name, pipe_name;
7215
7216 DbgEn();
7217
7219 if (RxContext == NULL) {
7221 goto unload;
7222 }
7223 status = RxStopMinirdr(RxContext, &RxContext->PostRequest);
7225
7226unload:
7229 if (status != STATUS_SUCCESS) {
7230 print_error("couldn't delete device symbolic link\n");
7231 }
7233 status = IoDeleteSymbolicLink(&pipe_name);
7234 if (status != STATUS_SUCCESS) {
7235 print_error("couldn't delete pipe symbolic link\n");
7236 }
7237 RxUnload(drv);
7238
7239 DbgP("driver unloaded %p\n", drv);
7240 DbgR();
7241}
unsigned char BOOLEAN
#define read
Definition: acwin.h:96
#define open
Definition: acwin.h:95
#define close
Definition: acwin.h:98
#define write
Definition: acwin.h:97
struct NameRec_ * Name
Definition: cdprocs.h:460
static int state
Definition: maze.c:121
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define InterlockedIncrement
Definition: armddk.h:53
#define SLASH(w)
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
#define CHAR(Char)
#define ULongToPtr(ul)
Definition: basetsd.h:92
#define InterlockedIncrement64(a)
Definition: btrfs_drv.h:143
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1417
_In_ PFCB Fcb
Definition: cdprocs.h:159
_In_ BOOLEAN Release
Definition: cdrom.h:920
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
_In_ PIRP Irp
Definition: csq.h:116
const char * opcode2string(DWORD opcode)
Definition: daemon_debug.c:280
void print_hexbuf(int level, unsigned char *title, unsigned char *buf, int len)
Definition: daemon_debug.c:98
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UINT op
Definition: effect.c:236
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SECTION_MAP_READ
Definition: compat.h:139
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
#define ERROR_INVALID_NAME
Definition: compat.h:103
static const WCHAR version[]
Definition: asmname.c:66
static ULONG lookup[16]
Definition: vga.c:38
USHORT NODE_TYPE_CODE
Definition: nodetype.h:22
CSHORT NODE_BYTE_SIZE
Definition: nodetype.h:37
#define NodeType(P)
Definition: nodetype.h:51
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define PtrToUlong(u)
Definition: config.h:107
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
BOOLEAN RtlTimeFieldsToTime(IN PTIME_FIELDS TimeFields, IN PLARGE_INTEGER Time)
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define DO_BUFFERED_IO
Definition: env_spec_w32.h:394
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
#define PagedPool
Definition: env_spec_w32.h:308
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN PVCB IN PDIRENT OUT PULONG EaLength
Definition: fatprocs.h:878
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
#define FCB_STATE_PAGING_FILE
Definition: fatstruc.h:1195
#define FCB_STATE_WRITECACHING_ENABLED
Definition: fcb.h:226
#define FCB_STATE_WRITEBUFFERING_ENABLED
Definition: fcb.h:225
#define FCB_STATE_DISABLE_LOCAL_BUFFERING
Definition: fcb.h:205
#define FCB_STATE_READCACHING_ENABLED
Definition: fcb.h:224
struct _V_NET_ROOT * PV_NET_ROOT
PMRX_FOBX NTAPI RxCreateNetFobx(_Out_ PRX_CONTEXT RxContext, _In_ PMRX_SRV_OPEN MrxSrvOpen)
#define GET_ALREADY_PREFIXED_NAME_FROM_CONTEXT(Rxcontext)
Definition: fcb.h:631
#define RxFormInitPacket(IP, I1, I1a, I2, I3, I4a, I4b, I5, I6, I7)
Definition: fcb.h:545
#define FCB_STATE_READBUFFERING_ENABLED
Definition: fcb.h:223
VOID NTAPI RxFinishFcbInitialization(_In_ OUT PMRX_FCB Fcb, _In_ RX_FILE_TYPE FileType, _In_opt_ PFCB_INIT_PACKET InitPacket)
struct _FileName FileName
Definition: fatprocs.h:896
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1801
struct _FILE_FULL_EA_INFORMATION * PFILE_FULL_EA_INFORMATION
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileLinkInformation
Definition: from_kernel.h:72
@ FileInternalInformation
Definition: from_kernel.h:67
@ FileAttributeTagInformation
Definition: from_kernel.h:96
@ FileDirectoryInformation
Definition: from_kernel.h:62
@ FileIdBothDirectoryInformation
Definition: from_kernel.h:98
@ FileEaInformation
Definition: from_kernel.h:68
@ FileNamesInformation
Definition: from_kernel.h:73
@ FileAllocationInformation
Definition: from_kernel.h:80
@ FileFullDirectoryInformation
Definition: from_kernel.h:63
@ FileNetworkOpenInformation
Definition: from_kernel.h:95
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
@ FileBothDirectoryInformation
Definition: from_kernel.h:64
@ FileIdFullDirectoryInformation
Definition: from_kernel.h:99
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_CREATE
Definition: from_kernel.h:55
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define FILE_SUPPORTS_EXTENDED_ATTRIBUTES
Definition: from_kernel.h:250
struct _FILE_LINK_INFORMATION * PFILE_LINK_INFORMATION
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
@ FileFsDeviceInformation
Definition: from_kernel.h:222
@ FileFsAttributeInformation
Definition: from_kernel.h:223
@ FileFsVolumeInformation
Definition: from_kernel.h:219
@ FileFsSizeInformation
Definition: from_kernel.h:221
struct _FILE_GET_EA_INFORMATION * PFILE_GET_EA_INFORMATION
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define FILE_OPEN_IF
Definition: from_kernel.h:56
struct _FILE_FS_ATTRIBUTE_INFORMATION * PFILE_FS_ATTRIBUTE_INFORMATION
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
enum _FSINFOCLASS FS_INFORMATION_CLASS
struct _FILE_FULL_EA_INFORMATION FILE_FULL_EA_INFORMATION
#define FILE_CREATE_TREE_CONNECTION
Definition: from_kernel.h:33
VOID pFxInterrupt ForceDisconnect()
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88
FxCollectionEntry * cur
ULONG Handle
Definition: gdb_input.c:15
GLint level
Definition: gl.h:1546
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLsizeiptr size
Definition: glext.h:5919
GLenum GLint GLuint mask
Definition: glext.h:6028
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
LARGE_INTEGER NTAPI KeQueryPerformanceCounter(IN PLARGE_INTEGER PerformanceFreq)
Definition: timer.c:138
struct dirent *__cdecl readdir(DIR *)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR)
struct _FILE_RENAME_INFORMATION * PFILE_RENAME_INFORMATION
struct _FILE_EA_INFORMATION * PFILE_EA_INFORMATION
NTSYSAPI NTSTATUS WINAPI RtlSetDaclSecurityDescriptor(PSECURITY_DESCRIPTOR, BOOLEAN, PACL, BOOLEAN)
NTSYSAPI void WINAPI RtlCopyLuid(PLUID, const LUID *)
#define InterlockedAdd64
Definition: interlocked.h:57
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define InterlockedCompareExchange
Definition: interlocked.h:104
const char * filename
Definition: ioapi.h:137
uint32_t entry
Definition: isohybrid.c:63
const char * op_str
Definition: compile.c:77
#define REPARSE_DATA_BUFFER_HEADER_SIZE
Definition: vista.c:17
NTSTATUS NTAPI RtlUnicodeToUTF8N(CHAR *utf8_dest, ULONG utf8_bytes_max, ULONG *utf8_bytes_written, const WCHAR *uni_src, ULONG uni_bytes)
Definition: utf8.c:20
if(dx< 0)
Definition: linetemp.h:194
NTSTATUS NTAPI RxLowIoCompletion(_In_ PRX_CONTEXT RxContext)
_SECURITY_IMPERSONATION_LEVEL
Definition: lsa.idl:54
@ SecurityImpersonation
Definition: lsa.idl:57
@ SecurityIdentification
Definition: lsa.idl:56
struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE
__u16 time
Definition: mkdosfs.c:8
#define error(str)
Definition: mkdosfs.c:1605
#define PCHAR
Definition: match.c:90
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1435
PVOID NTAPI MmMapLockedPagesSpecifyCache(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN ULONG Priority)
Definition: mdlsup.c:660
VOID NTAPI MmUnmapLockedPages(IN PVOID BaseAddress, IN PMDL Mdl)
Definition: mdlsup.c:837
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
#define ASSERT(a)
Definition: mode.c:44
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define SeDeleteClientSecurity(C)
Definition: imports.h:320
@ NormalPagePriority
Definition: imports.h:56
static PVOID ptr
Definition: dispmode.c:27
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
static PIO_STATUS_BLOCK void ULONG FS_INFORMATION_CLASS info_class
Definition: pipe.c:76
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
const char * dev_name(int device)
Definition: wave.c:211
#define min(a, b)
Definition: monoChain.cc:55
NTSTATUS NTAPI RxStartMinirdr(_In_ PRX_CONTEXT RxContext, _Out_ PBOOLEAN PostToFsp)
#define RDBSS_MANAGE_FOBX_EXTENSION
Definition: mrx.h:334
@ LOWIO_OP_FSCTL
Definition: mrx.h:240
@ LOWIO_OP_EXCLUSIVELOCK
Definition: mrx.h:237
@ LOWIO_OP_WRITE
Definition: mrx.h:235
@ LOWIO_OP_READ
Definition: mrx.h:234
@ LOWIO_OP_UNLOCK
Definition: mrx.h:238
@ LOWIO_OP_UNLOCK_MULTIPLE
Definition: mrx.h:239
@ LOWIO_OP_SHAREDLOCK
Definition: mrx.h:236
#define RX_REGISTERMINI_FLAG_DONT_PROVIDE_MAILSLOTS
Definition: mrx.h:10
#define RDBSS_MANAGE_FCB_EXTENSION
Definition: mrx.h:332
NTSTATUS NTAPI RxFsdDispatch(_In_ PRDBSS_DEVICE_OBJECT RxDeviceObject, _In_ PIRP Irp)
NTSTATUS NTAPI RxRegisterMinirdr(_Out_ PRDBSS_DEVICE_OBJECT *DeviceObject, _Inout_ PDRIVER_OBJECT DriverObject, _In_ PMINIRDR_DISPATCH MrdrDispatch, _In_ ULONG Controls, _In_ PUNICODE_STRING DeviceName, _In_ ULONG DeviceExtensionSize, _In_ DEVICE_TYPE DeviceType, _In_ ULONG DeviceCharacteristics)
#define RDBSS_MANAGE_V_NET_ROOT_EXTENSION
Definition: mrx.h:331
#define LOWIO_READWRITEFLAG_PAGING_IO
Definition: mrx.h:325
#define RDBSS_MANAGE_NET_ROOT_EXTENSION
Definition: mrx.h:330
NTSTATUS NTAPI RxStopMinirdr(_In_ PRX_CONTEXT RxContext, _Out_ PBOOLEAN PostToFsp)
struct _MRX_SRVCALLDOWN_STRUCTURE * PMRX_SRVCALLDOWN_STRUCTURE
#define NET_ROOT_WILD
Definition: mrxfcb.h:33
#define MRX_NET_ROOT_STATE_GOOD
Definition: mrxfcb.h:38
struct _MRX_SRV_OPEN_ * PMRX_SRV_OPEN
NTSTATUS NTAPI RxAcquireExclusiveFcbResourceInMRx(_Inout_ PMRX_FCB Fcb)
Definition: rxce.c:183
#define NET_ROOT_DISK
Definition: mrxfcb.h:30
struct _MRX_V_NET_ROOT_ * PMRX_V_NET_ROOT
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
struct _SECURITY_DESCRIPTOR * PSECURITY_DESCRIPTOR
Definition: security.c:98
#define __notnull
Definition: ms_sal.h:2614
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
#define SEC_COMMIT
Definition: mmtypes.h:100
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI NTSTATUS NTAPI RtlCreateSecurityDescriptor(_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ ULONG Revision)
NTSYSAPI NTSTATUS NTAPI RtlGetDaclSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PBOOLEAN DaclPresent, _Out_ PACL *Dacl, _Out_ PBOOLEAN DaclDefaulted)
void print_fo_all(int on, PRX_CONTEXT c)
Definition: nfs41_debug.c:312
unsigned char * print_file_information_class(int InfoClass)
Definition: nfs41_debug.c:498
VOID print_srv_call(int on, IN PMRX_SRV_CALL p)
Definition: nfs41_debug.c:240
void print_ioctl(int on, int op)
Definition: nfs41_debug.c:132
void print_driver_state(int state)
Definition: nfs41_debug.c:183
void print_get_ea(int on, PFILE_GET_EA_INFORMATION info)
Definition: nfs41_debug.c:233
void print_irps_flags(int on, PIO_STACK_LOCATION irps)
Definition: nfs41_debug.c:409
VOID print_net_root(int on, IN PMRX_NET_ROOT p)
Definition: nfs41_debug.c:258
VOID print_irp_flags(int on, PIRP irp)
Definition: nfs41_debug.c:387
VOID print_v_net_root(int on, IN PMRX_V_NET_ROOT p)
Definition: nfs41_debug.c:279
void print_fs_ioctl(int on, int op)
Definition: nfs41_debug.c:150
void print_open_error(int on, int status)
Definition: nfs41_debug.c:636
void print_acl_args(SECURITY_INFORMATION info)
Definition: nfs41_debug.c:626
ULONG __cdecl print_error(IN PCCH fmt,...)
Definition: nfs41_debug.c:75
void print_nt_create_params(int on, NT_CREATE_PARAMETERS params)
Definition: nfs41_debug.c:419
void print_file_object(int on, PFILE_OBJECT file)
Definition: nfs41_debug.c:302
void print_std_info(int on, PFILE_STANDARD_INFORMATION info)
Definition: nfs41_debug.c:212
unsigned char * print_fs_information_class(int InfoClass)
Definition: nfs41_debug.c:558
void print_ea_info(int on, PFILE_FULL_EA_INFORMATION info)
Definition: nfs41_debug.c:221
void print_basic_info(int on, PFILE_BASIC_INFORMATION info)
Definition: nfs41_debug.c:204
void print_wait_status(int on, const char *prefix, NTSTATUS status, const char *opcode, PVOID entry, LONGLONG xid)
Definition: nfs41_debug.c:688
void print_caching_level(int on, ULONG flag, PUNICODE_STRING name)
Definition: nfs41_debug.c:582
#define DbgEn()
Definition: nfs41_debug.h:57
#define DbgR()
Definition: nfs41_debug.h:68
#define DbgEx()
Definition: nfs41_debug.h:61
NTSTATUS marshal_nfs41_easet(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
NTSTATUS map_querydir_errors(DWORD status)
NTSTATUS marshal_nfs41_fileset(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
FAST_MUTEX xidLock
Definition: nfs41_driver.c:103
NTSTATUS nfs41_FinalizeSrvCall(PMRX_SRV_CALL pSrvCall, BOOLEAN Force)
VOID nfs41_ExtractNetRootName(IN PUNICODE_STRING FilePathName, IN PMRX_SRV_CALL SrvCall, OUT PUNICODE_STRING NetRootName, OUT PUNICODE_STRING RestOfName OPTIONAL)
NTSTATUS nfs41_DevFcbXXXControlFile(IN OUT PRX_CONTEXT RxContext)
#define DISABLE_CACHING
Definition: nfs41_driver.c:89
PRDBSS_DEVICE_OBJECT nfs41_dev
Definition: nfs41_driver.c:87
NTSTATUS nfs41_CollapseOpen(IN OUT PRX_CONTEXT RxContext)
DRIVER_UNLOAD nfs41_driver_unload
Definition: nfs41_driver.c:83
NTSTATUS marshal_nfs41_eaget(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
NTSTATUS nfs41_ShouldTryToCollapseThisOpen(IN OUT PRX_CONTEXT RxContext)
#define MIN_LOCK_POLL_WAIT
#define SECONDS(seconds)
Definition: nfs41_driver.c:117
#define nfs41_RemoveFirst(lock, list, pEntry)
Definition: nfs41_driver.c:292
NTSTATUS nfs41_SetEaInformation(IN OUT PRX_CONTEXT RxContext)
NTSTATUS nfs41_FinalizeNetRoot(IN OUT PMRX_NET_ROOT pNetRoot, IN PBOOLEAN ForceDisconnect)
struct _nfs3_attrs nfs3_attrs
#define ENABLE_READ_CACHING
Definition: nfs41_driver.c:90
const char * secflavorop2name(DWORD sec_flavor)
Definition: nfs41_driver.c:604
#define NFS41_MM_POOLTAG_UP
Definition: nfs41_driver.c:98
NTSTATUS map_readwrite_errors(DWORD status)
NTSTATUS nfs41_ComputeNewBufferingState(IN OUT PMRX_SRV_OPEN pSrvOpen, IN PVOID pMRxContext, OUT ULONG *pNewBufferingState)
void print_querydir_args(PRX_CONTEXT RxContext)
DWORD map_disposition_to_create_retval(DWORD disposition, DWORD errno)
FAST_MUTEX fcblistLock
Definition: nfs41_driver.c:102
ftype3
Definition: nfs41_driver.c:144
@ NF3LNK
Definition: nfs41_driver.c:149
@ NF3DIR
Definition: nfs41_driver.c:146
@ NF3FIFO
Definition: nfs41_driver.c:151
@ NF3SOCK
Definition: nfs41_driver.c:150
@ NF3REG
Definition: nfs41_driver.c:145
@ NF3CHR
Definition: nfs41_driver.c:148
@ NF3BLK
Definition: nfs41_driver.c:147
struct _NFS41_MOUNT_CONFIG NFS41_MOUNT_CONFIG
NTSTATUS nfs41_QueryFileInformation(IN OUT PRX_CONTEXT RxContext)
NTSTATUS map_close_errors(DWORD status)
NTSTATUS SharedMemoryInit(OUT PHANDLE phSection)
NTSTATUS nfs41_GetConnectionInfoFromBuffer(IN PVOID Buffer, IN ULONG BufferLen, OUT PUNICODE_STRING pConnectionName, OUT PVOID *ppEaBuffer, OUT PULONG pEaLength)
#define RELATIVE(wait)
Definition: nfs41_driver.c:113
NTSTATUS unmarshal_nfs41_getacl(nfs41_updowncall_entry *cur, unsigned char **buf)
NTSTATUS nfs41_GetLUID(PLUID id)
NTSTATUS check_nfs41_getreparse_args(PRX_CONTEXT RxContext)
NTSTATUS check_nfs41_dirquery_args(IN PRX_CONTEXT RxContext)
#define ENABLE_READWRITE_CACHING
Definition: nfs41_driver.c:92
#define NFS41_MM_POOLTAG_OPEN
Definition: nfs41_driver.c:97
void file_time_to_nfs_time(IN const PLARGE_INTEGER file_time, OUT LONGLONG *nfs_time)
struct _NFS41_FCB NFS41_FCB
#define NFS41GetVNetRootExtension(pVNetRoot)
Definition: nfs41_driver.c:395
NTSTATUS marshal_nfs41_getacl(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
#define MAX_SEC_FLAVOR_LEN
Definition: nfs41_driver.c:339
struct _NFS41_SERVER_ENTRY * PNFS41_SERVER_ENTRY
struct _NFS41_MOUNT_CONFIG * PNFS41_MOUNT_CONFIG
struct _NFS41_SERVER_ENTRY NFS41_SERVER_ENTRY
__inline ULONG unlock_list_count(PLOWIO_LOCK_LIST lock)
NTSTATUS nfs41_shutdown_daemon(DWORD version)
NTSTATUS nfs41_UpcallWaitForReply(IN nfs41_updowncall_entry *entry, IN DWORD secs)
enum _NULMRX_STORAGE_TYPE_CODES NFS41_STORAGE_TYPE_CODES
struct _NFS41_DEVICE_EXTENSION * PNFS41_DEVICE_EXTENSION
NTSTATUS unmarshal_nfs41_rw(nfs41_updowncall_entry *cur, unsigned char **buf)
nfs41_init_driver_state nfs41_init_state
Definition: nfs41_driver.c:481
#define nfs41_IsListEmpty(lock, list, flag)
Definition: nfs41_driver.c:302
NTSTATUS nfs41_QueryEaInformation(IN OUT PRX_CONTEXT RxContext)
static BOOLEAN is_root_directory(PRX_CONTEXT RxContext)
NTSTATUS marshal_nfs41_open(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
Definition: nfs41_driver.c:673
NTSTATUS map_lock_errors(DWORD status)
NTSTATUS nfs41_init_ops()
void unmarshal_nfs41_symlink(nfs41_updowncall_entry *cur, unsigned char **buf)
DRIVER_INITIALIZE DriverEntry
Definition: nfs41_driver.c:82
#define UPCALL_TIMEOUT_DEFAULT
Definition: nfs41_driver.c:340
INLINE ULONG length_as_utf8(PCUNICODE_STRING str)
Definition: nfs41_driver.c:510
struct _updowncall_list nfs41_updowncall_list
NTSTATUS nfs41_get_sec_ctx(IN enum _SECURITY_IMPERSONATION_LEVEL level, OUT PSECURITY_CLIENT_CONTEXT out_ctx)
NTSTATUS marshal_nfs41_mount(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
Definition: nfs41_driver.c:616
struct _NFS41_V_NET_ROOT_EXTENSION NFS41_V_NET_ROOT_EXTENSION
NTSTATUS nfs41_CloseSrvOpen(IN OUT PRX_CONTEXT RxContext)
NTSTATUS nfs41_SetFileInformation(IN OUT PRX_CONTEXT RxContext)
NTSTATUS nfs41_CompleteBufferingStateChangeRequest(IN OUT PRX_CONTEXT RxContext, IN OUT PMRX_SRV_OPEN SrvOpen, IN PVOID pContext)
NTSTATUS nfs41_Write(IN OUT PRX_CONTEXT RxContext)
void nfs41_create_volume_info(PFILE_FS_VOLUME_INFORMATION pVolInfo, DWORD *len)
NTSTATUS check_nfs41_setattr_args(IN PRX_CONTEXT RxContext)
void enable_caching(PMRX_SRV_OPEN SrvOpen, PNFS41_FOBX nfs41_fobx, ULONGLONG ChangeTime, HANDLE session)
#define MSEC_TO_RELATIVE_WAIT
void print_debug_header(PRX_CONTEXT RxContext)
Definition: nfs41_driver.c:486
NTSTATUS check_nfs41_write_args(IN PRX_CONTEXT RxContext)
LONG open_owner_id
Definition: nfs41_driver.c:107
NTSTATUS SharedMemoryFree(IN HANDLE hSection)
struct _NFS41_FOBX NFS41_FOBX
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
NTSTATUS marshal_nfs41_dirquery(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
Definition: nfs41_driver.c:933
NTSTATUS nfs41_unmount(HANDLE session, DWORD version, DWORD timeout)
NTSTATUS map_volume_errors(DWORD status)
FAST_MUTEX downcallLock
Definition: nfs41_driver.c:102
_nfs41_updowncall_state
Definition: nfs41_driver.c:154
@ NFS41_WAITING_FOR_DOWNCALL
Definition: nfs41_driver.c:156
@ NFS41_DONE_PROCESSING
Definition: nfs41_driver.c:157
@ NFS41_WAITING_FOR_UPCALL
Definition: nfs41_driver.c:155
@ NFS41_NOT_WAITING
Definition: nfs41_driver.c:158
NTSTATUS marshall_unicode_as_utf8(IN OUT unsigned char **pos, IN PCUNICODE_STRING str)
Definition: nfs41_driver.c:518
NTSTATUS unmarshal_nfs41_dirquery(nfs41_updowncall_entry *cur, unsigned char **buf)
#define NFS41_MM_POOLTAG_MOUNT
Definition: nfs41_driver.c:96
#define nfs41_RemoveEntry(lock, pEntry)
Definition: nfs41_driver.c:298
#define MOUNT_CONFIG_RW_SIZE_DEFAULT
Definition: nfs41_driver.c:337
#define RDR_STARTED
Definition: nfs41_driver.c:479
NTSTATUS nfs41_mount(PNFS41_MOUNT_CONFIG config, DWORD sec_flavor, PHANDLE session, DWORD *version, PFILE_FS_ATTRIBUTE_INFORMATION FsAttrs)
NTSTATUS nfs41_FsCtl(IN OUT PRX_CONTEXT RxContext)
NTSTATUS nfs41_FinalizeVNetRoot(IN OUT PMRX_V_NET_ROOT pVNetRoot, IN PBOOLEAN ForceDisconnect)
#define VOL_NAME
Definition: nfs41_driver.c:375
NTSTATUS nfs41_CreateSrvCall(PMRX_SRV_CALL pSrvCall, PMRX_SRVCALL_CALLBACK_CONTEXT pCallbackContext)
void print_readwrite_args(PRX_CONTEXT RxContext)
void print_nfs3_attrs(nfs3_attrs *attrs)
void unmarshal_nfs41_mount(nfs41_updowncall_entry *cur, unsigned char **buf)
void nfs41_invalidate_cache(IN PRX_CONTEXT RxContext)
NTSTATUS nfs41_Lock(IN OUT PRX_CONTEXT RxContext)
#define ENABLE_WRITE_CACHING
Definition: nfs41_driver.c:91
#define FS_NAME
Definition: nfs41_driver.c:370
NTSTATUS marshal_nfs41_setacl(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
struct _nfs41_fcb_list nfs41_fcb_list
#define RxDefineNode(node, type)
Definition: nfs41_driver.c:467
void unmarshal_nfs41_attrget(nfs41_updowncall_entry *cur, PVOID attr_value, ULONG *attr_len, unsigned char **buf)
NTSTATUS marshal_nfs41_header(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
Definition: nfs41_driver.c:562
NTSTATUS map_query_acl_error(DWORD error)
#define NFS41GetFobxExtension(pFobx)
Definition: nfs41_driver.c:425
NTSTATUS _nfs41_CreateSrvCall(PMRX_SRVCALL_CALLBACK_CONTEXT pCallbackContext)
NTSTATUS nfs41_AreFilesAliased(PFCB a, PFCB b)
NTSTATUS marshal_nfs41_filequery(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
ULONG nfs41_ExtendForCache(IN OUT PRX_CONTEXT RxContext, IN PLARGE_INTEGER pNewFileSize, OUT PLARGE_INTEGER pNewAllocationSize)
struct _NFS41_V_NET_ROOT_EXTENSION * PNFS41_V_NET_ROOT_EXTENSION
NTSTATUS nfs41_Flush(IN OUT PRX_CONTEXT RxContext)
NTSTATUS nfs41_SetFileInformationAtCleanup(IN OUT PRX_CONTEXT RxContext)
#define NFS41_MM_POOLTAG_ACL
Definition: nfs41_driver.c:95
#define nfs41_GetFirstMountEntry(lock, list, pEntry)
Definition: nfs41_driver.c:315
NTSTATUS check_nfs41_read_args(IN PRX_CONTEXT RxContext)
BOOLEAN isDataAccess(ACCESS_MASK mask)
NTSTATUS check_nfs41_setreparse_args(IN PRX_CONTEXT RxContext)
NTSTATUS nfs41_MountConfig_ParseOptions(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, IN OUT PNFS41_MOUNT_CONFIG Config)
NTSTATUS marshal_nfs41_lock(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
Definition: nfs41_driver.c:812
INLINE BOOL AnsiStrEq(IN const ANSI_STRING *lhs, IN const CHAR *rhs, IN const UCHAR rhs_len)
Definition: nfs41_driver.c:123
NTSTATUS check_nfs41_create_args(IN PRX_CONTEXT RxContext)
void create_nfs3_attrs(nfs3_attrs *attrs, PNFS41_FCB nfs41_fcb)
static NTSTATUS QueryCygwinSymlink(IN OUT PRX_CONTEXT RxContext, IN PFILE_GET_EA_INFORMATION query, OUT PFILE_FULL_EA_INFORMATION info)
NTSTATUS check_nfs41_setea_args(IN PRX_CONTEXT RxContext)
struct _nfs41_fcb_list_entry nfs41_fcb_list_entry
#define FS_ATTR_LEN
Definition: nfs41_driver.c:372
NTSTATUS nfs41_SetSecurityInformation(IN OUT PRX_CONTEXT RxContext)
NTSTATUS nfs41_DeallocateForFcb(IN OUT PMRX_FCB pFcb)
#define RDR_STARTING
Definition: nfs41_driver.c:478
NTSTATUS marshal_nfs41_unmount(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
Definition: nfs41_driver.c:664
#define MOUNT_CONFIG_RW_SIZE_MIN
Definition: nfs41_driver.c:336
NTSTATUS nfs41_QueryVolumeInformation(IN OUT PRX_CONTEXT RxContext)
NTSTATUS nfs41_UpcallCreate(IN DWORD opcode, IN PSECURITY_CLIENT_CONTEXT clnt_sec_ctx, IN HANDLE session, IN HANDLE open_state, IN DWORD version, IN PUNICODE_STRING filename, OUT nfs41_updowncall_entry **entry_out)
VOID nfs41_update_fcb_list(PMRX_FCB fcb, ULONGLONG ChangeTime)
#define NFS41GetNetRootExtension(pNetRoot)
Definition: nfs41_driver.c:365
BOOLEAN areOpenParamsValid(NT_CREATE_PARAMETERS *params)
BOOLEAN isFilenameTooLong(PUNICODE_STRING name, PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext)
#define RDR_STOPPED
Definition: nfs41_driver.c:476
struct _NFS41_NETROOT_EXTENSION NFS41_NETROOT_EXTENSION
enum _nfs41_updowncall_state nfs41_updowncall_state
#define DECLARE_CONST_ANSI_STRING(_var, _string)
Definition: nfs41_driver.c:109
BOOLEAN isOpen2Create(ULONG disposition)
NTSTATUS map_setea_error(DWORD error)
void unmarshal_nfs41_eaget(nfs41_updowncall_entry *cur, unsigned char **buf)
NTSTATUS marshal_nfs41_close(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
Definition: nfs41_driver.c:890
NTSTATUS check_nfs41_queryea_args(IN PRX_CONTEXT RxContext)
nfs41_updowncall_list downcall
Definition: nfs41_driver.c:273
NTSTATUS marshal_nfs41_symlink(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
DRIVER_DISPATCH(nfs41_FsdDispatch)
void denied_lock_backoff(IN OUT PLARGE_INTEGER delay)
#define VOL_ATTR_LEN
Definition: nfs41_driver.c:377
void print_queryvolume_args(PRX_CONTEXT RxContext)
NTSTATUS nfs41_IsValidDirectory(IN OUT PRX_CONTEXT RxContext, IN PUNICODE_STRING DirectoryName)
struct _NFS41_FOBX * PNFS41_FOBX
NTSTATUS nfs41_FsdDispatch(IN PDEVICE_OBJECT dev, IN PIRP Irp)
NTSTATUS handle_upcall(IN PRX_CONTEXT RxContext, IN nfs41_updowncall_entry *entry, OUT ULONG *len)
NTSTATUS nfs41_DeleteConnection(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
NTSTATUS nfs41_QueryDirectory(IN OUT PRX_CONTEXT RxContext)
NTSTATUS map_symlink_errors(NTSTATUS status)
NTSTATUS nfs41_Unlock(IN OUT PRX_CONTEXT RxContext)
NTSTATUS nfs41_Unimplemented(PRX_CONTEXT RxContext)
VOID unmarshal_nfs41_setattr(nfs41_updowncall_entry *cur, PULONGLONG dest_buf, unsigned char **buf)
NTSTATUS nfs41_Start(IN OUT PRX_CONTEXT RxContext, IN OUT PRDBSS_DEVICE_OBJECT dev)
_NULMRX_STORAGE_TYPE_CODES
Definition: nfs41_driver.c:464
@ NTC_NFS41_DEVICE_EXTENSION
Definition: nfs41_driver.c:465
struct _NFS41_FCB * PNFS41_FCB
#define nfs41_GetFirstEntry(lock, list, pEntry)
Definition: nfs41_driver.c:306
NTSTATUS map_mount_errors(DWORD status)
NTSTATUS nfs41_QuerySecurityInformation(IN OUT PRX_CONTEXT RxContext)
VOID nfs41_remove_fcb_entry(PMRX_FCB fcb)
NTSTATUS unmarshal_nfs41_open(nfs41_updowncall_entry *cur, unsigned char **buf)
NTSTATUS nfs41_CreateConnection(IN PRX_CONTEXT RxContext, OUT PBOOLEAN PostToFsp)
NTSTATUS nfs41_CreateVNetRoot(IN OUT PMRX_CREATENETROOT_CONTEXT pCreateNetRootContext)
NTSTATUS marshal_nfs41_shutdown(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
struct _NFS41_DEVICE_EXTENSION NFS41_DEVICE_EXTENSION
NTSTATUS nfs41_MountConfig_ParseBoolean(IN PFILE_FULL_EA_INFORMATION Option, IN PUNICODE_STRING usValue, OUT PBOOLEAN Value)
NTSTATUS nfs41_downcall(IN PRX_CONTEXT RxContext)
void nfs41_MountConfig_InitDefaults(OUT PNFS41_MOUNT_CONFIG Config)
NTSTATUS marshal_nfs41_unlock(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
Definition: nfs41_driver.c:849
KEVENT upcallEvent
Definition: nfs41_driver.c:101
static NTSTATUS QueryCygwinEA(IN OUT PRX_CONTEXT RxContext, IN PFILE_GET_EA_INFORMATION query, OUT PFILE_FULL_EA_INFORMATION info)
NTSTATUS marshal_nfs41_volume(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
void unmarshal_nfs41_header(nfs41_updowncall_entry *tmp, unsigned char **buf)
NTSTATUS nfs41_Stop(IN OUT PRX_CONTEXT RxContext, IN OUT PRDBSS_DEVICE_OBJECT dev)
NTSTATUS nfs41_SrvCallWinnerNotify(IN OUT PMRX_SRV_CALL pSrvCall, IN BOOLEAN ThisMinirdrIsTheWinner, IN OUT PVOID pSrvCallContext)
#define SERVER_NAME_BUFFER_SIZE
Definition: nfs41_driver.c:335
struct _MINIRDR_DISPATCH nfs41_ops
Definition: nfs41_driver.c:86
FAST_MUTEX openOwnerLock
Definition: nfs41_driver.c:104
struct _nfs41_mount_entry nfs41_mount_entry
NTSTATUS check_nfs41_setacl_args(PRX_CONTEXT RxContext)
NTSTATUS map_open_errors(DWORD status, USHORT len)
#define MOUNT_CONFIG_RW_SIZE_MAX
Definition: nfs41_driver.c:338
nfs41_start_driver_state nfs41_start_state
Definition: nfs41_driver.c:482
KSTART_ROUTINE fcbopen_main
NTSTATUS marshal_nfs41_rw(nfs41_updowncall_entry *entry, unsigned char *buf, ULONG buf_len, ULONG *len)
Definition: nfs41_driver.c:753
NTSTATUS GetConnectionHandle(IN PUNICODE_STRING ConnectionName, IN PVOID EaBuffer, IN ULONG EaLength, OUT PHANDLE Handle)
#define MAX_LOCK_POLL_WAIT
struct _NFS41_NETROOT_EXTENSION * PNFS41_NETROOT_EXTENSION
NTSTATUS nfs41_DeallocateForFobx(IN OUT PMRX_FOBX pFobx)
static BOOLEAN create_should_pass_ea(IN PFILE_FULL_EA_INFORMATION ea, IN ULONG disposition)
NTSTATUS nfs41_Create(IN OUT PRX_CONTEXT RxContext)
NTSTATUS nfs41_SetReparsePoint(IN OUT PRX_CONTEXT RxContext)
nfs41_fcb_list openlist
Definition: nfs41_driver.c:462
NTSTATUS nfs41_GetReparsePoint(IN OUT PRX_CONTEXT RxContext)
NTSTATUS nfs41_MountConfig_ParseDword(IN PFILE_FULL_EA_INFORMATION Option, IN PUNICODE_STRING usValue, OUT PDWORD Value, IN DWORD Minimum, IN DWORD Maximum)
NTSTATUS nfs41_IsLockRealizable(IN OUT PMRX_FCB pFcb, IN PLARGE_INTEGER ByteOffset, IN PLARGE_INTEGER Length, IN ULONG LowIoLockFlags)
LONGLONG xid
Definition: nfs41_driver.c:106
NTSTATUS map_queryfile_error(DWORD error)
FAST_MUTEX upcallLock
Definition: nfs41_driver.c:102
void unmarshal_nfs41_getattr(nfs41_updowncall_entry *cur, unsigned char **buf)
void print_unlock_args(PRX_CONTEXT RxContext)
#define RDR_NULL_STATE
Definition: nfs41_driver.c:471
struct _nfs41_mount_list nfs41_mount_list
NTSTATUS map_sec_flavor(IN PUNICODE_STRING sec_flavor_name, OUT PDWORD sec_flavor)
NTSTATUS has_nfs_prefix(IN PUNICODE_STRING SrvCallName, IN PUNICODE_STRING NetRootName)
#define NFS41GetDeviceExtension(RxContext, pExt)
Definition: nfs41_driver.c:446
void print_lock_args(PRX_CONTEXT RxContext)
LARGE_INTEGER unix_time_diff
Definition: nfs41_driver.c:142
#define NFS41GetFcbExtension(pFcb)
Definition: nfs41_driver.c:409
NTSTATUS map_setfile_error(DWORD error)
NTSTATUS nfs41_Read(IN OUT PRX_CONTEXT RxContext)
void print_debug_filedirquery_header(PRX_CONTEXT RxContext)
void print_reparse_buffer(PREPARSE_DATA_BUFFER Reparse)
NTSTATUS check_nfs41_getacl_args(PRX_CONTEXT RxContext)
#define nfs41_AddEntry(lock, list, pEntry)
Definition: nfs41_driver.c:288
#define NFS41_MM_POOLTAG
Definition: nfs41_driver.c:94
BOOLEAN isStream(PUNICODE_STRING name)
#define NFS41_MM_POOLTAG_DOWN
Definition: nfs41_driver.c:99
struct _updowncall_entry nfs41_updowncall_entry
#define IOCTL_NFS41_INVALCACHE
Definition: nfs41_driver.h:50
#define IOCTL_NFS41_WRITE
Definition: nfs41_driver.h:49
#define IOCTL_NFS41_READ
Definition: nfs41_driver.h:48
#define NFS41_DEVICE_NAME
Definition: nfs41_driver.h:25
#define IOCTL_NFS41_ADDCONN
Definition: nfs41_driver.h:46
#define NFS41_SHADOW_DEVICE_NAME
Definition: nfs41_driver.h:26
@ NFS41_READ
Definition: nfs41_driver.h:57
@ NFS41_CLOSE
Definition: nfs41_driver.h:56
@ NFS41_WRITE
Definition: nfs41_driver.h:58
@ NFS41_FILE_SET
Definition: nfs41_driver.h:63
@ NFS41_SYMLINK
Definition: nfs41_driver.h:66
@ NFS41_EA_GET
Definition: nfs41_driver.h:64
@ NFS41_EA_SET
Definition: nfs41_driver.h:65
@ NFS41_ACL_QUERY
Definition: nfs41_driver.h:68
@ NFS41_SHUTDOWN
Definition: nfs41_driver.h:70
@ NFS41_MOUNT
Definition: nfs41_driver.h:53
@ NFS41_UNMOUNT
Definition: nfs41_driver.h:54
@ NFS41_DIR_QUERY
Definition: nfs41_driver.h:61
@ NFS41_LOCK
Definition: nfs41_driver.h:59
@ NFS41_UNLOCK
Definition: nfs41_driver.h:60
@ NFS41_OPEN
Definition: nfs41_driver.h:55
@ NFS41_FILE_QUERY
Definition: nfs41_driver.h:62
@ NFS41_VOLUME_QUERY
Definition: nfs41_driver.h:67
@ NFS41_ACL_SET
Definition: nfs41_driver.h:69
#define IOCTL_NFS41_START
Definition: nfs41_driver.h:43
#define NFS41_SHARED_MEMORY_NAME
Definition: nfs41_driver.h:36
enum _nfs41_init_driver_state nfs41_init_driver_state
enum _nfs41_start_driver_state nfs41_start_driver_state
#define NFS41_SHADOW_PIPE_NAME
Definition: nfs41_driver.h:33
@ NFS41_START_DRIVER_STARTABLE
Definition: nfs41_driver.h:88
@ NFS41_START_DRIVER_START_IN_PROGRESS
Definition: nfs41_driver.h:89
@ NFS41_START_DRIVER_STARTED
Definition: nfs41_driver.h:90
@ NFS41_START_DRIVER_STOPPED
Definition: nfs41_driver.h:91
@ RPCSEC_AUTH_SYS
Definition: nfs41_driver.h:75
@ RPCSEC_AUTHGSS_KRB5P
Definition: nfs41_driver.h:78
@ RPCSEC_AUTHGSS_KRB5
Definition: nfs41_driver.h:76
@ RPCSEC_AUTHGSS_KRB5I
Definition: nfs41_driver.h:77
#define IOCTL_NFS41_GETSTATE
Definition: nfs41_driver.h:45
@ NFS41_INIT_DRIVER_STARTABLE
Definition: nfs41_driver.h:82
#define IOCTL_NFS41_DELCONN
Definition: nfs41_driver.h:47
#define IOCTL_NFS41_STOP
Definition: nfs41_driver.h:44
#define DbgP(_x_)
Definition: nfs41_np.c:36
struct __NFS41NP_SHARED_MEMORY NFS41NP_SHARED_MEMORY
sec_flavor
Definition: nfs41_ops.h:861
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_REMOTE_DEVICE
Definition: nt_native.h:811
#define SYNCHRONIZE
Definition: nt_native.h:61
#define SECTION_MAP_WRITE
Definition: nt_native.h:1288
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define PAGE_READWRITE
Definition: nt_native.h:1304
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FILE_CREATED
Definition: nt_native.h:770
#define FILE_READ_EA
Definition: nt_native.h:638
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
struct _FILE_FS_DEVICE_INFORMATION FILE_FS_DEVICE_INFORMATION
#define FILE_OVERWRITTEN
Definition: nt_native.h:771
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
struct _FILE_END_OF_FILE_INFORMATION * PFILE_END_OF_FILE_INFORMATION
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_SUPERSEDED
Definition: nt_native.h:768
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define FILE_DEVICE_IS_MOUNTED
Definition: nt_native.h:812
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define DELETE
Definition: nt_native.h:57
#define FILE_OPENED
Definition: nt_native.h:769
struct _FILE_DISPOSITION_INFORMATION * PFILE_DISPOSITION_INFORMATION
#define DWORD
Definition: nt_native.h:44
#define FILE_WRITE_EA
Definition: nt_native.h:640
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
WCHAR * PWCH
Definition: ntbasedef.h:410
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
@ SynchronizationEvent
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
#define IoCompleteRequest
Definition: irp.c:1240
PEPROCESS NTAPI IoGetCurrentProcess(VOID)
Definition: util.c:139
NTSTATUS NTAPI IoCheckEaBufferValidity(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: util.c:191
NTSTATUS NTAPI PsCreateSystemThread(OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE ProcessHandle, IN PCLIENT_ID ClientId, IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext)
Definition: thread.c:602
NTSTATUS NTAPI SeCreateClientSecurityFromSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext, _In_ PSECURITY_QUALITY_OF_SERVICE ClientSecurityQos, _In_ BOOLEAN ServerIsRemote, _Out_ PSECURITY_CLIENT_CONTEXT ClientContext)
Creates a client security context based upon the captured security subject context.
Definition: client.c:224
NTSTATUS NTAPI SeImpersonateClientEx(_In_ PSECURITY_CLIENT_CONTEXT ClientContext, _In_opt_ PETHREAD ServerThread)
Extended function that impersonates a client.
Definition: client.c:276
NTSTATUS NTAPI SeQueryAuthenticationIdToken(_In_ PACCESS_TOKEN Token, _Out_ PLUID LogonId)
Queries the authentication ID of an access token.
Definition: token.c:2036
#define RxAllocatePoolWithTag
Definition: ntrxdef.h:25
#define RxFreePool
Definition: ntrxdef.h:26
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INTERNAL_ERROR
Definition: ntstatus.h:465
#define STATUS_TIMEOUT
Definition: ntstatus.h:81
#define STATUS_NETWORK_NAME_DELETED
Definition: ntstatus.h:437
#define STATUS_NONEXISTENT_EA_ENTRY
Definition: ntstatus.h:317
#define STATUS_IO_REPARSE_TAG_INVALID
Definition: ntstatus.h:754
#define STATUS_NETWORK_UNREACHABLE
Definition: ntstatus.h:704
#define STATUS_ALERTED
Definition: ntstatus.h:80
#define STATUS_USER_APC
Definition: ntstatus.h:78
#define STATUS_IO_REPARSE_TAG_MISMATCH
Definition: ntstatus.h:755
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:320
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define STATUS_BAD_NETWORK_NAME
Definition: ntstatus.h:440
#define STATUS_EA_CORRUPT_ERROR
Definition: ntstatus.h:319
#define STATUS_INVALID_BUFFER_SIZE
Definition: ntstatus.h:650
#define STATUS_NETWORK_ACCESS_DENIED
Definition: ntstatus.h:438
#define STATUS_NO_EAS_ON_FILE
Definition: ntstatus.h:318
#define STATUS_REDIRECTOR_HAS_OPEN_HANDLES
Definition: ntstatus.h:214
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_INVALID_NETWORK_RESPONSE
Definition: ntstatus.h:431
#define STATUS_RANGE_NOT_LOCKED
Definition: ntstatus.h:362
#define STATUS_NOT_A_REPARSE_POINT
Definition: ntstatus.h:753
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_BAD_NETWORK_PATH
Definition: ntstatus.h:426
#define STATUS_FILE_INVALID
Definition: ntstatus.h:388
#define STATUS_IO_REPARSE_DATA_INVALID
Definition: ntstatus.h:756
#define STATUS_EAS_NOT_SUPPORTED
Definition: ntstatus.h:315
#define STATUS_REDIRECTOR_STARTED
Definition: ntstatus.h:488
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_CONNECTION_DISCONNECTED
Definition: ntstatus.h:656
#define STATUS_LOCK_NOT_GRANTED
Definition: ntstatus.h:321
#define STATUS_UNEXPECTED_NETWORK_ERROR
Definition: ntstatus.h:432
#define STATUS_EA_TOO_LARGE
Definition: ntstatus.h:316
#define STATUS_NET_WRITE_FAULT
Definition: ntstatus.h:446
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define STATUS_NO_MORE_EAS
Definition: ntstatus.h:198
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:448
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
BYTE * PBYTE
Definition: pedump.c:66
#define BOOLEAN
Definition: pedump.c:73
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
static PCWSTR TargetName
Definition: ping.c:67
#define RxIsPrefixTableLockAcquired(T)
Definition: prefix.h:113
#define RxAcquirePrefixTableLockExclusive(T, W)
Definition: prefix.h:83
#define RxReleasePrefixTableLock(T)
Definition: prefix.h:84
struct _FILE_STANDARD_INFORMATION * PFILE_STANDARD_INFORMATION
#define FileAccessInformation
Definition: propsheet.cpp:51
#define FileStandardInformation
Definition: propsheet.cpp:61
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:97
#define FSCTL_SET_REPARSE_POINT
Definition: winioctl.h:98
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:126
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
static unsigned __int64 next
Definition: rand_nt.c:6
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
struct _FILE_FS_VOLUME_INFORMATION FILE_FS_VOLUME_INFORMATION
NTSTATUS WINAPI RtlUTF8ToUnicodeN(PWSTR uni_dest, ULONG uni_bytes_max, PULONG uni_bytes_written, PCCH utf8_src, ULONG utf8_bytes)
Definition: reactos.cpp:21
static FILE * out
Definition: regtests2xml.c:44
#define INLINE
Definition: rosdhcp.h:56
const WCHAR * str
@ RX_CONTEXT_FLAG_IN_FSP
Definition: rxcontx.h:290
@ RX_CONTEXT_FLAG_WAIT
Definition: rxcontx.h:282
#define RxDereferenceAndDeleteRxContext(RXCONTEXT)
Definition: rxcontx.h:514
PRX_CONTEXT NTAPI RxCreateRxContext(_In_ PIRP Irp, _In_ PRDBSS_DEVICE_OBJECT RxDeviceObject, _In_ ULONG InitialContextFlags)
VOID NTAPI RxIndicateChangeOfBufferingStateForSrvOpen(PMRX_SRV_CALL SrvCall, PMRX_SRV_OPEN SrvOpen, PVOID SrvOpenKey, PVOID Context)
Definition: rdbss.c:6880
NTSTATUS NTAPI RxDriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
#define RxIsFcbAcquiredExclusive(Fcb)
Definition: rxprocs.h:229
NTSTATUS NTAPI RxFinalizeConnection(_Inout_ PNET_ROOT NetRoot, _Inout_opt_ PV_NET_ROOT VNetRoot, _In_ LOGICAL ForceFilesClosed)
#define RxIsFcbAcquiredShared(Fcb)
Definition: rxprocs.h:228
VOID NTAPI RxUnload(_In_ PDRIVER_OBJECT DriverObject)
NTSTATUS NTAPI RxChangeBufferingState(PSRV_OPEN SrvOpen, PVOID Context, BOOLEAN ComputeNewState)
Definition: rxce.c:783
NTSTATUS NTAPI RxPrepareToReparseSymbolicLink(PRX_CONTEXT RxContext, BOOLEAN SymbolicLinkEmbeddedInOldPath, PUNICODE_STRING NewPath, BOOLEAN NewPathIsAbsolute, PBOOLEAN ReparseRequired)
Definition: rdbss.c:7825
PEPROCESS NTAPI RxGetRDBSSProcess(VOID)
Definition: rxce.c:4497
FORCEINLINE VOID NTAPI RxUnregisterMinirdr(_In_ PRDBSS_DEVICE_OBJECT RxDeviceObject)
Definition: rxstruc.h:136
NTSTATUS NTAPI RxDispatchToWorkerThread(_In_ PRDBSS_DEVICE_OBJECT pMRxDeviceObject, _In_ WORK_QUEUE_TYPE WorkQueueType, _In_ PRX_WORKERTHREAD_ROUTINE Routine, _In_ PVOID pContext)
#define errno
Definition: errno.h:18
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define RDBSS_NTC_NETROOT
Definition: nodetype.h:49
#define RX_SCAVENGER_MASK
Definition: nodetype.h:70
#define RDBSS_NTC_SRVCALL
Definition: nodetype.h:48
#define RDBSS_NTC_MINIRDR_DISPATCH
Definition: nodetype.h:64
enum _RX_FILE_TYPE RX_FILE_TYPE
#define RDBSS_STORAGE_NTC(x)
Definition: nodetype.h:32
@ FileTypeDirectory
Definition: nodetype.h:37
@ FileTypeNotYetKnown
Definition: nodetype.h:36
@ FileTypeFile
Definition: nodetype.h:38
#define RDBSS_NTC_V_NETROOT
Definition: nodetype.h:50
#define RDBSS_NTC_SRVOPEN
Definition: nodetype.h:52
#define ZeroAndInitializeNodeType(Node, Type, Size)
Definition: nodetype.h:25
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define SYMLINK_FLAG_RELATIVE
Definition: shellext.h:193
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
struct _REPARSE_DATA_BUFFER * PREPARSE_DATA_BUFFER
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
base of all file and directory entries
Definition: entries.h:83
USHORT MaximumLength
Definition: env_spec_w32.h:377
Definition: cdstruc.h:902
CLONG OpenCount
Definition: fatstruc.h:881
ULONG FcbState
Definition: cdstruc.h:971
LARGE_INTEGER CreationTime
Definition: nt_native.h:939
LARGE_INTEGER ChangeTime
Definition: nt_native.h:942
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:940
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
XXCTL_LOWIO_COMPONENT IoCtl
Definition: mrx.h:309
XXCTL_LOWIO_COMPONENT FsCtl
Definition: mrx.h:308
union _LOWIO_CONTEXT::@2060 ParamsFor
struct _LOWIO_CONTEXT::@2060::@2062 Locks
struct _LOWIO_CONTEXT::@2060::@2061 ReadWrite
USHORT Operation
Definition: mrx.h:281
LONG HighPart
DWORD LowPart
ULONG Attributes
Definition: mrxfcb.h:121
PMRX_NET_ROOT pNetRoot
Definition: mrxfcb.h:111
UNICODE_STRING UnicodeQueryTemplate
Definition: mrxfcb.h:204
volatile ULONG NumberOfSrvOpens
Definition: mrxfcb.h:61
volatile ULONG NumberOfFcbs
Definition: mrxfcb.h:60
NET_ROOT_TYPE Type
Definition: mrxfcb.h:63
PMRX_SRV_CALL pSrvCall
Definition: mrxfcb.h:56
PMRX_SRV_CALL SrvCall
Definition: mrx.h:136
PMRX_SRVCALL_CALLBACK CallBack
Definition: mrx.h:137
PMRX_SRVCALLDOWN_STRUCTURE SrvCalldownStructure
Definition: mrx.h:119
PUNICODE_STRING pSrvCallName
Definition: mrxfcb.h:22
ACCESS_MASK DesiredAccess
Definition: mrxfcb.h:173
PMRX_V_NET_ROOT pVNetRoot
Definition: mrxfcb.h:162
PVOID Key
Definition: mrxfcb.h:172
PMRX_FCB pFcb
Definition: mrxfcb.h:161
PUNICODE_STRING pAlreadyPrefixedName
Definition: mrxfcb.h:169
Definition: fcb.h:34
NODE_BYTE_SIZE NodeByteSize
Definition: nfs41_driver.c:436
BYTE VolAttrs[VOL_ATTR_LEN]
Definition: nfs41_driver.c:441
PRDBSS_DEVICE_OBJECT DeviceObject
Definition: nfs41_driver.c:437
NODE_TYPE_CODE NodeTypeCode
Definition: nfs41_driver.c:435
NODE_BYTE_SIZE NodeByteSize
Definition: nfs41_driver.c:401
BOOLEAN Renamed
Definition: nfs41_driver.c:404
NODE_TYPE_CODE NodeTypeCode
Definition: nfs41_driver.c:400
FILE_BASIC_INFORMATION BasicInfo
Definition: nfs41_driver.c:402
BOOLEAN DeletePending
Definition: nfs41_driver.c:405
FILE_STANDARD_INFORMATION StandardInfo
Definition: nfs41_driver.c:403
ULONGLONG changeattr
Definition: nfs41_driver.c:407
DWORD deleg_type
Definition: nfs41_driver.c:421
BOOLEAN nocache
Definition: nfs41_driver.c:423
BOOLEAN write_thru
Definition: nfs41_driver.c:422
NODE_TYPE_CODE NodeTypeCode
Definition: nfs41_driver.c:413
HANDLE nfs41_open_state
Definition: nfs41_driver.c:416
NODE_BYTE_SIZE NodeByteSize
Definition: nfs41_driver.c:414
LARGE_INTEGER time
Definition: nfs41_driver.c:420
SECURITY_CLIENT_CONTEXT sec_ctx
Definition: nfs41_driver.c:417
WCHAR srv_buffer[SERVER_NAME_BUFFER_SIZE]
Definition: nfs41_driver.c:348
UNICODE_STRING MntPt
Definition: nfs41_driver.c:351
UNICODE_STRING SecFlavor
Definition: nfs41_driver.c:353
UNICODE_STRING SrvName
Definition: nfs41_driver.c:349
WCHAR mntpt_buffer[MAX_PATH]
Definition: nfs41_driver.c:350
nfs41_mount_list mounts
Definition: nfs41_driver.c:363
NODE_BYTE_SIZE NodeByteSize
Definition: nfs41_driver.c:359
NODE_TYPE_CODE NodeTypeCode
Definition: nfs41_driver.c:358
Definition: nfs41_driver.c:428
UNICODE_STRING Name
Definition: nfs41_driver.c:431
PMRX_SRV_CALL pRdbssSrvCall
Definition: nfs41_driver.c:429
WCHAR NameBuffer[SERVER_NAME_BUFFER_SIZE]
Definition: nfs41_driver.c:430
FILE_FS_ATTRIBUTE_INFORMATION FsAttrs
Definition: nfs41_driver.c:383
SECURITY_CLIENT_CONTEXT mount_sec_ctx
Definition: nfs41_driver.c:392
WCHAR PathBuffer[1]
Definition: shellext.h:176
struct _REPARSE_DATA_BUFFER::@318::@320 SymbolicLinkReparseBuffer
USHORT ReparseDataLength
Definition: shellext.h:166
ULONG_PTR InformationToReturn
Definition: rxcontx.h:137
PIRP CurrentIrp
Definition: rxcontx.h:110
BOOLEAN PostRequest
Definition: rxcontx.h:108
LOWIO_CONTEXT LowIoContext
Definition: rxcontx.h:263
struct _RX_CONTEXT::@2143::@2156 QueryDirectory
PMRX_FOBX pFobx
Definition: rxcontx.h:113
PIO_STACK_LOCATION CurrentIrpSp
Definition: rxcontx.h:111
PMRX_SRV_OPEN pRelevantSrvOpen
Definition: rxcontx.h:114
struct _RX_CONTEXT::@2141::@2149 Info
PMRX_FCB pFcb
Definition: rxcontx.h:112
Definition: prefix.h:45
UNICODE_STRING Prefix
Definition: prefix.h:53
PACCESS_TOKEN ClientToken
Definition: imports.h:291
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
Definition: fcb.h:261
USHORT MaximumLength
Definition: env_spec_w32.h:370
PNET_ROOT NetRoot
Definition: fcb.h:65
RX_PREFIX_ENTRY PrefixEntry
Definition: fcb.h:72
ULONG OutputBufferLength
Definition: mrx.h:274
ULONG InputBufferLength
Definition: mrx.h:272
PVOID pInputBuffer
Definition: mrx.h:273
PVOID pOutputBuffer
Definition: mrx.h:275
ULONG FsControlCode
Definition: mrx.h:269
LONGLONG mtime
Definition: nfs41_driver.c:140
LARGE_INTEGER size
Definition: nfs41_driver.c:134
LARGE_INTEGER used
Definition: nfs41_driver.c:134
LONGLONG fileid
Definition: nfs41_driver.c:139
LONGLONG fsid
Definition: nfs41_driver.c:139
DWORD specdata1
Definition: nfs41_driver.c:136
LONGLONG atime
Definition: nfs41_driver.c:140
LONGLONG ctime
Definition: nfs41_driver.c:140
DWORD specdata2
Definition: nfs41_driver.c:137
struct _nfs3_attrs::@741 rdev
Definition: nfs41_driver.c:450
BOOLEAN skip
Definition: nfs41_driver.c:456
ULONGLONG ChangeTime
Definition: nfs41_driver.c:455
LIST_ENTRY next
Definition: nfs41_driver.c:451
PNFS41_FOBX nfs41_fobx
Definition: nfs41_driver.c:454
HANDLE session
Definition: nfs41_driver.c:453
PMRX_FCB fcb
Definition: nfs41_driver.c:452
LIST_ENTRY head
Definition: nfs41_driver.c:460
Definition: nfs41_driver.c:275
HANDLE gssp_session
Definition: nfs41_driver.c:281
LUID login_id
Definition: nfs41_driver.c:277
HANDLE authsys_session
Definition: nfs41_driver.c:278
HANDLE gssi_session
Definition: nfs41_driver.c:280
HANDLE gss_session
Definition: nfs41_driver.c:279
LIST_ENTRY next
Definition: nfs41_driver.c:276
Definition: nfs41_driver.c:166
LONGLONG offset
Definition: nfs41_driver.c:201
BOOLEAN renamed
Definition: nfs41_driver.c:231
struct _updowncall_entry::@742::@748 Close
FILE_STANDARD_INFORMATION sinfo
Definition: nfs41_driver.c:212
ULONG attrs
Definition: nfs41_driver.c:216
UNICODE_STRING symlink
Definition: nfs41_driver.c:213
PSECURITY_CLIENT_CONTEXT psec_ctx
Definition: nfs41_driver.c:178
PUNICODE_STRING root
Definition: nfs41_driver.c:188
struct _updowncall_entry::@742::@747 Open
ULONG buf_len
Definition: nfs41_driver.c:183
BOOLEAN remove
Definition: nfs41_driver.c:230
union _updowncall_entry::@742 u
KEVENT cond
Definition: nfs41_driver.c:174
BOOLEAN ReturnSingleEntry
Definition: nfs41_driver.c:253
struct _updowncall_entry::@742::@752 QueryEa
struct _updowncall_entry::@742::@743 Mount
NTSTATUS status
Definition: nfs41_driver.c:170
LIST_ENTRY next
Definition: nfs41_driver.c:173
HANDLE open_state
Definition: nfs41_driver.c:179
PUNICODE_STRING srv_name
Definition: nfs41_driver.c:187
DWORD version
Definition: nfs41_driver.c:167
ULONG cattrs
Definition: nfs41_driver.c:219
HANDLE srv_open
Definition: nfs41_driver.c:222
LONGLONG xid
Definition: nfs41_driver.c:168
PMDL mdl
Definition: nfs41_driver.c:239
BOOLEAN blocking
Definition: nfs41_driver.c:204
struct _updowncall_entry::@742::@755 Acl
BOOLEAN return_single
Definition: nfs41_driver.c:237
PUNICODE_STRING target
Definition: nfs41_driver.c:257
PUNICODE_STRING filter
Definition: nfs41_driver.c:234
PFILE_FS_ATTRIBUTE_INFORMATION FsAttrs
Definition: nfs41_driver.c:189
struct _updowncall_entry::@742::@744 ReadWrite
BOOLEAN initial_query
Definition: nfs41_driver.c:238
FS_INFORMATION_CLASS query
Definition: nfs41_driver.c:261
PMDL EaMdl
Definition: nfs41_driver.c:225
DWORD errno
Definition: nfs41_driver.c:175
SECURITY_INFORMATION query
Definition: nfs41_driver.c:264
BOOLEAN restart_scan
Definition: nfs41_driver.c:236
PVOID buf
Definition: nfs41_driver.c:182
struct _updowncall_entry::@742::@750 SetFile
struct _updowncall_entry::@742::@751 SetEa
LONG open_owner_id
Definition: nfs41_driver.c:220
LONGLONG length
Definition: nfs41_driver.c:202
struct _updowncall_entry::@742::@749 QueryFile
ULONG copts
Definition: nfs41_driver.c:217
SECURITY_CLIENT_CONTEXT sec_ctx
Definition: nfs41_driver.c:177
nfs41_updowncall_state state
Definition: nfs41_driver.c:171
FILE_BASIC_INFORMATION binfo
Definition: nfs41_driver.c:211
ULONG disp
Definition: nfs41_driver.c:218
ULONGLONG ChangeTime
Definition: nfs41_driver.c:184
BOOLEAN exclusive
Definition: nfs41_driver.c:203
BOOLEAN RestartScan
Definition: nfs41_driver.c:254
BOOLEAN symlink_embedded
Definition: nfs41_driver.c:224
struct _updowncall_entry::@742::@753 Symlink
FILE_INFORMATION_CLASS InfoClass
Definition: nfs41_driver.c:235
PMDL MdlAddress
Definition: nfs41_driver.c:196
BOOLEAN set
Definition: nfs41_driver.c:258
ULONG EaListLength
Definition: nfs41_driver.c:250
DWORD deleg_type
Definition: nfs41_driver.c:223
ULONG EaIndex
Definition: nfs41_driver.c:252
PVOID EaBuffer
Definition: nfs41_driver.c:226
PUNICODE_STRING filename
Definition: nfs41_driver.c:181
DWORD wsize
Definition: nfs41_driver.c:192
ULONG access_mode
Definition: nfs41_driver.c:215
FAST_MUTEX lock
Definition: nfs41_driver.c:172
ULONG access_mask
Definition: nfs41_driver.c:214
ULONG count
Definition: nfs41_driver.c:207
ULONG Overflow
Definition: nfs41_driver.c:251
DWORD opcode
Definition: nfs41_driver.c:169
DWORD sec_flavor
Definition: nfs41_driver.c:190
LOWIO_LOCK_LIST locks
Definition: nfs41_driver.c:208
PVOID mdl_buf
Definition: nfs41_driver.c:240
ULONGLONG offset
Definition: nfs41_driver.c:197
DWORD rsize
Definition: nfs41_driver.c:191
PVOID EaList
Definition: nfs41_driver.c:249
PRX_CONTEXT rxcontext
Definition: nfs41_driver.c:198
DWORD mode
Definition: nfs41_driver.c:221
struct _updowncall_entry::@742::@754 Volume
BOOLEAN async_op
Definition: nfs41_driver.c:176
HANDLE session
Definition: nfs41_driver.c:180
DWORD lease_time
Definition: nfs41_driver.c:193
struct _updowncall_entry::@742::@746 Unlock
struct _updowncall_entry::@742::@745 Lock
LIST_ENTRY head
Definition: nfs41_driver.c:271
Definition: inflate.c:139
Definition: name.c:39
Definition: ps.c:97
Definition: dhcpd.h:245
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: subject.c:171
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: subject.c:85
rwlock_t lock
Definition: tcpcore.h:0
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * PBOOLEAN
Definition: typedefs.h:53
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
PVOID HANDLE
Definition: typedefs.h:73
uint16_t * PUSHORT
Definition: typedefs.h:56
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define STATUS_FILE_IS_A_DIRECTORY
Definition: udferr_usr.h:164
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_TOO_MANY_LINKS
Definition: udferr_usr.h:184
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_NO_MORE_FILES
Definition: udferr_usr.h:128
LONGLONG QuadPart
Definition: typedefs.h:114
struct __nfs41_upcall nfs41_upcall
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_CHILD_LIST_CONFIG Config
Definition: wdfchildlist.h:476
#define DECLARE_CONST_UNICODE_STRING(_variablename, _string)
Definition: wdfcore.h:161
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define ERROR_BAD_NETPATH
Definition: winerror.h:145
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
#define ERROR_NET_WRITE_FAULT
Definition: winerror.h:172
#define ERROR_REPARSE
Definition: winerror.h:522
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135
#define ERROR_INVALID_EA_HANDLE
Definition: winerror.h:299
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_DIRECTORY
Definition: winerror.h:295
#define ERROR_EA_FILE_CORRUPT
Definition: winerror.h:297
#define ERROR_NETWORK_UNREACHABLE
Definition: winerror.h:734
#define ERROR_NOT_EMPTY
Definition: winerror.h:1251
#define ERROR_NOT_LOCKED
Definition: winerror.h:230
#define ERROR_HANDLE_EOF
Definition: winerror.h:140
#define ERROR_TOO_MANY_LINKS
Definition: winerror.h:671
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define ERROR_FILE_TOO_LARGE
Definition: winerror.h:278
#define ERROR_LOCK_VIOLATION
Definition: winerror.h:136
#define ERROR_BAD_NET_RESP
Definition: winerror.h:150
#define ERROR_NO_MORE_FILES
Definition: winerror.h:121
#define ERROR_BAD_FILE_TYPE
Definition: winerror.h:277
#define ERROR_NOT_SAME_DEVICE
Definition: winerror.h:120
#define ERROR_FILE_INVALID
Definition: winerror.h:585
#define ERROR_VC_DISCONNECTED
Definition: winerror.h:287
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263
#define ERROR_LOCK_FAILED
Definition: winerror.h:236
#define ERROR_INTERNAL_ERROR
Definition: winerror.h:840
#define ERROR_ATOMIC_LOCKS_NOT_SUPPORTED
Definition: winerror.h:240
#define ERROR_NOT_A_REPARSE_POINT
Definition: winerror.h:1288
#define ERROR_NETWORK_ACCESS_DENIED
Definition: winerror.h:157
#define ERROR_INVALID_REPARSE_DATA
Definition: winerror.h:1290
#define ERROR_BAD_NET_NAME
Definition: winerror.h:159
#define ERROR_NETNAME_DELETED
Definition: winerror.h:156
_In_ const BITMAPINFO _In_ UINT _In_opt_ HANDLE hSection
Definition: wingdi.h:3239
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
FAST_MUTEX
Definition: extypes.h:17
@ DelayedWorkQueue
Definition: extypes.h:190
_In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG _In_ ULONG _In_ ULONG _In_ ULONG _In_opt_ PVOID EaBuffer
Definition: iofuncs.h:845
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MJ_FILE_SYSTEM_CONTROL
DRIVER_DISPATCH * PDRIVER_DISPATCH
Definition: iotypes.h:2262
* PFILE_OBJECT
Definition: iotypes.h:1998
#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE
Definition: iotypes.h:7213
#define IsReparseTagValid(tag)
Definition: iotypes.h:7225
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7240
#define SL_FAIL_IMMEDIATELY
Definition: iotypes.h:1832
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define SL_EXCLUSIVE_LOCK
Definition: iotypes.h:1833
#define IRP_MJ_MAXIMUM_FUNCTION
@ Executive
Definition: ketypes.h:415
@ IoModifyAccess
Definition: ketypes.h:865
@ MmCached
Definition: mmtypes.h:130
@ MmNonCached
Definition: mmtypes.h:129
#define MDL_MAPPING_CAN_FAIL
Definition: mmtypes.h:31
#define ObDereferenceObject
Definition: obfuncs.h:203
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
#define SeStopImpersonatingClient()
Definition: sefuncs.h:581
#define LABEL_SECURITY_INFORMATION
Definition: setypes.h:127
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define SECURITY_STATIC_TRACKING
Definition: setypes.h:104
#define SECURITY_DESCRIPTOR_REVISION
Definition: setypes.h:58
#define SACL_SECURITY_INFORMATION
Definition: setypes.h:126
#define SECURITY_DYNAMIC_TRACKING
Definition: setypes.h:103
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193