ReactOS 0.4.16-dev-1264-g92ff994
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{
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);
545 status = RtlUnicodeToUTF8N(ansi.Buffer, ansi.MaximumLength,
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 }
4582#ifndef __REACTOS__
4583 // FileAccessInformation isn't the correct enum type!
4584 // It has the value 8, which is FileFsObjectIdInformation
4587 goto out;
4588#endif
4590 if (RxContext->Info.LengthRemaining < FS_ATTR_LEN) {
4591 RxContext->InformationToReturn = FS_ATTR_LEN;
4593 goto out;
4594 }
4595
4596 /* on attribute queries for the root directory,
4597 * use cached volume attributes from mount */
4598 if (is_root_directory(RxContext)) {
4600 (PFILE_FS_ATTRIBUTE_INFORMATION)RxContext->Info.Buffer;
4602
4603 RtlCopyMemory(attrs, &pVNetRootContext->FsAttrs,
4604 sizeof(pVNetRootContext->FsAttrs));
4605
4606 /* fill in the FileSystemName */
4607 RtlCopyMemory(attrs->FileSystemName, FsName.Buffer,
4608 FsName.MaximumLength); /* 'MaximumLength' to include null */
4609 attrs->FileSystemNameLength = FsName.Length;
4610
4611 RxContext->Info.LengthRemaining -= FS_ATTR_LEN;
4612 goto out;
4613 }
4614 /* else fall through and send the upcall */
4617 break;
4618
4619 default:
4620 print_error("nfs41_QueryVolumeInformation: unhandled class %d\n", InfoClass);
4622 goto out;
4623 }
4624 status = nfs41_UpcallCreate(NFS41_VOLUME_QUERY, &nfs41_fobx->sec_ctx,
4625 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
4626 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
4627 if (status) goto out;
4628
4629 entry->u.Volume.query = InfoClass;
4630 entry->buf = RxContext->Info.Buffer;
4631 entry->buf_len = RxContext->Info.LengthRemaining;
4632
4633 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
4634 if (status) goto out;
4635
4636 if (entry->status == STATUS_BUFFER_TOO_SMALL) {
4637 RxContext->InformationToReturn = entry->buf_len;
4639 } else if (entry->status == STATUS_SUCCESS) {
4640 if (InfoClass == FileFsAttributeInformation) {
4641 /* fill in the FileSystemName */
4643 (PFILE_FS_ATTRIBUTE_INFORMATION)RxContext->Info.Buffer;
4645
4646 RtlCopyMemory(attrs->FileSystemName, FsName.Buffer,
4647 FsName.MaximumLength); /* 'MaximumLength' to include null */
4648 attrs->FileSystemNameLength = FsName.Length;
4649
4650 entry->buf_len = FS_ATTR_LEN;
4651 }
4652#ifdef ENABLE_TIMINGS
4654 InterlockedAdd64(&volume.size, entry->u.Volume.buf_len);
4655#endif
4656 RxContext->Info.LengthRemaining -= entry->buf_len;
4658 } else {
4659 status = map_volume_errors(entry->status);
4660 }
4662out:
4663#ifdef ENABLE_TIMINGS
4666 InterlockedAdd64(&volume.ticks, t2.QuadPart - t1.QuadPart);
4667#ifdef ENABLE_INDV_TIMINGS
4668 DbgP("nfs41_QueryVolumeInformation delta = %d op=%d sum=%d\n",
4669 t2.QuadPart - t1.QuadPart, volume.tops, volume.ticks);
4670#endif
4671#endif
4672#ifdef DEBUG_VOLUME_QUERY
4673 DbgEx();
4674#endif
4675 return status;
4676}
4677
4679 PMRX_FCB fcb,
4680 ULONGLONG ChangeTime)
4681{
4686 while (!IsListEmpty(&openlist.head)) {
4689 if (cur->fcb == fcb &&
4690 cur->ChangeTime != ChangeTime) {
4691#if defined(DEBUG_FILE_SET) || defined(DEBUG_ACL_SET) || \
4692 defined(DEBUG_WRITE) || defined(DEBUG_EA_SET)
4693 DbgP("nfs41_update_fcb_list: Found match for fcb %p: updating "
4694 "%llu to %llu\n", fcb, cur->ChangeTime, ChangeTime);
4695#endif
4696 cur->ChangeTime = ChangeTime;
4697 break;
4698 }
4699 /* place an upcall for this srv_open */
4700 if (pEntry->Flink == &openlist.head) {
4701#if defined(DEBUG_FILE_SET) || defined(DEBUG_ACL_SET) || \
4702 defined(DEBUG_WRITE) || defined(DEBUG_EA_SET)
4703 DbgP("nfs41_update_fcb_list: reached EOL loooking for "
4704 "fcb=%p\n", fcb);
4705#endif
4706 break;
4707 }
4708 pEntry = pEntry->Flink;
4709 }
4711}
4712
4714 nfs3_attrs *attrs)
4715{
4716 DbgP("type=%d mode=%o nlink=%d size=%d atime=%x mtime=%x ctime=%x\n",
4717 attrs->type, attrs->mode, attrs->nlink, attrs->size, attrs->atime,
4718 attrs->mtime, attrs->ctime);
4719}
4720
4722 IN const PLARGE_INTEGER file_time,
4723 OUT LONGLONG *nfs_time)
4724{
4726 diff.QuadPart = file_time->QuadPart - diff.QuadPart;
4727 *nfs_time = diff.QuadPart / 10000000;
4728}
4729
4731 nfs3_attrs *attrs,
4732 PNFS41_FCB nfs41_fcb)
4733{
4734 RtlZeroMemory(attrs, sizeof(nfs3_attrs));
4736 attrs->type = NF3LNK;
4737 else if (nfs41_fcb->StandardInfo.Directory)
4738 attrs->type = NF3DIR;
4739 else
4740 attrs->type = NF3REG;
4741 attrs->mode = nfs41_fcb->mode;
4742 attrs->nlink = nfs41_fcb->StandardInfo.NumberOfLinks;
4743 attrs->size.QuadPart = attrs->used.QuadPart =
4744 nfs41_fcb->StandardInfo.EndOfFile.QuadPart;
4746 file_time_to_nfs_time(&nfs41_fcb->BasicInfo.ChangeTime, &attrs->mtime);
4747 file_time_to_nfs_time(&nfs41_fcb->BasicInfo.CreationTime, &attrs->ctime);
4748}
4749
4750
4752 DWORD error)
4753{
4754 switch (error) {
4755 case NO_ERROR: return STATUS_SUCCESS;
4767 default:
4768 print_error("failed to map windows error %d to NTSTATUS; "
4769 "defaulting to STATUS_INVALID_PARAMETER\n", error);
4771 }
4772}
4773
4775 IN PRX_CONTEXT RxContext)
4776{
4778 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
4779 NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
4781 &pVNetRootContext->FsAttrs;
4783 (PFILE_FULL_EA_INFORMATION)RxContext->Info.Buffer;
4784
4785 status = check_nfs41_dirquery_args(RxContext);
4786 if (status) goto out;
4787
4788 if (ea == NULL) {
4790 goto out;
4791 }
4792 if (AnsiStrEq(&NfsActOnLink, ea->EaName, ea->EaNameLength) ||
4793 AnsiStrEq(&NfsSymlinkTargetName, ea->EaName, ea->EaNameLength)) {
4794 status = STATUS_INVALID_PARAMETER; /* only allowed on create */
4795 goto out;
4796 }
4797 /* ignore cygwin EAs when checking support */
4798 if (!(FsAttrs->FileSystemAttributes & FILE_SUPPORTS_EXTENDED_ATTRIBUTES)
4799 && !AnsiStrEq(&NfsV3Attributes, ea->EaName, ea->EaNameLength)) {
4801 goto out;
4802 }
4803 if ((RxContext->pRelevantSrvOpen->DesiredAccess & FILE_WRITE_EA) == 0) {
4805 goto out;
4806 }
4807 if (pVNetRootContext->read_only) {
4808 print_error("check_nfs41_setattr_args: Read-only mount\n");
4810 goto out;
4811 }
4812out:
4813 return status;
4814}
4815
4816#ifdef __REACTOS__
4818#else
4820#endif
4821 IN OUT PRX_CONTEXT RxContext)
4822{
4826 (PFILE_FULL_EA_INFORMATION)RxContext->Info.Buffer;
4827 nfs3_attrs *attrs = NULL;
4828 ULONG buflen = RxContext->CurrentIrpSp->Parameters.SetEa.Length, error_offset;
4829 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
4830 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
4831 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
4832 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
4833 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
4834 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
4835 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
4836#ifdef ENABLE_TIMINGS
4837 LARGE_INTEGER t1, t2;
4839#endif
4840
4841#ifdef DEBUG_EA_SET
4842 DbgEn();
4843 print_debug_header(RxContext);
4844 print_ea_info(1, eainfo);
4845#endif
4846
4847 status = check_nfs41_setea_args(RxContext);
4848 if (status) goto out;
4849
4850 status = nfs41_UpcallCreate(NFS41_EA_SET, &nfs41_fobx->sec_ctx,
4851 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
4852 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
4853 if (status) goto out;
4854
4855 if (AnsiStrEq(&NfsV3Attributes, eainfo->EaName, eainfo->EaNameLength)) {
4856 attrs = (nfs3_attrs *)(eainfo->EaName + eainfo->EaNameLength + 1);
4857#ifdef DEBUG_EA_SET
4858 print_nfs3_attrs(attrs);
4859 DbgP("old mode is %o new mode is %o\n", nfs41_fcb->mode, attrs->mode);
4860#endif
4861 entry->u.SetEa.mode = attrs->mode;
4862 } else {
4863 entry->u.SetEa.mode = 0;
4864 status = IoCheckEaBufferValidity(eainfo, buflen, &error_offset);
4865 if (status) {
4867 goto out;
4868 }
4869 }
4870 entry->buf = eainfo;
4871 entry->buf_len = buflen;
4872
4873 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
4874 if (status) goto out;
4875#ifdef ENABLE_TIMINGS
4876 if (entry->status == STATUS_SUCCESS) {
4877 InterlockedIncrement(&setexattr.sops);
4878 InterlockedAdd64(&setexattr.size, entry->u.SetEa.buf_len);
4879 }
4880#endif
4881 status = map_setea_error(entry->status);
4882 if (!status) {
4883 if (!nfs41_fobx->deleg_type && entry->ChangeTime &&
4884 (SrvOpen->DesiredAccess &
4886 nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
4887 nfs41_fcb->changeattr = entry->ChangeTime;
4888 nfs41_fcb->mode = entry->u.SetEa.mode;
4889 }
4891out:
4892#ifdef ENABLE_TIMINGS
4894 InterlockedIncrement(&setexattr.tops);
4895 InterlockedAdd64(&setexattr.ticks, t2.QuadPart - t1.QuadPart);
4896#ifdef ENABLE_INDV_TIMINGS
4897 DbgP("nfs41_SetEaInformation delta = %d op=%d sum=%d\n",
4898 t2.QuadPart - t1.QuadPart, setexattr.tops, setexattr.ticks);
4899#endif
4900#endif
4901#ifdef DEBUG_EA_SET
4902 DbgEx();
4903#endif
4904 return status;
4905}
4906
4908 IN PRX_CONTEXT RxContext)
4909{
4911 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
4912 NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
4914 &pVNetRootContext->FsAttrs;
4916 RxContext->CurrentIrpSp->Parameters.QueryEa.EaList;
4917
4918 status = check_nfs41_dirquery_args(RxContext);
4919 if (status) goto out;
4920
4921 if (!(FsAttrs->FileSystemAttributes & FILE_SUPPORTS_EXTENDED_ATTRIBUTES)) {
4922 if (ea == NULL) {
4924 goto out;
4925 }
4926 /* ignore cygwin EAs when checking support */
4927 if (!AnsiStrEq(&NfsV3Attributes, ea->EaName, ea->EaNameLength) &&
4928 !AnsiStrEq(&NfsActOnLink, ea->EaName, ea->EaNameLength) &&
4929 !AnsiStrEq(&NfsSymlinkTargetName, ea->EaName, ea->EaNameLength)) {
4931 goto out;
4932 }
4933 }
4934 if ((RxContext->pRelevantSrvOpen->DesiredAccess & FILE_READ_EA) == 0) {
4936 goto out;
4937 }
4938out:
4939 return status;
4940}
4941
4943 IN OUT PRX_CONTEXT RxContext,
4946{
4947 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
4948 __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
4949 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
4950 __notnull PNFS41_NETROOT_EXTENSION NetRootContext =
4951 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
4952 __notnull PNFS41_FOBX Fobx = NFS41GetFobxExtension(RxContext->pFobx);
4955 const USHORT HeaderLen = FIELD_OFFSET(FILE_FULL_EA_INFORMATION, EaName) +
4956 query->EaNameLength + 1;
4958
4959 if (RxContext->Info.LengthRemaining < HeaderLen) {
4961 RxContext->InformationToReturn = HeaderLen;
4962 goto out;
4963 }
4964
4965 TargetName.Buffer = (PWCH)(info->EaName + query->EaNameLength + 1);
4966 TargetName.MaximumLength = (USHORT)min(RxContext->Info.LengthRemaining -
4967 HeaderLen, 0xFFFF);
4968
4969 status = nfs41_UpcallCreate(NFS41_SYMLINK, &Fobx->sec_ctx,
4970 VNetRootContext->session, Fobx->nfs41_open_state,
4971 NetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
4972 if (status) goto out;
4973
4974 entry->u.Symlink.target = &TargetName;
4975 entry->u.Symlink.set = FALSE;
4976
4977 status = nfs41_UpcallWaitForReply(entry, VNetRootContext->timeout);
4978 if (status) goto out;
4979
4980 status = map_setea_error(entry->status);
4981 if (status == STATUS_SUCCESS) {
4982 info->NextEntryOffset = 0;
4983 info->Flags = 0;
4984 info->EaNameLength = query->EaNameLength;
4985 info->EaValueLength = TargetName.Length - sizeof(UNICODE_NULL);
4986 TargetName.Buffer[TargetName.Length/sizeof(WCHAR)] = UNICODE_NULL;
4987 RtlCopyMemory(info->EaName, query->EaName, query->EaNameLength);
4988 RxContext->Info.LengthRemaining = HeaderLen + info->EaValueLength;
4989 } else if (status == STATUS_BUFFER_TOO_SMALL) {
4990 RxContext->InformationToReturn = HeaderLen +
4991 entry->u.Symlink.target->Length;
4992 }
4994out:
4995 return status;
4996}
4997
4999 IN OUT PRX_CONTEXT RxContext,
5002{
5004
5005 if (query == NULL)
5006 goto out;
5007
5008 if (AnsiStrEq(&NfsSymlinkTargetName, query->EaName, query->EaNameLength)) {
5009 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
5010 if (nfs41_fcb->BasicInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
5011 status = QueryCygwinSymlink(RxContext, query, info);
5012 goto out;
5013 } else {
5014 const LONG LengthRequired = sizeof(FILE_FULL_EA_INFORMATION) +
5015 NfsSymlinkTargetName.Length - sizeof(CHAR);
5016 if (LengthRequired > RxContext->Info.LengthRemaining) {
5018 RxContext->InformationToReturn = LengthRequired;
5019 goto out;
5020 }
5021 info->NextEntryOffset = 0;
5022 info->Flags = 0;
5023 info->EaValueLength = 0;
5024 info->EaNameLength = (UCHAR)NfsActOnLink.Length;
5025 RtlCopyMemory(info->EaName, NfsSymlinkTargetName.Buffer,
5026 NfsSymlinkTargetName.Length);
5027 RxContext->Info.LengthRemaining = LengthRequired;
5029 goto out;
5030 }
5031 }
5032
5033 if (AnsiStrEq(&NfsV3Attributes, query->EaName, query->EaNameLength)) {
5034 nfs3_attrs attrs;
5035
5036 const LONG LengthRequired = sizeof(FILE_FULL_EA_INFORMATION) +
5037 NfsV3Attributes.Length + sizeof(nfs3_attrs) - sizeof(CHAR);
5038 if (LengthRequired > RxContext->Info.LengthRemaining) {
5040 RxContext->InformationToReturn = LengthRequired;
5041 goto out;
5042 }
5043
5044 create_nfs3_attrs(&attrs, NFS41GetFcbExtension(RxContext->pFcb));
5045#ifdef DEBUG_EA_QUERY
5046 print_nfs3_attrs(&attrs);
5047#endif
5048
5049 info->NextEntryOffset = 0;
5050 info->Flags = 0;
5051 info->EaNameLength = (UCHAR)NfsV3Attributes.Length;
5052 info->EaValueLength = sizeof(nfs3_attrs);
5053 RtlCopyMemory(info->EaName, NfsV3Attributes.Buffer,
5054 NfsV3Attributes.Length);
5055 RtlCopyMemory(info->EaName + info->EaNameLength + 1, &attrs,
5056 sizeof(nfs3_attrs));
5057 RxContext->Info.LengthRemaining = LengthRequired;
5059 goto out;
5060 }
5061
5062 if (AnsiStrEq(&NfsActOnLink, query->EaName, query->EaNameLength)) {
5063
5064 const LONG LengthRequired = sizeof(FILE_FULL_EA_INFORMATION) +
5065 query->EaNameLength - sizeof(CHAR);
5066 if (LengthRequired > RxContext->Info.LengthRemaining) {
5068 RxContext->InformationToReturn = LengthRequired;
5069 goto out;
5070 }
5071
5072 info->NextEntryOffset = 0;
5073 info->Flags = 0;
5074 info->EaNameLength = query->EaNameLength;
5075 info->EaValueLength = 0;
5076 RtlCopyMemory(info->EaName, query->EaName, query->EaNameLength);
5077 RxContext->Info.LengthRemaining = LengthRequired;
5079 goto out;
5080 }
5081out:
5082 return status;
5083}
5084
5085#ifdef __REACTOS__
5087#else
5089#endif
5090 IN OUT PRX_CONTEXT RxContext)
5091{
5095 RxContext->CurrentIrpSp->Parameters.QueryEa.EaList;
5096 ULONG buflen = RxContext->CurrentIrpSp->Parameters.QueryEa.Length;
5097 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
5098 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5099 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
5100 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
5101 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
5102 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
5103#ifdef ENABLE_TIMINGS
5104 LARGE_INTEGER t1, t2;
5106#endif
5107
5108#ifdef DEBUG_EA_QUERY
5109 DbgEn();
5110 print_debug_header(RxContext);
5111 print_get_ea(1, query);
5112#endif
5113 status = check_nfs41_queryea_args(RxContext);
5114 if (status) goto out;
5115
5116 /* handle queries for cygwin EAs */
5117 status = QueryCygwinEA(RxContext, query,
5118 (PFILE_FULL_EA_INFORMATION)RxContext->Info.Buffer);
5120 goto out;
5121
5122 status = nfs41_UpcallCreate(NFS41_EA_GET, &nfs41_fobx->sec_ctx,
5123 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
5124 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
5125 if (status) goto out;
5126
5127 entry->buf_len = buflen;
5128 entry->buf = RxContext->Info.Buffer;
5129 entry->u.QueryEa.EaList = query;
5130 entry->u.QueryEa.EaListLength = query == NULL ? 0 :
5131 RxContext->QueryEa.UserEaListLength;
5132 entry->u.QueryEa.EaIndex = RxContext->QueryEa.IndexSpecified ?
5133 RxContext->QueryEa.UserEaIndex : 0;
5134 entry->u.QueryEa.RestartScan = RxContext->QueryEa.RestartScan;
5135 entry->u.QueryEa.ReturnSingleEntry = RxContext->QueryEa.ReturnSingleEntry;
5136
5137 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
5138 if (status) goto out;
5139
5140 if (entry->status == STATUS_SUCCESS) {
5141 switch (entry->u.QueryEa.Overflow) {
5144 break;
5146 status = RxContext->IoStatusBlock.Status = STATUS_BUFFER_OVERFLOW;
5147 break;
5148 default:
5149 RxContext->IoStatusBlock.Status = STATUS_SUCCESS;
5150 break;
5151 }
5152 RxContext->InformationToReturn = entry->buf_len;
5153#ifdef ENABLE_TIMINGS
5154 InterlockedIncrement(&getexattr.sops);
5155 InterlockedAdd64(&getexattr.size, entry->u.QueryEa.buf_len);
5156#endif
5157 } else {
5158 status = map_setea_error(entry->status);
5159 }
5161out:
5162#ifdef ENABLE_TIMINGS
5164 InterlockedIncrement(&getexattr.tops);
5165 InterlockedAdd64(&getexattr.ticks, t2.QuadPart - t1.QuadPart);
5166#ifdef ENABLE_INDV_TIMINGS
5167 DbgP("nfs41_QueryEaInformation delta = %d op=%d sum=%d\n",
5168 t2.QuadPart - t1.QuadPart, getexattr.tops, getexattr.ticks);
5169#endif
5170#endif
5171#ifdef DEBUG_EA_QUERY
5172 DbgEx();
5173#endif
5174 return status;
5175}
5176
5178 DWORD error)
5179{
5180 switch (error) {
5181 case NO_ERROR: return STATUS_SUCCESS;
5186 default:
5187 print_error("failed to map windows error %d to NTSTATUS; "
5188 "defaulting to STATUS_INVALID_NETWORK_RESPONSE\n", error);
5190 }
5191}
5192
5194 PRX_CONTEXT RxContext)
5195{
5198 RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
5199
5200 /* we don't support sacls */
5204 goto out;
5205 }
5206 if (RxContext->CurrentIrp->UserBuffer == NULL &&
5207 RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length)
5209out:
5210 return status;
5211}
5212
5213#ifdef __REACTOS__
5215#else
5217#endif
5218 IN OUT PRX_CONTEXT RxContext)
5219{
5222 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
5223 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
5224 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5225 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
5226 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
5227 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
5229 RxContext->CurrentIrpSp->Parameters.QuerySecurity.SecurityInformation;
5230#ifdef ENABLE_TIMINGS
5231 LARGE_INTEGER t1, t2;
5233#endif
5234
5235#ifdef DEBUG_ACL_QUERY
5236 DbgEn();
5237 print_debug_header(RxContext);
5239#endif
5240
5241 status = check_nfs41_getacl_args(RxContext);
5242 if (status) goto out;
5243
5244 if (nfs41_fobx->acl && nfs41_fobx->acl_len) {
5245 LARGE_INTEGER current_time;
5246 KeQuerySystemTime(&current_time);
5247#ifdef DEBUG_ACL_QUERY
5248 DbgP("CurrentTime %lx Saved Acl time %lx\n",
5249 current_time.QuadPart, nfs41_fobx->time.QuadPart);
5250#endif
5251 if (current_time.QuadPart - nfs41_fobx->time.QuadPart <= 20*1000) {
5253 RxContext->CurrentIrp->UserBuffer;
5254 RtlCopyMemory(sec_desc, nfs41_fobx->acl, nfs41_fobx->acl_len);
5255 RxContext->IoStatusBlock.Information =
5256 RxContext->InformationToReturn = nfs41_fobx->acl_len;
5257 RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
5258#ifdef ENABLE_TIMINGS
5259 InterlockedIncrement(&getacl.sops);
5260 InterlockedAdd64(&getacl.size, nfs41_fobx->acl_len);
5261#endif
5262 } else status = 1;
5263 RxFreePool(nfs41_fobx->acl);
5264 nfs41_fobx->acl = NULL;
5265 nfs41_fobx->acl_len = 0;
5266 if (!status)
5267 goto out;
5268 }
5269
5270 status = nfs41_UpcallCreate(NFS41_ACL_QUERY, &nfs41_fobx->sec_ctx,
5271 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
5272 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
5273 if (status) goto out;
5274
5275 entry->u.Acl.query = info_class;
5276 /* we can't provide RxContext->CurrentIrp->UserBuffer to the upcall thread
5277 * because it becomes an invalid pointer with that execution context
5278 */
5279 entry->buf_len = RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length;
5280
5281 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
5282 if (status) goto out;
5283
5284 if (entry->status == STATUS_BUFFER_TOO_SMALL) {
5285#ifdef DEBUG_ACL_QUERY
5286 DbgP("nfs41_QuerySecurityInformation: provided buffer size=%d but we "
5287 "need %lu\n",
5288 RxContext->CurrentIrpSp->Parameters.QuerySecurity.Length,
5289 entry->buf_len);
5290#endif
5292 RxContext->InformationToReturn = entry->buf_len;
5293
5294 /* Save ACL buffer */
5295 nfs41_fobx->acl = entry->buf;
5296 nfs41_fobx->acl_len = entry->buf_len;
5297 KeQuerySystemTime(&nfs41_fobx->time);
5298 } else if (entry->status == STATUS_SUCCESS) {
5300 RxContext->CurrentIrp->UserBuffer;
5301 RtlCopyMemory(sec_desc, entry->buf, entry->buf_len);
5302#ifdef ENABLE_TIMINGS
5303 InterlockedIncrement(&getacl.sops);
5304 InterlockedAdd64(&getacl.size, entry->u.Acl.buf_len);
5305#endif
5306 RxFreePool(entry->buf);
5307 nfs41_fobx->acl = NULL;
5308 nfs41_fobx->acl_len = 0;
5309 RxContext->IoStatusBlock.Information = RxContext->InformationToReturn =
5310 entry->buf_len;
5311 RxContext->IoStatusBlock.Status = status = STATUS_SUCCESS;
5312 } else {
5313 status = map_query_acl_error(entry->status);
5314 }
5316out:
5317#ifdef ENABLE_TIMINGS
5319 /* only count getacl that we made an upcall for */
5321 InterlockedIncrement(&getacl.tops);
5322 InterlockedAdd64(&getacl.ticks, t2.QuadPart - t1.QuadPart);
5323 }
5324#ifdef ENABLE_INDV_TIMINGS
5325 DbgP("nfs41_QuerySecurityInformation: delta = %d op=%d sum=%d\n",
5326 t2.QuadPart - t1.QuadPart, getacl.tops, getacl.ticks);
5327#endif
5328#endif
5329#ifdef DEBUG_ACL_QUERY
5330 DbgEx();
5331#endif
5332 return status;
5333}
5334
5336 PRX_CONTEXT RxContext)
5337{
5339 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5342 RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityInformation;
5343
5344 if (pVNetRootContext->read_only) {
5345 print_error("check_nfs41_setacl_args: Read-only mount\n");
5347 goto out;
5348 }
5349 /* we don't support sacls */
5353 goto out;
5354 }
5355out:
5356 return status;
5357}
5358
5359#ifdef __REACTOS__
5361#else
5363#endif
5364 IN OUT PRX_CONTEXT RxContext)
5365{
5368 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
5369 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
5370 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5371 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
5372 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
5373 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
5375 RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityDescriptor;
5376 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
5378 RxContext->CurrentIrpSp->Parameters.SetSecurity.SecurityInformation;
5379#ifdef ENABLE_TIMINGS
5380 LARGE_INTEGER t1, t2;
5382#endif
5383
5384#ifdef DEBUG_ACL_SET
5385 DbgEn();
5386 print_debug_header(RxContext);
5388#endif
5389
5390 status = check_nfs41_setacl_args(RxContext);
5391 if (status) goto out;
5392
5393 /* check that ACL is present */
5395 PACL acl;
5396 BOOLEAN present, dacl_default;
5397 status = RtlGetDaclSecurityDescriptor(sec_desc, &present, &acl,
5398 &dacl_default);
5399 if (status) {
5400 DbgP("RtlGetDaclSecurityDescriptor failed %x\n", status);
5401 goto out;
5402 }
5403 if (present == FALSE) {
5404 DbgP("NO ACL present\n");
5405 goto out;
5406 }
5407 }
5408
5409 status = nfs41_UpcallCreate(NFS41_ACL_SET, &nfs41_fobx->sec_ctx,
5410 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
5411 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
5412 if (status) goto out;
5413
5414 entry->u.Acl.query = info_class;
5415 entry->buf = sec_desc;
5416 entry->buf_len = RtlLengthSecurityDescriptor(sec_desc);
5417#ifdef ENABLE_TIMINGS
5418 InterlockedIncrement(&setacl.sops);
5419 InterlockedAdd64(&setacl.size, entry->u.Acl.buf_len);
5420#endif
5421
5422 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
5423 if (status) goto out;
5424
5425 status = map_query_acl_error(entry->status);
5426 if (!status) {
5427 if (!nfs41_fobx->deleg_type && entry->ChangeTime &&
5428 (SrvOpen->DesiredAccess &
5430 nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
5431 nfs41_fcb->changeattr = entry->ChangeTime;
5432 }
5434out:
5435#ifdef ENABLE_TIMINGS
5437 InterlockedIncrement(&setacl.tops);
5438 InterlockedAdd64(&setacl.ticks, t2.QuadPart - t1.QuadPart);
5439#ifdef ENABLE_INDV_TIMINGS
5440 DbgP("nfs41_SetSecurityInformation delta = %d op=%d sum=%d\n",
5441 t2.QuadPart - t1.QuadPart, setacl.tops, setacl.ticks);
5442#endif
5443#endif
5444#ifdef DEBUG_ACL_SET
5445 DbgEx();
5446#endif
5447 return status;
5448}
5449
5451 DWORD error)
5452{
5453 switch (error) {
5457 default:
5458 print_error("failed to map windows error %d to NTSTATUS; "
5459 "defaulting to STATUS_INVALID_NETWORK_RESPONSE\n", error);
5461 }
5462}
5463
5464#ifdef __REACTOS__
5466#else
5468#endif
5469 IN OUT PRX_CONTEXT RxContext)
5470{
5472 FILE_INFORMATION_CLASS InfoClass = RxContext->Info.FileInformationClass;
5474 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
5475 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5476 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
5477 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
5478 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
5479 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
5480 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
5481#ifdef ENABLE_TIMINGS
5482 LARGE_INTEGER t1, t2;
5484#endif
5485
5486#ifdef DEBUG_FILE_QUERY
5487 DbgEn();
5489#endif
5490
5491 status = check_nfs41_dirquery_args(RxContext);
5492 if (status) goto out;
5493
5494 switch (InfoClass) {
5495 case FileEaInformation:
5496 {
5498 (PFILE_EA_INFORMATION)RxContext->Info.Buffer;
5499 info->EaSize = 0;
5500 RxContext->Info.LengthRemaining -= sizeof(FILE_EA_INFORMATION);
5502 goto out;
5503 }
5509 break;
5510 default:
5511 print_error("nfs41_QueryFileInformation: unhandled class %d\n", InfoClass);
5513 goto out;
5514 }
5515
5516 status = nfs41_UpcallCreate(NFS41_FILE_QUERY, &nfs41_fobx->sec_ctx,
5517 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
5518 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
5519 if (status) goto out;
5520
5521 entry->u.QueryFile.InfoClass = InfoClass;
5522 entry->buf = RxContext->Info.Buffer;
5523 entry->buf_len = RxContext->Info.LengthRemaining;
5524
5525 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
5526 if (status) goto out;
5527
5528 if (entry->status == STATUS_BUFFER_TOO_SMALL) {
5529 RxContext->InformationToReturn = entry->buf_len;
5531 } else if (entry->status == STATUS_SUCCESS) {
5532 BOOLEAN DeletePending = FALSE;
5533#ifdef ENABLE_TIMINGS
5534 InterlockedIncrement(&getattr.sops);
5535 InterlockedAdd64(&getattr.size, entry->u.QueryFile.buf_len);
5536#endif
5537 RxContext->Info.LengthRemaining -= entry->buf_len;
5539
5540 switch (InfoClass) {
5542 RtlCopyMemory(&nfs41_fcb->BasicInfo, RxContext->Info.Buffer,
5543 sizeof(nfs41_fcb->BasicInfo));
5544#ifdef DEBUG_FILE_QUERY
5545 print_basic_info(1, &nfs41_fcb->BasicInfo);
5546#endif
5547 break;
5549 /* this a fix for RDBSS behaviour when it first calls ExtendForCache,
5550 * then it sends a file query irp for standard attributes and
5551 * expects to receive EndOfFile of value set by the ExtendForCache.
5552 * It seems to cache the filesize based on that instead of sending
5553 * a file size query for after doing the write.
5554 */
5555 {
5557 std_info = (PFILE_STANDARD_INFORMATION)RxContext->Info.Buffer;
5558 if (nfs41_fcb->StandardInfo.AllocationSize.QuadPart >
5559 std_info->AllocationSize.QuadPart) {
5560#ifdef DEBUG_FILE_QUERY
5561 DbgP("Old AllocationSize is bigger: saving %x\n",
5562 nfs41_fcb->StandardInfo.AllocationSize.QuadPart);
5563#endif
5564 std_info->AllocationSize.QuadPart =
5565 nfs41_fcb->StandardInfo.AllocationSize.QuadPart;
5566 }
5567 if (nfs41_fcb->StandardInfo.EndOfFile.QuadPart >
5568 std_info->EndOfFile.QuadPart) {
5569#ifdef DEBUG_FILE_QUERY
5570 DbgP("Old EndOfFile is bigger: saving %x\n",
5571 nfs41_fcb->StandardInfo.EndOfFile);
5572#endif
5573 std_info->EndOfFile.QuadPart =
5574 nfs41_fcb->StandardInfo.EndOfFile.QuadPart;
5575 }
5576 std_info->DeletePending = nfs41_fcb->DeletePending;
5577 }
5578 if (nfs41_fcb->StandardInfo.DeletePending)
5579 DeletePending = TRUE;
5580 RtlCopyMemory(&nfs41_fcb->StandardInfo, RxContext->Info.Buffer,
5581 sizeof(nfs41_fcb->StandardInfo));
5582 nfs41_fcb->StandardInfo.DeletePending = DeletePending;
5583#ifdef DEBUG_FILE_QUERY
5584 print_std_info(1, &nfs41_fcb->StandardInfo);
5585#endif
5586 break;
5587 }
5588 } else {
5589 status = map_queryfile_error(entry->status);
5590 }
5592out:
5593#ifdef ENABLE_TIMINGS
5595 InterlockedIncrement(&getattr.tops);
5596 InterlockedAdd64(&getattr.ticks, t2.QuadPart - t1.QuadPart);
5597#ifdef ENABLE_INDV_TIMINGS
5598 DbgP("nfs41_QueryFileInformation delta = %d op=%d sum=%d\n",
5599 t2.QuadPart - t1.QuadPart, getattr.tops, getattr.ticks);
5600#endif
5601#endif
5602#ifdef DEBUG_FILE_QUERY
5603 DbgEx();
5604#endif
5605 return status;
5606}
5607
5609 DWORD error)
5610{
5611 switch (error) {
5612 case NO_ERROR: return STATUS_SUCCESS;
5624 default:
5625 print_error("failed to map windows error %d to NTSTATUS; "
5626 "defaulting to STATUS_INVALID_PARAMETER\n", error);
5628 }
5629}
5630
5632 IN PRX_CONTEXT RxContext)
5633{
5635 FILE_INFORMATION_CLASS InfoClass = RxContext->Info.FileInformationClass;
5636 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5637 NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
5638
5639 if (pVNetRootContext->read_only) {
5640 print_error("check_nfs41_setattr_args: Read-only mount\n");
5642 goto out;
5643 }
5644
5645 /* http://msdn.microsoft.com/en-us/library/ff469355(v=PROT.10).aspx
5646 * http://msdn.microsoft.com/en-us/library/ff469424(v=PROT.10).aspx
5647 * If Open.GrantedAccess does not contain FILE_WRITE_DATA, the operation
5648 * MUST be failed with STATUS_ACCESS_DENIED.
5649 */
5650 if (InfoClass == FileAllocationInformation ||
5651 InfoClass == FileEndOfFileInformation) {
5652 if (!(RxContext->pRelevantSrvOpen->DesiredAccess & FILE_WRITE_DATA)) {
5654 goto out;
5655 }
5656 }
5657 status = check_nfs41_dirquery_args(RxContext);
5658 if (status) goto out;
5659
5660 switch (InfoClass) {
5662 {
5664 (PFILE_RENAME_INFORMATION)RxContext->Info.Buffer;
5666 (USHORT)rinfo->FileNameLength, rinfo->FileName };
5667#ifdef DEBUG_FILE_SET
5668 DbgP("Attempting to rename to '%wZ'\n", &dst);
5669#endif
5670 if (isFilenameTooLong(&dst, pVNetRootContext)) {
5672 goto out;
5673 }
5674 if (rinfo->RootDirectory) {
5676 goto out;
5677 }
5678 break;
5679 }
5681 {
5683 (PFILE_LINK_INFORMATION)RxContext->Info.Buffer;
5685 (USHORT)linfo->FileNameLength, linfo->FileName };
5686#ifdef DEBUG_FILE_SET
5687 DbgP("Attempting to add link as '%wZ'\n", &dst);
5688#endif
5689 if (isFilenameTooLong(&dst, pVNetRootContext)) {
5691 goto out;
5692 }
5693 if (linfo->RootDirectory) {
5695 goto out;
5696 }
5697 break;
5698 }
5700 {
5702 (PFILE_DISPOSITION_INFORMATION)RxContext->Info.Buffer;
5703 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
5704 if (dinfo->DeleteFile && nfs41_fcb->DeletePending) {
5706 goto out;
5707 }
5708 break;
5709 }
5713 break;
5714 default:
5715 print_error("nfs41_SetFileInformation: unhandled class %d\n", InfoClass);
5717 }
5718
5719out:
5720 return status;
5721}
5722
5723#ifdef __REACTOS__
5725#else
5727#endif
5728 IN OUT PRX_CONTEXT RxContext)
5729{
5732 FILE_INFORMATION_CLASS InfoClass = RxContext->Info.FileInformationClass;
5734 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
5735 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
5736 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
5737 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
5738 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
5739 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
5740 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
5741#ifdef ENABLE_TIMINGS
5742 LARGE_INTEGER t1, t2;
5744#endif
5745
5746#ifdef DEBUG_FILE_SET
5747 DbgEn();
5749#endif
5750
5751 status = check_nfs41_setattr_args(RxContext);
5752 if (status) goto out;
5753
5754 switch (InfoClass) {
5756 {
5758 (PFILE_DISPOSITION_INFORMATION)RxContext->Info.Buffer;
5759 if (dinfo->DeleteFile) {
5760 nfs41_fcb->DeletePending = TRUE;
5761 // we can delete directories right away
5762 if (nfs41_fcb->StandardInfo.Directory)
5763 break;
5764 nfs41_fcb->StandardInfo.DeletePending = TRUE;
5765 if (RxContext->pFcb->OpenCount > 1) {
5766 rinfo.ReplaceIfExists = 0;
5768 rinfo.FileNameLength = 0;
5769 rinfo.FileName[0] = L'\0';
5770 InfoClass = FileRenameInformation;
5771 nfs41_fcb->Renamed = TRUE;
5772 break;
5773 }
5774 } else {
5775 /* section 4.3.3 of [FSBO]
5776 * "file system behavior in the microsoft windows environment"
5777 */
5778 if (nfs41_fcb->DeletePending) {
5779 nfs41_fcb->DeletePending = 0;
5780 nfs41_fcb->StandardInfo.DeletePending = 0;
5781 }
5782 }
5784 goto out;
5785 }
5787 {
5789 (PFILE_END_OF_FILE_INFORMATION)RxContext->Info.Buffer;
5790 nfs41_fcb->StandardInfo.AllocationSize =
5791 nfs41_fcb->StandardInfo.EndOfFile = info->EndOfFile;
5792 break;
5793 }
5795 {
5796 /* noop if filename and destination are the same */
5798 (PFILE_RENAME_INFORMATION)RxContext->Info.Buffer;
5799 const UNICODE_STRING dst = { (USHORT)prinfo->FileNameLength,
5800 (USHORT)prinfo->FileNameLength, prinfo->FileName };
5802 SrvOpen->pAlreadyPrefixedName, FALSE) == 0) {
5804 goto out;
5805 }
5806 }
5807 }
5808
5809 status = nfs41_UpcallCreate(NFS41_FILE_SET, &nfs41_fobx->sec_ctx,
5810 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
5811 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
5812 if (status) goto out;
5813
5814 entry->u.SetFile.InfoClass = InfoClass;
5815
5816 /* original irp has infoclass for remove but we need to rename instead,
5817 * thus we changed the local variable infoclass */
5818 if (RxContext->Info.FileInformationClass == FileDispositionInformation &&
5819 InfoClass == FileRenameInformation) {
5820 entry->buf = &rinfo;
5821 entry->buf_len = sizeof(rinfo);
5822 } else {
5823 entry->buf = RxContext->Info.Buffer;
5824 entry->buf_len = RxContext->Info.Length;
5825 }
5826#ifdef ENABLE_TIMINGS
5827 InterlockedIncrement(&setattr.sops);
5828 InterlockedAdd64(&setattr.size, entry->u.SetFile.buf_len);
5829#endif
5830
5831 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
5832 if (status) goto out;
5833
5834 status = map_setfile_error(entry->status);
5835 if (!status) {
5836 if (!nfs41_fobx->deleg_type && entry->ChangeTime &&
5837 (SrvOpen->DesiredAccess &
5839 nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
5840 nfs41_fcb->changeattr = entry->ChangeTime;
5841 }
5843out:
5844#ifdef ENABLE_TIMINGS
5846 InterlockedIncrement(&setattr.tops);
5847 InterlockedAdd64(&setattr.ticks, t2.QuadPart - t1.QuadPart);
5848#ifdef ENABLE_INDV_TIMINGS
5849 DbgP("nfs41_SetFileInformation delta = %d op=%d sum=%d\n",
5850 t2.QuadPart - t1.QuadPart, setattr.tops, setattr.ticks);
5851#endif
5852#endif
5853#ifdef DEBUG_FILE_SET
5854 DbgEx();
5855#endif
5856 return status;
5857}
5858
5860 IN OUT PRX_CONTEXT RxContext)
5861{
5863 DbgEn();
5864 status = nfs41_SetFileInformation(RxContext);
5865 DbgEx();
5866 return status;
5867}
5868
5869#ifdef __REACTOS__
5871#else
5873#endif
5874 IN OUT PRX_CONTEXT RxContext,
5875 IN PUNICODE_STRING DirectoryName)
5876{
5877 return STATUS_SUCCESS;
5878}
5879
5880#ifdef __REACTOS__
5882#else
5884#endif
5885 IN OUT PMRX_SRV_OPEN pSrvOpen,
5886 IN PVOID pMRxContext,
5887 OUT ULONG *pNewBufferingState)
5888{
5890 ULONG flag = PtrToUlong(pMRxContext), oldFlags = pSrvOpen->BufferingFlags;
5891
5892 switch(flag) {
5893 case DISABLE_CACHING:
5894 if (pSrvOpen->BufferingFlags &
5896 pSrvOpen->BufferingFlags &=
5899 if (pSrvOpen->BufferingFlags &
5901 pSrvOpen->BufferingFlags &=
5904 pSrvOpen->BufferingFlags |= FCB_STATE_DISABLE_LOCAL_BUFFERING;
5905 break;
5907 pSrvOpen->BufferingFlags |=
5909 break;
5911 pSrvOpen->BufferingFlags |=
5913 break;
5915 pSrvOpen->BufferingFlags =
5918 }
5919#ifdef DEBUG_TIME_BASED_COHERENCY
5920 DbgP("nfs41_ComputeNewBufferingState: %wZ pSrvOpen %p Old %08x New %08x\n",
5921 pSrvOpen->pAlreadyPrefixedName, pSrvOpen, oldFlags,
5922 pSrvOpen->BufferingFlags);
5923 *pNewBufferingState = pSrvOpen->BufferingFlags;
5924#endif
5925 return status;
5926}
5927
5929 PRX_CONTEXT RxContext)
5930{
5931 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
5932
5933 print_debug_header(RxContext);
5934 DbgP("Bytecount 0x%x Byteoffset 0x%x Buffer %p\n",
5935 LowIoContext->ParamsFor.ReadWrite.ByteCount,
5936 LowIoContext->ParamsFor.ReadWrite.ByteOffset,
5937 LowIoContext->ParamsFor.ReadWrite.Buffer);
5938}
5939
5941 PMRX_SRV_OPEN SrvOpen,
5942 PNFS41_FOBX nfs41_fobx,
5943 ULONGLONG ChangeTime,
5945{
5946 ULONG flag = 0;
5949 BOOLEAN found = FALSE;
5950
5951 if (SrvOpen->DesiredAccess & FILE_READ_DATA)
5953 if ((SrvOpen->DesiredAccess & FILE_WRITE_DATA) &&
5954 !nfs41_fobx->write_thru)
5956 if ((SrvOpen->DesiredAccess & FILE_READ_DATA) &&
5957 (SrvOpen->DesiredAccess & FILE_WRITE_DATA) &&
5958 !nfs41_fobx->write_thru)
5960
5961#if defined(DEBUG_TIME_BASED_COHERENCY) || \
5962 defined(DEBUG_WRITE) || defined(DEBUG_READ)
5964#endif
5965
5966 if (!flag)
5967 return;
5968
5970
5973 while (!IsListEmpty(&openlist.head)) {
5976 if (cur->fcb == SrvOpen->pFcb) {
5977#ifdef DEBUG_TIME_BASED_COHERENCY
5978 DbgP("enable_caching: Looked&Found match for fcb=%p %wZ\n",
5979 SrvOpen->pFcb, SrvOpen->pAlreadyPrefixedName);
5980#endif
5981 cur->skip = FALSE;
5982 found = TRUE;
5983 break;
5984 }
5985 if (pEntry->Flink == &openlist.head) {
5986#ifdef DEBUG_TIME_BASED_COHERENCY
5987 DbgP("enable_caching: reached EOL looking for fcb=%p %wZ\n",
5988 SrvOpen->pFcb, SrvOpen->pAlreadyPrefixedName);
5989#endif
5990 break;
5991 }
5992 pEntry = pEntry->Flink;
5993 }
5994 if (!found && nfs41_fobx->deleg_type) {
5995 nfs41_fcb_list_entry *oentry;
5996#ifdef DEBUG_TIME_BASED_COHERENCY
5997 DbgP("enable_caching: delegation recalled: srv_open=%p\n", SrvOpen);
5998#endif
6001 if (oentry == NULL) return;
6002 oentry->fcb = SrvOpen->pFcb;
6003 oentry->session = session;
6004 oentry->nfs41_fobx = nfs41_fobx;
6005 oentry->ChangeTime = ChangeTime;
6006 oentry->skip = FALSE;
6007 InsertTailList(&openlist.head, &oentry->next);
6008 nfs41_fobx->deleg_type = 0;
6009 }
6011}
6012
6014 DWORD status)
6015{
6016 switch (status) {
6024 default:
6025 print_error("failed to map windows error %d to NTSTATUS; "
6026 "defaulting to STATUS_NET_WRITE_FAULT\n", status);
6028 }
6029}
6030
6032 IN PRX_CONTEXT RxContext)
6033{
6034 if (!RxContext->LowIoContext.ParamsFor.ReadWrite.Buffer)
6036 return STATUS_SUCCESS;
6037}
6038
6039#ifdef __REACTOS__
6041#else
6043#endif
6044 IN OUT PRX_CONTEXT RxContext)
6045{
6048 BOOLEAN async = FALSE;
6049 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6050 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6051 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
6052 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6053 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6054 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6055 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
6056 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
6057 DWORD io_delay;
6058#ifdef ENABLE_TIMINGS
6059 LARGE_INTEGER t1, t2;
6061#endif
6062
6063#ifdef DEBUG_READ
6064 DbgEn();
6065 print_readwrite_args(RxContext);
6066#endif
6067 status = check_nfs41_read_args(RxContext);
6068 if (status) goto out;
6069
6070 status = nfs41_UpcallCreate(NFS41_READ, &nfs41_fobx->sec_ctx,
6071 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
6072 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6073 if (status) goto out;
6074
6075 entry->u.ReadWrite.MdlAddress = LowIoContext->ParamsFor.ReadWrite.Buffer;
6076 entry->buf_len = LowIoContext->ParamsFor.ReadWrite.ByteCount;
6077 entry->u.ReadWrite.offset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
6078 if (FlagOn(RxContext->CurrentIrpSp->FileObject->Flags,
6080 entry->u.ReadWrite.rxcontext = RxContext;
6081 async = entry->async_op = TRUE;
6082 }
6083
6084 /* assume network speed is 100MB/s and disk speed is 100MB/s so add
6085 * time to transfer requested bytes over the network and read from disk
6086 */
6087 io_delay = pVNetRootContext->timeout + 2 * entry->buf_len / 104857600;
6089 if (status) goto out;
6090
6091 if (async) {
6092#ifdef DEBUG_READ
6093 DbgP("This is asynchronous read, returning control back to the user\n");
6094#endif
6096 goto out;
6097 }
6098
6099 if (entry->status == NO_ERROR) {
6100#ifdef ENABLE_TIMINGS
6102 InterlockedAdd64(&read.size, entry->u.ReadWrite.len);
6103#endif
6104 status = RxContext->CurrentIrp->IoStatus.Status = STATUS_SUCCESS;
6105 RxContext->IoStatusBlock.Information = entry->buf_len;
6106
6107 if ((!BooleanFlagOn(LowIoContext->ParamsFor.ReadWrite.Flags,
6109 (SrvOpen->DesiredAccess & FILE_READ_DATA) &&
6110 !pVNetRootContext->nocache && !nfs41_fobx->nocache &&
6111 !(SrvOpen->BufferingFlags &
6114 enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr,
6115 pVNetRootContext->session);
6116 }
6117 } else {
6119 RxContext->CurrentIrp->IoStatus.Status = status;
6120 RxContext->IoStatusBlock.Information = 0;
6121 }
6123out:
6124#ifdef ENABLE_TIMINGS
6127 InterlockedAdd64(&read.ticks, t2.QuadPart - t1.QuadPart);
6128#ifdef ENABLE_INDV_TIMINGS
6129 DbgP("nfs41_Read delta = %d op=%d sum=%d\n", t2.QuadPart - t1.QuadPart,
6130 read.tops, read.ticks);
6131#endif
6132#endif
6133#ifdef DEBUG_READ
6134 DbgEx();
6135#endif
6136 return status;
6137}
6138
6140 IN PRX_CONTEXT RxContext)
6141{
6143 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
6144 NFS41GetVNetRootExtension(RxContext->pRelevantSrvOpen->pVNetRoot);
6145
6146 if (!RxContext->LowIoContext.ParamsFor.ReadWrite.Buffer) {
6148 goto out;
6149 }
6150
6151 if (pVNetRootContext->read_only) {
6152 print_error("check_nfs41_write_args: Read-only mount\n");
6154 goto out;
6155 }
6156out:
6157 return status;
6158}
6159
6160#ifdef __REACTOS__
6162#else
6164#endif
6165 IN OUT PRX_CONTEXT RxContext)
6166{
6169 BOOLEAN async = FALSE;
6170 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6171 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6172 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
6173 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6174 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6175 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6176 __notnull PNFS41_FCB nfs41_fcb = NFS41GetFcbExtension(RxContext->pFcb);
6177 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
6178 DWORD io_delay;
6179#ifdef ENABLE_TIMINGS
6180 LARGE_INTEGER t1, t2;
6182#endif
6183
6184#ifdef DEBUG_WRITE
6185 DbgEn();
6186 print_readwrite_args(RxContext);
6187#endif
6188
6189 status = check_nfs41_write_args(RxContext);
6190 if (status) goto out;
6191
6192 status = nfs41_UpcallCreate(NFS41_WRITE, &nfs41_fobx->sec_ctx,
6193 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
6194 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6195 if (status) goto out;
6196
6197 entry->u.ReadWrite.MdlAddress = LowIoContext->ParamsFor.ReadWrite.Buffer;
6198 entry->buf_len = LowIoContext->ParamsFor.ReadWrite.ByteCount;
6199 entry->u.ReadWrite.offset = LowIoContext->ParamsFor.ReadWrite.ByteOffset;
6200
6201 if (FlagOn(RxContext->CurrentIrpSp->FileObject->Flags,
6203 entry->u.ReadWrite.rxcontext = RxContext;
6204 async = entry->async_op = TRUE;
6205 }
6206
6207 /* assume network speed is 100MB/s and disk speed is 100MB/s so add
6208 * time to transfer requested bytes over the network and write to disk
6209 */
6210 io_delay = pVNetRootContext->timeout + 2 * entry->buf_len / 104857600;
6212 if (status) goto out;
6213
6214 if (async) {
6215#ifdef DEBUG_WRITE
6216 DbgP("This is asynchronous write, returning control back to the user\n");
6217#endif
6219 goto out;
6220 }
6221
6222 if (entry->status == NO_ERROR) {
6223 //update cached file attributes
6224#ifdef ENABLE_TIMINGS
6226 InterlockedAdd64(&write.size, entry->u.ReadWrite.len);
6227#endif
6228 nfs41_fcb->StandardInfo.EndOfFile.QuadPart = entry->buf_len +
6229 entry->u.ReadWrite.offset;
6230 status = RxContext->CurrentIrp->IoStatus.Status = STATUS_SUCCESS;
6231 RxContext->IoStatusBlock.Information = entry->buf_len;
6232 nfs41_fcb->changeattr = entry->ChangeTime;
6233
6234 //re-enable write buffering
6235 if (!BooleanFlagOn(LowIoContext->ParamsFor.ReadWrite.Flags,
6237 (SrvOpen->DesiredAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) &&
6238 !pVNetRootContext->write_thru &&
6239 !pVNetRootContext->nocache &&
6240 !nfs41_fobx->write_thru && !nfs41_fobx->nocache &&
6241 !(SrvOpen->BufferingFlags &
6244 enable_caching(SrvOpen, nfs41_fobx, nfs41_fcb->changeattr,
6245 pVNetRootContext->session);
6246 } else if (!nfs41_fobx->deleg_type)
6247 nfs41_update_fcb_list(RxContext->pFcb, entry->ChangeTime);
6248
6249 } else {
6251 RxContext->CurrentIrp->IoStatus.Status = status;
6252 RxContext->IoStatusBlock.Information = 0;
6253 }
6255out:
6256#ifdef ENABLE_TIMINGS
6259 InterlockedAdd64(&write.ticks, t2.QuadPart - t1.QuadPart);
6260#ifdef ENABLE_INDV_TIMINGS
6261 DbgP("nfs41_Write delta = %d op=%d sum=%d\n", t2.QuadPart - t1.QuadPart,
6262 write.tops, write.ticks);
6263#endif
6264#endif
6265#ifdef DEBUG_WRITE
6266 DbgEx();
6267#endif
6268 return status;
6269}
6270
6271#ifdef __REACTOS__
6273#else
6275#endif
6276 IN OUT PMRX_FCB pFcb,
6279 IN ULONG LowIoLockFlags)
6280{
6282#ifdef DEBUG_LOCK
6283 DbgEn();
6284 DbgP("offset 0x%llx, length 0x%llx, exclusive=%u, blocking=%u\n",
6285 ByteOffset->QuadPart,Length->QuadPart,
6286 BooleanFlagOn(LowIoLockFlags, SL_EXCLUSIVE_LOCK),
6287 !BooleanFlagOn(LowIoLockFlags, SL_FAIL_IMMEDIATELY));
6288#endif
6289
6290 /* NFS lock operations with length=0 MUST fail with NFS4ERR_INVAL */
6291 if (Length->QuadPart == 0)
6293
6294#ifdef DEBUG_LOCK
6295 DbgEx();
6296#endif
6297 return status;
6298}
6299
6301 DWORD status)
6302{
6303 switch (status) {
6304 case NO_ERROR: return STATUS_SUCCESS;
6312 /* if we return ERROR_INVALID_PARAMETER, Windows translates that to
6313 * success!! */
6315 default:
6316 print_error("failed to map windows error %d to NTSTATUS; "
6317 "defaulting to STATUS_INVALID_NETWORK_RESPONSE\n", status);
6319 }
6320}
6321
6323 PRX_CONTEXT RxContext)
6324{
6325 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6326 const ULONG flags = LowIoContext->ParamsFor.Locks.Flags;
6327 print_debug_header(RxContext);
6328 DbgP("offset 0x%llx, length 0x%llx, exclusive=%u, blocking=%u\n",
6329 LowIoContext->ParamsFor.Locks.ByteOffset,
6330 LowIoContext->ParamsFor.Locks.Length,
6333}
6334
6335
6336/* use exponential backoff between polls for blocking locks */
6337#define MSEC_TO_RELATIVE_WAIT (-10000)
6338#define MIN_LOCK_POLL_WAIT (500 * MSEC_TO_RELATIVE_WAIT) /* 500ms */
6339#define MAX_LOCK_POLL_WAIT (30000 * MSEC_TO_RELATIVE_WAIT) /* 30s */
6340
6342 IN OUT PLARGE_INTEGER delay)
6343{
6344 if (delay->QuadPart == 0)
6345 delay->QuadPart = MIN_LOCK_POLL_WAIT;
6346 else
6347 delay->QuadPart <<= 1;
6348
6349 if (delay->QuadPart < MAX_LOCK_POLL_WAIT)
6350 delay->QuadPart = MAX_LOCK_POLL_WAIT;
6351}
6352
6353#ifdef __REACTOS__
6355#else
6357#endif
6358 IN OUT PRX_CONTEXT RxContext)
6359{
6362 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6363 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
6364 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6365 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
6366 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6367 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6368 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6369 const ULONG flags = LowIoContext->ParamsFor.Locks.Flags;
6370#ifdef _MSC_VER
6371 LARGE_INTEGER poll_delay = {0};
6372#else
6373 LARGE_INTEGER poll_delay;
6374#endif
6375#ifdef ENABLE_TIMINGS
6376 LARGE_INTEGER t1, t2;
6378#endif
6379
6380#ifndef _MSC_VER
6381 poll_delay.QuadPart = 0;
6382#endif
6383
6384#ifdef DEBUG_LOCK
6385 DbgEn();
6386 print_lock_args(RxContext);
6387#endif
6388
6389/* RxReleaseFcbResourceForThreadInMRx(RxContext, RxContext->pFcb,
6390 LowIoContext->ResourceThreadId); */
6391
6392 status = nfs41_UpcallCreate(NFS41_LOCK, &nfs41_fobx->sec_ctx,
6393 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
6394 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6395 if (status) goto out;
6396
6397 entry->u.Lock.offset = LowIoContext->ParamsFor.Locks.ByteOffset;
6398 entry->u.Lock.length = LowIoContext->ParamsFor.Locks.Length;
6399 entry->u.Lock.exclusive = BooleanFlagOn(flags, SL_EXCLUSIVE_LOCK);
6400 entry->u.Lock.blocking = !BooleanFlagOn(flags, SL_FAIL_IMMEDIATELY);
6401
6402retry_upcall:
6403 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
6404 if (status) goto out;
6405
6406 /* blocking locks keep trying until it succeeds */
6407 if (entry->status == ERROR_LOCK_FAILED && entry->u.Lock.blocking) {
6408 denied_lock_backoff(&poll_delay);
6409 DbgP("returned ERROR_LOCK_FAILED; retrying in %llums\n",
6410 poll_delay.QuadPart / MSEC_TO_RELATIVE_WAIT);
6413 goto retry_upcall;
6414 }
6415
6416 status = map_lock_errors(entry->status);
6417 RxContext->CurrentIrp->IoStatus.Status = status;
6418
6420out:
6421#ifdef ENABLE_TIMINGS
6424 InterlockedAdd64(&lock.ticks, t2.QuadPart - t1.QuadPart);
6425#ifdef ENABLE_INDV_TIMINGS
6426 DbgP("nfs41_Lock delta = %d op=%d sum=%d\n", t2.QuadPart - t1.QuadPart,
6427 lock.tops, lock.ticks);
6428#endif
6429#endif
6430#ifdef DEBUG_LOCK
6431 DbgEx();
6432#endif
6433 return status;
6434}
6435
6437 PRX_CONTEXT RxContext)
6438{
6439 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6440 print_debug_header(RxContext);
6441 if (LowIoContext->Operation == LOWIO_OP_UNLOCK_MULTIPLE) {
6442 PLOWIO_LOCK_LIST lock = LowIoContext->ParamsFor.Locks.LockList;
6443 DbgP("LOWIO_OP_UNLOCK_MULTIPLE:");
6444 while (lock) {
6445 DbgP(" (offset=%llu, length=%llu)", lock->ByteOffset, lock->Length);
6446 lock = lock->Next;
6447 }
6448 DbgP("\n");
6449 } else {
6450 DbgP("LOWIO_OP_UNLOCK: offset=%llu, length=%llu\n",
6451 LowIoContext->ParamsFor.Locks.ByteOffset,
6452 LowIoContext->ParamsFor.Locks.Length);
6453 }
6454}
6455
6458{
6459 ULONG count = 0;
6460 while (lock) {
6461 count++;
6462 lock = lock->Next;
6463 }
6464 return count;
6465}
6466
6467#ifdef __REACTOS__
6469#else
6471#endif
6472 IN OUT PRX_CONTEXT RxContext)
6473{
6476 PLOWIO_CONTEXT LowIoContext = &RxContext->LowIoContext;
6477 __notnull PNFS41_FOBX nfs41_fobx = NFS41GetFobxExtension(RxContext->pFobx);
6478 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6479 __notnull PNFS41_V_NET_ROOT_EXTENSION pVNetRootContext =
6480 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6481 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6482 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6483#ifdef ENABLE_TIMINGS
6484 LARGE_INTEGER t1, t2;
6486#endif
6487#ifdef DEBUG_LOCK
6488 DbgEn();
6489 print_lock_args(RxContext);
6490#endif
6491
6492/* RxReleaseFcbResourceForThreadInMRx(RxContext, RxContext->pFcb,
6493 LowIoContext->ResourceThreadId); */
6494
6495 status = nfs41_UpcallCreate(NFS41_UNLOCK, &nfs41_fobx->sec_ctx,
6496 pVNetRootContext->session, nfs41_fobx->nfs41_open_state,
6497 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6498 if (status) goto out;
6499
6500 if (LowIoContext->Operation == LOWIO_OP_UNLOCK_MULTIPLE) {
6501 entry->u.Unlock.count = unlock_list_count(
6502 LowIoContext->ParamsFor.Locks.LockList);
6503 RtlCopyMemory(&entry->u.Unlock.locks,
6504 LowIoContext->ParamsFor.Locks.LockList,
6505 sizeof(LOWIO_LOCK_LIST));
6506 } else {
6507 entry->u.Unlock.count = 1;
6508 entry->u.Unlock.locks.ByteOffset =
6509 LowIoContext->ParamsFor.Locks.ByteOffset;
6510 entry->u.Unlock.locks.Length =
6511 LowIoContext->ParamsFor.Locks.Length;
6512 }
6513
6514 status = nfs41_UpcallWaitForReply(entry, pVNetRootContext->timeout);
6515 if (status) goto out;
6516
6517 status = map_lock_errors(entry->status);
6518 RxContext->CurrentIrp->IoStatus.Status = status;
6520out:
6521#ifdef ENABLE_TIMINGS
6523 InterlockedIncrement(&unlock.tops);
6524 InterlockedAdd64(&unlock.ticks, t2.QuadPart - t1.QuadPart);
6525#ifdef ENABLE_INDV_TIMINGS
6526 DbgP("nfs41_Unlock delta = %d op=%d sum=%d\n", t2.QuadPart - t1.QuadPart,
6527 unlock.tops, unlock.ticks);
6528#endif
6529#endif
6530#ifdef DEBUG_LOCK
6531 DbgEx();
6532#endif
6533 return status;
6534}
6535
6538{
6539 switch (status) {
6540 case NO_ERROR: return STATUS_SUCCESS;
6549 default:
6550 print_error("failed to map windows error %d to NTSTATUS; "
6551 "defaulting to STATUS_INVALID_NETWORK_RESPONSE\n", status);
6553 }
6554}
6555
6557 PREPARSE_DATA_BUFFER Reparse)
6558{
6560 DbgP("ReparseTag: %08X\n", Reparse->ReparseTag);
6561 DbgP("ReparseDataLength: %8u\n", Reparse->ReparseDataLength);
6562 DbgP("Reserved: %8u\n", Reparse->Reserved);
6563 DbgP("SubstituteNameOffset: %8u\n",
6564 Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset);
6565 DbgP("SubstituteNameLength: %8u\n",
6566 Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength);
6567 DbgP("PrintNameOffset: %8u\n",
6568 Reparse->SymbolicLinkReparseBuffer.PrintNameOffset);
6569 DbgP("PrintNameLength: %8u\n",
6570 Reparse->SymbolicLinkReparseBuffer.PrintNameLength);
6571 DbgP("Flags: %08X\n",
6572 Reparse->SymbolicLinkReparseBuffer.Flags);
6573
6574 name.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
6575 Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset/sizeof(WCHAR)];
6576 name.MaximumLength = name.Length =
6577 Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength;
6578 DbgP("SubstituteName: %wZ\n", &name);
6579
6580 name.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
6581 Reparse->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
6582 name.MaximumLength = name.Length =
6583 Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
6584 DbgP("PrintName: %wZ\n", &name);
6585}
6586
6588 IN PRX_CONTEXT RxContext)
6589{
6591 __notnull XXCTL_LOWIO_COMPONENT *FsCtl = &RxContext->LowIoContext.ParamsFor.FsCtl;
6592 __notnull PREPARSE_DATA_BUFFER Reparse = (PREPARSE_DATA_BUFFER)FsCtl->pInputBuffer;
6593 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6594 __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
6595 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6596 const ULONG HeaderLen = REPARSE_DATA_BUFFER_HEADER_SIZE;
6597
6598 /* access checks */
6599 if (VNetRootContext->read_only) {
6601 goto out;
6602 }
6603 if (!(SrvOpen->DesiredAccess & (FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES))) {
6605 goto out;
6606 }
6607
6608 /* must have a filename longer than vnetroot name,
6609 * or it's trying to operate on the volume itself */
6610 if (is_root_directory(RxContext)) {
6612 goto out;
6613 }
6614 if (FsCtl->pOutputBuffer != NULL) {
6616 goto out;
6617 }
6618
6619 /* validate input buffer and length */
6620 if (!Reparse) {
6622 goto out;
6623 }
6624
6625 if (FsCtl->InputBufferLength < HeaderLen ||
6626 FsCtl->InputBufferLength > MAXIMUM_REPARSE_DATA_BUFFER_SIZE) {
6628 goto out;
6629 }
6630 if (FsCtl->InputBufferLength != HeaderLen + Reparse->ReparseDataLength) {
6632 goto out;
6633 }
6634
6635 /* validate reparse tag */
6636 if (!IsReparseTagValid(Reparse->ReparseTag)) {
6638 goto out;
6639 }
6640 if (Reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
6642 goto out;
6643 }
6644out:
6645 return status;
6646}
6647
6649 IN OUT PRX_CONTEXT RxContext)
6650{
6653 __notnull XXCTL_LOWIO_COMPONENT *FsCtl = &RxContext->LowIoContext.ParamsFor.FsCtl;
6654 __notnull PREPARSE_DATA_BUFFER Reparse = (PREPARSE_DATA_BUFFER)FsCtl->pInputBuffer;
6655 __notnull PNFS41_FOBX Fobx = NFS41GetFobxExtension(RxContext->pFobx);
6656 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6657 __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
6658 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6659 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6660 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6662
6663#ifdef DEBUG_SYMLINK
6664 DbgEn();
6665 print_debug_header(RxContext);
6666 print_reparse_buffer(Reparse);
6667#endif
6669 if (status) goto out;
6670
6671 TargetName.MaximumLength = TargetName.Length =
6672 Reparse->SymbolicLinkReparseBuffer.PrintNameLength;
6673 TargetName.Buffer = &Reparse->SymbolicLinkReparseBuffer.PathBuffer[
6674 Reparse->SymbolicLinkReparseBuffer.PrintNameOffset/sizeof(WCHAR)];
6675
6676 status = nfs41_UpcallCreate(NFS41_SYMLINK, &Fobx->sec_ctx,
6677 VNetRootContext->session, Fobx->nfs41_open_state,
6678 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6679 if (status) goto out;
6680
6681 entry->u.Symlink.target = &TargetName;
6682 entry->u.Symlink.set = TRUE;
6683
6684 status = nfs41_UpcallWaitForReply(entry, VNetRootContext->timeout);
6685 if (status) goto out;
6686
6687 status = map_symlink_errors(entry->status);
6689out:
6690#ifdef DEBUG_SYMLINK
6691 DbgEx();
6692#endif
6693 return status;
6694}
6695
6697 PRX_CONTEXT RxContext)
6698{
6701 const USHORT HeaderLen = FIELD_OFFSET(REPARSE_DATA_BUFFER,
6702 SymbolicLinkReparseBuffer.PathBuffer);
6703
6704 /* must have a filename longer than vnetroot name,
6705 * or it's trying to operate on the volume itself */
6706 if (is_root_directory(RxContext)) {
6708 goto out;
6709 }
6710 /* ifs reparse tests expect STATUS_INVALID_PARAMETER,
6711 * but 'dir' passes a buffer here when querying symlinks
6712 if (FsCtl->pInputBuffer != NULL) {
6713 status = STATUS_INVALID_PARAMETER;
6714 goto out;
6715 } */
6716 if (!FsCtl->pOutputBuffer) {
6718 goto out;
6719 }
6720 if (!BooleanFlagOn(RxContext->pFcb->Attributes,
6723 DbgP("FILE_ATTRIBUTE_REPARSE_POINT is not set!\n");
6724 goto out;
6725 }
6726
6727 if (FsCtl->OutputBufferLength < HeaderLen) {
6728 RxContext->InformationToReturn = HeaderLen;
6730 goto out;
6731 }
6732out:
6733 return status;
6734}
6735
6737 IN OUT PRX_CONTEXT RxContext)
6738{
6741 XXCTL_LOWIO_COMPONENT *FsCtl = &RxContext->LowIoContext.ParamsFor.FsCtl;
6742 __notnull PNFS41_FOBX Fobx = NFS41GetFobxExtension(RxContext->pFobx);
6743 __notnull PMRX_SRV_OPEN SrvOpen = RxContext->pRelevantSrvOpen;
6744 __notnull PNFS41_V_NET_ROOT_EXTENSION VNetRootContext =
6745 NFS41GetVNetRootExtension(SrvOpen->pVNetRoot);
6746 __notnull PNFS41_NETROOT_EXTENSION pNetRootContext =
6747 NFS41GetNetRootExtension(SrvOpen->pVNetRoot->pNetRoot);
6749 const USHORT HeaderLen = FIELD_OFFSET(REPARSE_DATA_BUFFER,
6750 SymbolicLinkReparseBuffer.PathBuffer);
6751
6752#ifdef DEBUG_SYMLINK
6753 DbgEn();
6754#endif
6756 if (status) goto out;
6757
6758 TargetName.Buffer = (PWCH)((PBYTE)FsCtl->pOutputBuffer + HeaderLen);
6759 TargetName.MaximumLength = (USHORT)min(FsCtl->OutputBufferLength -
6760 HeaderLen, 0xFFFF);
6761
6762 status = nfs41_UpcallCreate(NFS41_SYMLINK, &Fobx->sec_ctx,
6763 VNetRootContext->session, Fobx->nfs41_open_state,
6764 pNetRootContext->nfs41d_version, SrvOpen->pAlreadyPrefixedName, &entry);
6765 if (status) goto out;
6766
6767 entry->u.Symlink.target = &TargetName;
6768 entry->u.Symlink.set = FALSE;
6769
6770 status = nfs41_UpcallWaitForReply(entry, VNetRootContext->timeout);
6771 if (status) goto out;
6772
6773 status = map_symlink_errors(entry->status);
6774 if (status == STATUS_SUCCESS) {
6775 /* fill in the output buffer */
6777 FsCtl->pOutputBuffer;
6779 Reparse->ReparseDataLength = HeaderLen + TargetName.Length -
6781 Reparse->Reserved = 0;
6783 /* PrintName and SubstituteName point to the same string */
6784 Reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;
6785 Reparse->SymbolicLinkReparseBuffer.SubstituteNameLength =
6786 TargetName.Length;
6787 Reparse->SymbolicLinkReparseBuffer.PrintNameOffset = 0;
6788 Reparse->SymbolicLinkReparseBuffer.PrintNameLength = TargetName.Length;
6789 print_reparse_buffer(Reparse);
6790
6791 RxContext->IoStatusBlock.Information = HeaderLen + TargetName.Length;
6792 } else if (status == STATUS_BUFFER_TOO_SMALL) {
6793 RxContext->InformationToReturn = HeaderLen + TargetName.Length;
6794 }
6796out:
6797#ifdef DEBUG_SYMLINK
6798 DbgEx();
6799#endif
6800 return status;
6801}
6802
6803#ifdef __REACTOS__
6805#else
6807#endif
6808 IN OUT PRX_CONTEXT RxContext)
6809{
6811#ifdef DEBUG_MISC
6812 DbgEn();
6813 print_debug_header(RxContext);
6814#endif
6815 switch (RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode) {
6817 status = nfs41_SetReparsePoint(RxContext);
6818 break;
6819
6821 status = nfs41_GetReparsePoint(RxContext);
6822 break;
6823#ifdef DEBUG_MISC
6824 default:
6825 DbgP("FsControlCode: %d\n",
6826 RxContext->LowIoContext.ParamsFor.FsCtl.FsControlCode);
6827#endif
6828 }
6829#ifdef DEBUG_MISC
6830 DbgEx();
6831#endif
6832 return status;
6833}
6834
6835#ifdef __REACTOS__
6837#else
6839#endif
6840 IN OUT PRX_CONTEXT RxContext,
6841 IN OUT PMRX_SRV_OPEN SrvOpen,
6842 IN PVOID pContext)
6843{
6844 return STATUS_SUCCESS;
6845}
6846
6847#ifdef __REACTOS__
6849#else
6851#endif
6853 IN PIRP Irp)
6854{
6855#ifdef DEBUG_FSDDISPATCH
6857#endif
6859
6860#ifdef DEBUG_FSDDISPATCH
6861 DbgEn();
6862 DbgP("CURRENT IRP = %d.%d\n", IrpSp->MajorFunction, IrpSp->MinorFunction);
6863 if(IrpSp->FileObject)
6864 DbgP("FileOject %p Filename %wZ\n", IrpSp->FileObject,
6865 &IrpSp->FileObject->FileName);
6866#endif
6867
6868 if (dev != (PDEVICE_OBJECT)nfs41_dev) {
6869 print_error("*** not ours ***\n");
6870 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
6871 Irp->IoStatus.Information = 0;
6874 goto out;
6875 }
6876
6878 /* AGLO: 08/05/2009 - looks like RxFsdDispatch frees IrpSp */
6879
6880out:
6881#ifdef DEBUG_FSDDISPATCH
6882 DbgP("IoStatus status = 0x%x info = 0x%x\n", Irp->IoStatus.Status,
6883 Irp->IoStatus.Information);
6884 DbgEx();
6885#endif
6886 return status;
6887}
6888
6889#ifdef __REACTOS__
6891#else
6893#endif
6894 PRX_CONTEXT RxContext)
6895{
6897}
6898
6899#ifdef __REACTOS__
6901#else
6903#endif
6904 PFCB a,
6905 PFCB b)
6906{
6908}
6909
6911{
6912 DbgEn();
6913
6915 sizeof(MINIRDR_DISPATCH));
6916
6921
6922 nfs41_ops.MRxSrvCallSize = 0; // srvcall extension is not handled in rdbss
6923 nfs41_ops.MRxNetRootSize = sizeof(NFS41_NETROOT_EXTENSION);
6924 nfs41_ops.MRxVNetRootSize = sizeof(NFS41_V_NET_ROOT_EXTENSION);
6925 nfs41_ops.MRxFcbSize = sizeof(NFS41_FCB);
6926 nfs41_ops.MRxFobxSize = sizeof(NFS41_FOBX);
6927
6928 // Mini redirector cancel routine ..
6929
6930 nfs41_ops.MRxCancel = NULL;
6931
6932 //
6933 // Mini redirector Start/Stop. Each mini-rdr can be started or stopped
6934 // while the others continue to operate.
6935 //
6936
6937 nfs41_ops.MRxStart = nfs41_Start;
6938 nfs41_ops.MRxStop = nfs41_Stop;
6939 nfs41_ops.MRxDevFcbXXXControlFile = nfs41_DevFcbXXXControlFile;
6940
6941 //
6942 // Mini redirector name resolution.
6943 //
6944
6945 nfs41_ops.MRxCreateSrvCall = nfs41_CreateSrvCall;
6946 nfs41_ops.MRxSrvCallWinnerNotify = nfs41_SrvCallWinnerNotify;
6947 nfs41_ops.MRxCreateVNetRoot = nfs41_CreateVNetRoot;
6948 nfs41_ops.MRxExtractNetRootName = nfs41_ExtractNetRootName;
6949 nfs41_ops.MRxFinalizeSrvCall = nfs41_FinalizeSrvCall;
6950 nfs41_ops.MRxFinalizeNetRoot = nfs41_FinalizeNetRoot;
6951 nfs41_ops.MRxFinalizeVNetRoot = nfs41_FinalizeVNetRoot;
6952
6953 //
6954 // File System Object Creation/Deletion.
6955 //
6956
6957 nfs41_ops.MRxCreate = nfs41_Create;
6958 nfs41_ops.MRxCollapseOpen = nfs41_CollapseOpen;
6959 nfs41_ops.MRxShouldTryToCollapseThisOpen = nfs41_ShouldTryToCollapseThisOpen;
6960 nfs41_ops.MRxExtendForCache = nfs41_ExtendForCache;
6961 nfs41_ops.MRxExtendForNonCache = nfs41_ExtendForCache;
6962 nfs41_ops.MRxCloseSrvOpen = nfs41_CloseSrvOpen;
6963 nfs41_ops.MRxFlush = nfs41_Flush;
6964 nfs41_ops.MRxDeallocateForFcb = nfs41_DeallocateForFcb;
6965 nfs41_ops.MRxDeallocateForFobx = nfs41_DeallocateForFobx;
6966 nfs41_ops.MRxIsLockRealizable = nfs41_IsLockRealizable;
6967
6968 //
6969 // File System Objects query/Set
6970 //
6971
6972 nfs41_ops.MRxQueryDirectory = nfs41_QueryDirectory;
6973 nfs41_ops.MRxQueryVolumeInfo = nfs41_QueryVolumeInformation;
6974 nfs41_ops.MRxQueryEaInfo = nfs41_QueryEaInformation;
6975 nfs41_ops.MRxSetEaInfo = nfs41_SetEaInformation;
6978 nfs41_ops.MRxQueryFileInfo = nfs41_QueryFileInformation;
6979 nfs41_ops.MRxSetFileInfo = nfs41_SetFileInformation;
6980
6981 //
6982 // Buffering state change
6983 //
6984
6985 nfs41_ops.MRxComputeNewBufferingState = nfs41_ComputeNewBufferingState;
6986
6987 //
6988 // File System Object I/O
6989 //
6990
6991 nfs41_ops.MRxLowIOSubmit[LOWIO_OP_READ] = nfs41_Read;
6992 nfs41_ops.MRxLowIOSubmit[LOWIO_OP_WRITE] = nfs41_Write;
6993 nfs41_ops.MRxLowIOSubmit[LOWIO_OP_SHAREDLOCK] = nfs41_Lock;
6995 nfs41_ops.MRxLowIOSubmit[LOWIO_OP_UNLOCK] = nfs41_Unlock;
6997 nfs41_ops.MRxLowIOSubmit[LOWIO_OP_FSCTL] = nfs41_FsCtl;
6998
6999 //
7000 // Miscellanous
7001 //
7002
7003 nfs41_ops.MRxCompleteBufferingStateChangeRequest =
7005 nfs41_ops.MRxIsValidDirectory = nfs41_IsValidDirectory;
7006
7007 nfs41_ops.MRxTruncate = nfs41_Unimplemented;
7008 nfs41_ops.MRxZeroExtend = nfs41_Unimplemented;
7009 nfs41_ops.MRxAreFilesAliased = nfs41_AreFilesAliased;
7010 nfs41_ops.MRxQueryQuotaInfo = nfs41_Unimplemented;
7011 nfs41_ops.MRxSetQuotaInfo = nfs41_Unimplemented;
7012 nfs41_ops.MRxSetVolumeInfo = nfs41_Unimplemented;
7013
7014 DbgR();
7015 return(STATUS_SUCCESS);
7016}
7017
7018KSTART_ROUTINE fcbopen_main;
7019#ifdef __REACTOS__
7021#else
7023#endif
7024{
7027
7028 DbgEn();
7029 timeout.QuadPart = RELATIVE(SECONDS(30));
7030 while(1) {
7036 while (!IsListEmpty(&openlist.head)) {
7037 PNFS41_NETROOT_EXTENSION pNetRootContext;
7040 PNFS41_FCB nfs41_fcb;
7043
7044#ifdef DEBUG_TIME_BASED_COHERENCY
7045 DbgP("fcbopen_main: Checking attributes for fcb=%p "
7046 "change_time=%llu skipping=%d\n", cur->fcb,
7047 cur->ChangeTime, cur->skip);
7048#endif
7049 if (cur->skip) goto out;
7050 pNetRootContext =
7051 NFS41GetNetRootExtension(cur->fcb->pNetRoot);
7052 /* place an upcall for this srv_open */
7054 &cur->nfs41_fobx->sec_ctx, cur->session,
7055 cur->nfs41_fobx->nfs41_open_state,
7056 pNetRootContext->nfs41d_version, NULL, &entry);
7057 if (status) goto out;
7058
7059 entry->u.QueryFile.InfoClass = FileBasicInformation;
7060 entry->buf = &binfo;
7061 entry->buf_len = sizeof(binfo);
7062
7064 if (status) goto out;
7065
7066 if (cur->ChangeTime != entry->ChangeTime) {
7068 PMRX_SRV_OPEN srv_open;
7069 PLIST_ENTRY psrvEntry;
7070#ifdef DEBUG_TIME_BASED_COHERENCY
7071 DbgP("fcbopen_main: old ctime=%llu new_ctime=%llu\n",
7072 cur->ChangeTime, entry->ChangeTime);
7073#endif
7074 cur->ChangeTime = entry->ChangeTime;
7075 cur->skip = TRUE;
7076 psrvEntry = &cur->fcb->SrvOpenList;
7077 psrvEntry = psrvEntry->Flink;
7078 while (!IsListEmpty(&cur->fcb->SrvOpenList)) {
7079 srv_open = (PMRX_SRV_OPEN)CONTAINING_RECORD(psrvEntry,
7080 MRX_SRV_OPEN, SrvOpenQLinks);
7081 if (srv_open->DesiredAccess &
7083#ifdef DEBUG_TIME_BASED_COHERENCY
7084 DbgP("fcbopen_main: ************ Invalidate the cache %wZ"
7085 "************\n", srv_open->pAlreadyPrefixedName);
7086#endif
7088 cur->fcb->pNetRoot->pSrvCall, srv_open,
7089 srv_open->Key, ULongToPtr(flag));
7090 }
7091 if (psrvEntry->Flink == &cur->fcb->SrvOpenList) {
7092#ifdef DEBUG_TIME_BASED_COHERENCY
7093 DbgP("fcbopen_main: reached end of srvopen for fcb %p\n",
7094 cur->fcb);
7095#endif
7096 break;
7097 }
7098 psrvEntry = psrvEntry->Flink;
7099 };
7100 }
7101 nfs41_fcb = (PNFS41_FCB)cur->fcb->Context;
7102 nfs41_fcb->changeattr = entry->ChangeTime;
7104out:
7105 if (pEntry->Flink == &openlist.head) {
7106#ifdef DEBUG_TIME_BASED_COHERENCY
7107 DbgP("fcbopen_main: reached end of the fcb list\n");
7108#endif
7109 break;
7110 }
7111 pEntry = pEntry->Flink;
7112 }
7114 }
7115 DbgEx();
7116}
7117
7118#ifdef __REACTOS__
7120#else
7122#endif
7123 IN PDRIVER_OBJECT drv,
7125{
7127 ULONG flags = 0, i;
7128 UNICODE_STRING dev_name, user_dev_name;
7129 PNFS41_DEVICE_EXTENSION dev_exts;
7130 TIME_FIELDS jan_1_1970 = {1970, 1, 1, 0, 0, 0, 0, 0};
7131 ACCESS_MASK mask = 0;
7132 OBJECT_ATTRIBUTES oattrs;
7133
7134 DbgEn();
7135
7136 status = RxDriverEntry(drv, path);
7137 if (status != STATUS_SUCCESS) {
7138 print_error("RxDriverEntry failed: %08lx\n", status);
7139 goto out;
7140 }
7141
7144
7146 if (status != STATUS_SUCCESS) {
7147 print_error("nfs41_init_ops failed to initialize dispatch table\n");
7148 goto out;
7149 }
7150
7151 DbgP("calling RxRegisterMinirdr\n");
7153 sizeof(NFS41_DEVICE_EXTENSION),
7155 if (status != STATUS_SUCCESS) {
7156 print_error("RxRegisterMinirdr failed: %08lx\n", status);
7157 goto out;
7158 }
7159#ifndef __REACTOS__
7160 nfs41_dev->Flags |= DO_BUFFERED_IO;
7161#endif
7162
7163 dev_exts = (PNFS41_DEVICE_EXTENSION)
7164 ((PBYTE)(nfs41_dev) + sizeof(RDBSS_DEVICE_OBJECT));
7165
7167 dev_exts->DeviceObject = nfs41_dev;
7169 &dev_exts->VolAttrsLen);
7170
7172 DbgP("calling IoCreateSymbolicLink %wZ %wZ\n", &user_dev_name, &dev_name);
7173 status = IoCreateSymbolicLink(&user_dev_name, &dev_name);
7174 if (status != STATUS_SUCCESS) {
7175 print_error("Device name IoCreateSymbolicLink failed: %08lx\n", status);
7176 goto out_unregister;
7177 }
7178
7190 &oattrs, NULL, NULL, &fcbopen_main, NULL);
7191 if (status != STATUS_SUCCESS)
7192 goto out_unregister;
7193
7194 drv->DriverUnload = nfs41_driver_unload;
7195
7196 for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
7197 drv->MajorFunction[i] = (PDRIVER_DISPATCH)nfs41_FsdDispatch;
7198
7199 RtlTimeFieldsToTime(&jan_1_1970, &unix_time_diff);
7200
7201out_unregister:
7202 if (status != STATUS_SUCCESS)
7204out:
7205 DbgEx();
7206 return status;
7207}
7208
7209#ifdef __REACTOS__
7211#else
7213#endif
7214{
7215 PRX_CONTEXT RxContext;
7217 UNICODE_STRING dev_name, pipe_name;
7218
7219 DbgEn();
7220
7222 if (RxContext == NULL) {
7224 goto unload;
7225 }
7226 status = RxStopMinirdr(RxContext, &RxContext->PostRequest);
7228
7229unload:
7232 if (status != STATUS_SUCCESS) {
7233 print_error("couldn't delete device symbolic link\n");
7234 }
7236 status = IoDeleteSymbolicLink(&pipe_name);
7237 if (status != STATUS_SUCCESS) {
7238 print_error("couldn't delete pipe symbolic link\n");
7239 }
7240 RxUnload(drv);
7241
7242 DbgP("driver unloaded %p\n", drv);
7243 DbgR();
7244}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
#define __inline
Definition: _wctype.cpp:15
#define read
Definition: acwin.h:96
#define open
Definition: acwin.h:95
#define close
Definition: acwin.h:98
#define write
Definition: acwin.h:97
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
#define STATUS_TIMEOUT
Definition: d3dkmdt.h:49
#define STATUS_PENDING
Definition: d3dkmdt.h:43
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
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
LPWSTR Name
Definition: desk.c:124
#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:33
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:48
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:4138
#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:879
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:732
#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:897
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 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 EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define InterlockedAdd64
Definition: interlocked.h:72
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
#define InterlockedCompareExchange
Definition: interlocked.h:119
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:54
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 KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
#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
#define __notnull
Definition: no_sal2.h:36
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:422
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:395
#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_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_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_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_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
#define FSCTL_GET_REPARSE_POINT
Definition: winioctl.h:746
#define FSCTL_SET_REPARSE_POINT
Definition: winioctl.h:747
#define FILE_DEVICE_NETWORK_FILE_SYSTEM
Definition: winioctl.h:65
#define FILE_DEVICE_DISK
Definition: winioctl.h:52
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
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
#define RtlUTF8ToUnicodeN
Definition: reactos.cpp:12
#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
struct _FILE_STANDARD_INFORMATION * PFILE_STANDARD_INFORMATION
#define FileAccessInformation
Definition: propsheet.cpp:51
#define FileStandardInformation
Definition: propsheet.cpp:61
#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
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
struct _IO_STACK_LOCATION::@4137::@4155 QuerySecurity
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
struct _IO_STACK_LOCATION::@4137::@4156 SetSecurity
union _IO_STACK_LOCATION::@1647 Parameters
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
USHORT Operation
Definition: mrx.h:281
struct _LOWIO_CONTEXT::@2185::@2187 Locks
struct _LOWIO_CONTEXT::@2185::@2186 ReadWrite
union _LOWIO_CONTEXT::@2185 ParamsFor
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::@354::@356 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
PMRX_FOBX pFobx
Definition: rxcontx.h:113
struct _RX_CONTEXT::@2268::@2281 QueryDirectory
PIO_STACK_LOCATION CurrentIrpSp
Definition: rxcontx.h:111
struct _RX_CONTEXT::@2266::@2274 Info
PMRX_SRV_OPEN pRelevantSrvOpen
Definition: rxcontx.h:114
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
struct _nfs3_attrs::@816 rdev
DWORD specdata2
Definition: nfs41_driver.c:137
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
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
ULONG buf_len
Definition: nfs41_driver.c:183
BOOLEAN remove
Definition: nfs41_driver.c:230
KEVENT cond
Definition: nfs41_driver.c:174
BOOLEAN ReturnSingleEntry
Definition: nfs41_driver.c:253
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::@817::@829 Volume
BOOLEAN return_single
Definition: nfs41_driver.c:237
PUNICODE_STRING target
Definition: nfs41_driver.c:257
PUNICODE_STRING filter
Definition: nfs41_driver.c:234
struct _updowncall_entry::@817::@822 Open
PFILE_FS_ATTRIBUTE_INFORMATION FsAttrs
Definition: nfs41_driver.c:189
struct _updowncall_entry::@817::@828 Symlink
BOOLEAN initial_query
Definition: nfs41_driver.c:238
struct _updowncall_entry::@817::@819 ReadWrite
struct _updowncall_entry::@817::@823 Close
struct _updowncall_entry::@817::@824 QueryFile
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
LONG open_owner_id
Definition: nfs41_driver.c:220
LONGLONG length
Definition: nfs41_driver.c:202
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
struct _updowncall_entry::@817::@825 SetFile
ULONGLONG ChangeTime
Definition: nfs41_driver.c:184
BOOLEAN exclusive
Definition: nfs41_driver.c:203
BOOLEAN RestartScan
Definition: nfs41_driver.c:254
struct _updowncall_entry::@817::@826 SetEa
BOOLEAN symlink_embedded
Definition: nfs41_driver.c:224
FILE_INFORMATION_CLASS InfoClass
Definition: nfs41_driver.c:235
PMDL MdlAddress
Definition: nfs41_driver.c:196
struct _updowncall_entry::@817::@820 Lock
struct _updowncall_entry::@817::@827 QueryEa
BOOLEAN set
Definition: nfs41_driver.c:258
ULONG EaListLength
Definition: nfs41_driver.c:250
struct _updowncall_entry::@817::@830 Acl
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
struct _updowncall_entry::@817::@821 Unlock
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
union _updowncall_entry::@817 u
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
BOOLEAN async_op
Definition: nfs41_driver.c:176
struct _updowncall_entry::@817::@818 Mount
HANDLE session
Definition: nfs41_driver.c:180
DWORD lease_time
Definition: nfs41_driver.c:193
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
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383
_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
static UINT WPARAM LPARAM BOOL ansi
Definition: misc.c:135
#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
#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:7214
#define IsReparseTagValid(tag)
Definition: iotypes.h:7226
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:7241
#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:304
#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