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 
25 #include "nfs41_driver.h"
26 #include "nfs41_debug.h"
27 #include <stdio.h>
28 #include <stdarg.h>
29 #include <ntstrsafe.h>
30 #include <winerror.h>
31 
32 #if defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_WIN7)
33 NTSTATUS NTAPI RtlUnicodeToUTF8N(CHAR *utf8_dest, ULONG utf8_bytes_max,
34                                  ULONG *utf8_bytes_written,
35                                  const WCHAR *uni_src, ULONG uni_bytes);
36 NTSTATUS NTAPI RtlUTF8ToUnicodeN(WCHAR *uni_dest, ULONG uni_bytes_max,
37                                  ULONG *uni_bytes_written,
38                                  const CHAR *utf8_src, ULONG utf8_bytes);
39 #endif /* defined(__REACTOS__) && (NTDDI_VERSION < NTDDI_WIN7) */
40 
41 //#define INCLUDE_TIMESTAMPS
42 
43 ULONG __cdecl DbgP(IN PCCH fmt, ...)
44 {
45     CHAR msg[512];
46     va_list args;
47     NTSTATUS status;
48 
49     va_start(args, fmt);
50     ASSERT(fmt != NULL);
51     status = RtlStringCbVPrintfA(msg, sizeof(msg), fmt, args);
52     if (NT_SUCCESS(status)) {
53 #ifdef INCLUDE_TIMESTAMPS
54         LARGE_INTEGER timestamp, local_time;
55         TIME_FIELDS time_fields;
56 
57         KeQuerySystemTime(&timestamp);
58         ExSystemTimeToLocalTime(&timestamp,&local_time);
59         RtlTimeToTimeFields(&local_time, &time_fields);
60 
61         DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
62             "[%ld].[%02u:%02u:%02u.%u] %s", IoGetCurrentProcess(),
63             time_fields.Hour, time_fields.Minute, time_fields.Second,
64             time_fields.Milliseconds, msg);
65 #else
66         DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
67             "[%04x] %s", PsGetCurrentProcessId(), msg);
68 #endif
69     }
70     va_end(args);
71 
72     return 0;
73 }
74 
75 ULONG __cdecl print_error(IN PCCH fmt, ...)
76 {
77     CHAR msg[512];
78     va_list args;
79     NTSTATUS status;
80 
81     va_start(args, fmt);
82     ASSERT(fmt != NULL);
83     status = RtlStringCbVPrintfA(msg, sizeof(msg), fmt, args);
84     if (NT_SUCCESS(status)) {
85 #ifdef INCLUDE_TIMESTAMPS
86         LARGE_INTEGER timestamp, local_time;
87         TIME_FIELDS time_fields;
88 
89         KeQuerySystemTime(&timestamp);
90         ExSystemTimeToLocalTime(&timestamp,&local_time);
91         RtlTimeToTimeFields(&local_time, &time_fields);
92 
93         DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
94             "[%ld].[%02u:%02u:%02u.%u] %s", IoGetCurrentProcess(),
95             time_fields.Hour, time_fields.Minute, time_fields.Second,
96             time_fields.Milliseconds, msg);
97 #else
98         DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
99             "[%04x] %s", PsGetCurrentProcessId(), msg);
100 #endif
101     }
102     va_end(args);
103 
104     return 0;
105 }
106 
107 void print_hexbuf(int on, unsigned char *title, unsigned char *buf, int len)
108 {
109     int j, k;
110     LARGE_INTEGER timestamp, local_time;
111     TIME_FIELDS time_fields;
112 
113     if (!on) return;
114 
115     KeQuerySystemTime(&timestamp);
116     ExSystemTimeToLocalTime(&timestamp,&local_time);
117     RtlTimeToTimeFields(&local_time, &time_fields);
118 
119     DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
120         "[%ld].[%02u:%02u:%02u.%u] %s\n", IoGetCurrentProcess(),
121         time_fields.Hour, time_fields.Minute, time_fields.Second,
122         time_fields.Milliseconds, title);
123     for(j = 0, k = 0; j < len; j++, k++) {
124         DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL,
125             "%02x ", buf[j]);
126         if (((k+1) % 30 == 0 && k > 0))
127             DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "\n");
128     }
129     DbgPrintEx(DPFLTR_IHVNETWORK_ID, DPFLTR_ERROR_LEVEL, "\n");
130 }
131 
132 void print_ioctl(int on, int op)
133 {
134     if(!on) return;
135     switch(op) {
136         case IRP_MJ_FILE_SYSTEM_CONTROL:
137             DbgP("IRP_MJ_FILE_SYSTEM_CONTROL\n");
138             break;
139         case IRP_MJ_DEVICE_CONTROL:
140             DbgP("IRP_MJ_DEVICE_CONTROL\n");
141             break;
142         case IRP_MJ_INTERNAL_DEVICE_CONTROL:
143             DbgP("IRP_MJ_INTERNAL_DEVICE_CONTROL\n");
144             break;
145         default:
146             DbgP("UNKNOWN MJ IRP %d\n", op);
147     };
148 }
149 
150 void print_fs_ioctl(int on, int op)
151 {
152     if(!on) return;
153     switch(op) {
154         case IOCTL_NFS41_INVALCACHE:
155             DbgP("IOCTL_NFS41_INVALCACHE\n");
156             break;
157         case IOCTL_NFS41_READ:
158             DbgP("IOCTL_NFS41_UPCALL\n");
159             break;
160         case IOCTL_NFS41_WRITE:
161             DbgP("IOCTL_NFS41_DOWNCALL\n");
162             break;
163         case IOCTL_NFS41_ADDCONN:
164             DbgP("IOCTL_NFS41_ADDCONN\n");
165             break;
166         case IOCTL_NFS41_DELCONN:
167             DbgP("IOCTL_NFS41_DELCONN\n");
168             break;
169         case IOCTL_NFS41_GETSTATE:
170             DbgP("IOCTL_NFS41_GETSTATE\n");
171             break;
172         case IOCTL_NFS41_START:
173             DbgP("IOCTL_NFS41_START\n");
174             break;
175         case IOCTL_NFS41_STOP:
176             DbgP("IOCTL_NFS41_STOP\n");
177             break;
178         default:
179             DbgP("UNKNOWN FS IOCTL %d\n", op);
180     };
181 }
182 
183 void print_driver_state(int state)
184 {
185     switch (state) {
186         case NFS41_START_DRIVER_STARTABLE:
187             DbgP("NFS41_START_DRIVER_STARTABLE\n");
188             break;
189         case NFS41_START_DRIVER_STOPPED:
190             DbgP("NFS41_START_DRIVER_STOPPED\n");
191             break;
192         case NFS41_START_DRIVER_START_IN_PROGRESS:
193             DbgP("NFS41_START_DRIVER_START_IN_PROGRESS\n");
194             break;
195         case NFS41_START_DRIVER_STARTED:
196             DbgP("NFS41_START_DRIVER_STARTED\n");
197             break;
198         default:
199             DbgP("UNKNOWN DRIVER STATE %d\n", state);
200     };
201 
202 }
203 
204 void print_basic_info(int on, PFILE_BASIC_INFORMATION info)
205 {
206     if (!on) return;
207     DbgP("BASIC_INFO: Create=%lx Access=%lx Write=%lx Change=%lx Attr=%x\n",
208         info->CreationTime.QuadPart, info->LastAccessTime.QuadPart,
209         info->LastWriteTime.QuadPart, info->ChangeTime.QuadPart,
210         info->FileAttributes);
211 }
212 void print_std_info(int on, PFILE_STANDARD_INFORMATION info)
213 {
214     if (!on) return;
215     DbgP("STD_INFO: Type=%s #Links=%d Alloc=%lx EOF=%lx Delete=%d\n",
216         info->Directory?"DIR":"FILE", info->NumberOfLinks,
217         info->AllocationSize.QuadPart, info->EndOfFile.QuadPart,
218         info->DeletePending);
219 }
220 
221 void print_ea_info(int on, PFILE_FULL_EA_INFORMATION info)
222 {
223     if (!on) return;
224     DbgP("FULL_EA_INFO: NextOffset=%d Flags=%x EaNameLength=%d "
225         "ExValueLength=%x EaName=%s\n", info->NextEntryOffset, info->Flags,
226         info->EaNameLength, info->EaValueLength, info->EaName);
227     if (info->EaValueLength)
228         print_hexbuf(0, (unsigned char *)"eavalue",
229             (unsigned char *)info->EaName + info->EaNameLength + 1,
230             info->EaValueLength);
231 }
232 
233 void print_get_ea(int on, PFILE_GET_EA_INFORMATION info)
234 {
235     if (!on || !info) return;
236     DbgP("GET_EA_INFO: NextOffset=%d EaNameLength=%d EaName=%s\n",
237         info->NextEntryOffset, info->EaNameLength, info->EaName);
238 }
239 
240 VOID print_srv_call(int on, IN PMRX_SRV_CALL p)
241 {
242     if (!on) return;
243     DbgP("PMRX_SRV_CALL %p\n", p);
244 #if 0
245     DbgP("\tNodeReferenceCount %ld\n", p->NodeReferenceCount);
246     //DbgP("Context %p\n", p->Context);
247     //DbgP("Context2 %p\n", p->Context2);
248     //DbgP("pSrvCallName %wZ\n", p->pSrvCallName);
249     //DbgP("pPrincipalName %wZ\n", p->pPrincipalName);
250     //DbgP("PDomainName %wZ\n", p->pDomainName);
251     //DbgP("Flags %08lx\n", p->Flags);
252     //DbgP("MaximumNumberOfCloseDelayedFiles %ld\n", p->MaximumNumberOfCloseDelayedFiles);
253     //DbgP("Status %ld\n", p->Status);
254     DbgP("*****************\n");
255 #endif
256 }
257 
258 VOID print_net_root(int on, IN PMRX_NET_ROOT p)
259 {
260     if (!on) return;
261     DbgP("PMRX_NET_ROOT %p\n", p);
262 #if 0
263     DbgP("\tNodeReferenceCount %ld\n", p->NodeReferenceCount);
264     DbgP("\tpSrvCall %p\n", p->pSrvCall);
265     //DbgP("Context %p\n", p->Context);
266     //DbgP("Context2 %p\n", p->Context2);
267     //DbgP("Flags %08lx\n", p->Flags);
268     DbgP("\tNumberOfFcbs %ld\n", p->NumberOfFcbs);
269     DbgP("\tNumberofSrvOpens %ld\n", p->NumberOfSrvOpens);
270     //DbgP("MRxNetRootState %ld\n", p->MRxNetRootState);
271     //DbgP("Type %ld\n", p->Type);
272     //DbgP("DeviceType %ld\n", p->DeviceType);
273     //DbgP("pNetRootName %wZ\n", p->pNetRootName);
274     //DbgP("InnerNamePrefix %wZ\n", &p->InnerNamePrefix);
275     DbgP("*****************\n");
276 #endif
277 }
278 
279 VOID print_v_net_root(int on, IN PMRX_V_NET_ROOT p)
280 {
281     if (!on) return;
282     DbgP("PMRX_V_NET_ROOT %p\n", p);
283 #if 0
284     DbgP("\tNodeReferenceCount %ld\n", p->NodeReferenceCount);
285     DbgP("\tpNetRoot %p\n", p->pNetRoot);
286     //DbgP("Context %p\n", p->Context);
287     //DbgP("Context2 %p\n", p->Context2);
288     //DbgP("Flags %08lx\n", p->Flags);
289     DbgP("\tNumberofOpens %ld\n", p->NumberOfOpens);
290     DbgP("\tNumberofFobxs %ld\n", p->NumberOfFobxs);
291     //DbgP("LogonId\n");
292     //DbgP("pUserDomainName %wZ\n", p->pUserDomainName);
293     //DbgP("pUserName %wZ\n", p->pUserName);
294     //DbgP("pPassword %wZ\n", p->pPassword);
295     //DbgP("SessionId %ld\n", p->SessionId);
296     //DbgP("ConstructionStatus %08lx\n", p->ConstructionStatus);
297     //DbgP("IsExplicitConnection %d\n", p->IsExplicitConnection);
298     DbgP("*****************\n");
299 #endif
300 }
301 
302 void print_file_object(int on, PFILE_OBJECT file)
303 {
304     if (!on) return;
305     DbgP("FsContext %p FsContext2 %p\n", file->FsContext, file->FsContext2);
306     DbgP("DeletePending %d ReadAccess %d WriteAccess %d DeleteAccess %d\n",
307         file->DeletePending, file->WriteAccess, file->DeleteAccess);
308     DbgP("SharedRead %d SharedWrite %d SharedDelete %d Flags %x\n",
309         file->SharedRead, file->SharedWrite, file->SharedDelete, file->Flags);
310 }
311 
312 void print_fo_all(int on, PRX_CONTEXT c)
313 {
314     if (!on) return;
315     if (c->pFcb && c->pRelevantSrvOpen)
316         DbgP("OpenCount %d FCB %p SRV %p FOBX %p VNET %p NET %p\n",
317             c->pFcb->OpenCount, c->pFcb, c->pRelevantSrvOpen, c->pFobx,
318             c->pRelevantSrvOpen->pVNetRoot, c->pFcb->pNetRoot);
319 }
320 
321 VOID print_fcb(int on, IN PMRX_FCB p)
322 {
323     if (!on) return;
324     DbgP("PMRX_FCB %p OpenCount %d\n", p, p->OpenCount);
325 #if 0
326     DbgP("\tNodeReferenceCount %ld\n", p->NodeReferenceCount);
327     DbgP("\tpNetRoot %p\n", p->pNetRoot);
328     //DbgP("Context %p\n", p->Context);
329     //DbgP("Context2 %p\n", p->Context2);
330     //DbgP("FcbState %ld\n", p->FcbState);
331     //DbgP("UncleanCount %ld\n", p->UncleanCount);
332     //DbgP("UncachedUncleanCount %ld\n", p->UncachedUncleanCount);
333     DbgP("\tOpenCount %ld\n", p->OpenCount);
334     //DbgP("OutstandingLockOperationsCount %ld\n", p->OutstandingLockOperationsCount);
335     //DbgP("ActualAllocationLength %ull\n", p->ActualAllocationLength);
336     //DbgP("Attributes %ld\n", p->Attributes);
337     //DbgP("IsFileWritten %d\n", p->IsFileWritten);
338     //DbgP("fShouldBeOrphaned %d\n", p->fShouldBeOrphaned);
339     //DbgP("fMiniInited %ld\n", p->fMiniInited);
340     //DbgP("CachedNetRootType %c\n", p->CachedNetRootType);
341     //DbgP("SrvOpenList\n");
342     //DbgP("SrvOpenListVersion %ld\n", p->SrvOpenListVersion);
343     DbgP("*****************\n");
344 #endif
345 }
346 
347 VOID print_srv_open(int on, IN PMRX_SRV_OPEN p)
348 {
349     if (!on) return;
350     DbgP("PMRX_SRV_OPEN %p\n", p);
351 #if 0
352     DbgP("\tNodeReferenceCount %ld\n", p->NodeReferenceCount);
353     DbgP("\tpFcb %p\n", p->pFcb);
354     DbgP("\tpVNetRoot %p\n", p->pVNetRoot);
355     //DbgP("Context %p\n", p->Context);
356     //DbgP("Context2 %p\n", p->Context2);
357     //DbgP("Flags %08lx\n", p->Flags);
358     //DbgP("pAlreadyPrefixedName %wZ\n", p->pAlreadyPrefixedName);
359     //DbgP("UncleanFobxCount %ld\n", p->UncleanFobxCount);
360     DbgP("\tOpenCount %ld\n", p->OpenCount);
361     //DbgP("Key %p\n", p->Key);
362     //DbgP("DesiredAccess\n");
363     //DbgP("ShareAccess %ld\n", p->ShareAccess);
364     //DbgP("CreateOptions %ld\n", p->CreateOptions);
365     //DbgP("BufferingFlags %ld\n", p->BufferingFlags);
366     //DbgP("ulFileSizeVersion %ld\n", p->ulFileSizeVersion);
367     //DbgP("SrvOpenQLinks\n");
368     DbgP("*****************\n");
369 #endif
370 }
371 
372 VOID print_fobx(int on, IN PMRX_FOBX p)
373 {
374     if (!on) return;
375     DbgP("PMRX_FOBX %p\n", p);
376 #if 0
377     DbgP("\tNodeReferenceCount %ld\n", p->NodeReferenceCount);
378     DbgP("\tpSrvOpen %p\n", p->pSrvOpen);
379     DbgP("\tAssociatedFileObject %p\n", p->AssociatedFileObject);
380     //DbgP("Context %p\n", p->Context);
381     //DbgP("Context2 %p\n", p->Context2);
382     //DbgP("Flags %08lx\n", p->Flags);
383     DbgP("*****************\n");
384 #endif
385 }
386 
387 VOID print_irp_flags(int on, PIRP irp)
388 {
389     if (!on) return;
390     if (irp->Flags)
391         DbgP("IRP FLAGS: 0x%x %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
392             irp->Flags,
393             (irp->Flags & IRP_NOCACHE)?"NOCACHE":"",
394             (irp->Flags & IRP_PAGING_IO)?"PAGING_IO":"",
395             (irp->Flags & IRP_MOUNT_COMPLETION)?"MOUNT":"",
396             (irp->Flags & IRP_SYNCHRONOUS_API)?"SYNC":"",
397             (irp->Flags & IRP_ASSOCIATED_IRP)?"ASSOC_IPR":"",
398             (irp->Flags & IRP_BUFFERED_IO)?"BUFFERED":"",
399             (irp->Flags & IRP_DEALLOCATE_BUFFER)?"DEALLOC_BUF":"",
400             (irp->Flags & IRP_INPUT_OPERATION)?"INPUT_OP":"",
401             (irp->Flags & IRP_SYNCHRONOUS_PAGING_IO)?"SYNC_PAGIN_IO":"",
402             (irp->Flags & IRP_CREATE_OPERATION)?"CREATE_OP":"",
403             (irp->Flags & IRP_READ_OPERATION)?"READ_OP":"",
404             (irp->Flags & IRP_WRITE_OPERATION)?"WRITE_OP":"",
405             (irp->Flags & IRP_CLOSE_OPERATION)?"CLOSE_OP":"",
406             (irp->Flags & IRP_DEFER_IO_COMPLETION)?"DEFER_IO":"");
407 }
408 
409 void print_irps_flags(int on, PIO_STACK_LOCATION irps)
410 {
411     if (!on) return;
412     if (irps->Flags)
413         DbgP("IRPSP FLAGS 0x%x %s %s %s %s\n", irps->Flags,
414             (irps->Flags & SL_CASE_SENSITIVE)?"CASE_SENSITIVE":"",
415             (irps->Flags & SL_OPEN_PAGING_FILE)?"PAGING_FILE":"",
416             (irps->Flags & SL_FORCE_ACCESS_CHECK)?"ACCESS_CHECK":"",
417             (irps->Flags & SL_OPEN_TARGET_DIRECTORY)?"TARGET_DIR":"");
418 }
419 void print_nt_create_params(int on, NT_CREATE_PARAMETERS params)
420 {
421     if (!on) return;
422     if (params.FileAttributes)
423         DbgP("File attributes %x: %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
424             params.FileAttributes,
425             (params.FileAttributes & FILE_ATTRIBUTE_TEMPORARY)?"TEMPFILE ":"",
426             (params.FileAttributes & FILE_ATTRIBUTE_READONLY)?"READONLY ":"",
427             (params.FileAttributes & FILE_ATTRIBUTE_HIDDEN)?"HIDDEN ":"",
428             (params.FileAttributes & FILE_ATTRIBUTE_SYSTEM)?"SYSTEM ":"",
429             (params.FileAttributes & FILE_ATTRIBUTE_ARCHIVE)?"ARCHIVE ":"",
430             (params.FileAttributes & FILE_ATTRIBUTE_DIRECTORY)?"DIR ":"",
431             (params.FileAttributes & FILE_ATTRIBUTE_DEVICE)?"DEVICE ":"",
432             (params.FileAttributes & FILE_ATTRIBUTE_NORMAL)?"NORMAL ":"",
433             (params.FileAttributes & FILE_ATTRIBUTE_SPARSE_FILE)?"SPARSE_FILE ":"",
434             (params.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)?"REPARSE_POINT ":"",
435             (params.FileAttributes & FILE_ATTRIBUTE_COMPRESSED)?"COMPRESSED ":"",
436             (params.FileAttributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED)?"NOT INDEXED ":"",
437             (params.FileAttributes & FILE_ATTRIBUTE_ENCRYPTED)?"ENCRYPTED ":"",
438             (params.FileAttributes & FILE_ATTRIBUTE_VIRTUAL)?"VIRTUAL":"");
439 
440     if (params.Disposition  == FILE_SUPERSEDE)
441         DbgP("Create Dispositions: FILE_SUPERSEDE\n");
442     if (params.Disposition == FILE_CREATE)
443         DbgP("Create Dispositions: FILE_CREATE\n");
444     if (params.Disposition == FILE_OPEN)
445         DbgP("Create Dispositions: FILE_OPEN\n");
446     if (params.Disposition == FILE_OPEN_IF)
447         DbgP("Create Dispositions: FILE_OPEN_IF\n");
448     if (params.Disposition == FILE_OVERWRITE)
449         DbgP("Create Dispositions: FILE_OVERWRITE\n");
450     if (params.Disposition == FILE_OVERWRITE_IF)
451         DbgP("Create Dispositions: FILE_OVERWRITE_IF\n");
452 
453     DbgP("Create Attributes: 0x%x %s %s %s %s %s %s %s %s %s %s %s %s %s %s "
454         "%s %s\n", params.CreateOptions,
455         (params.CreateOptions & FILE_DIRECTORY_FILE)?"DIRFILE":"",
456         (params.CreateOptions & FILE_NON_DIRECTORY_FILE)?"FILE":"",
457         (params.CreateOptions & FILE_DELETE_ON_CLOSE)?"DELETE_ON_CLOSE":"",
458         (params.CreateOptions & FILE_WRITE_THROUGH)?"WRITE_THROUGH":"",
459         (params.CreateOptions & FILE_SEQUENTIAL_ONLY)?"SEQUENTIAL":"",
460         (params.CreateOptions & FILE_RANDOM_ACCESS)?"RANDOM":"",
461         (params.CreateOptions & FILE_NO_INTERMEDIATE_BUFFERING)?"NO_BUFFERING":"",
462         (params.CreateOptions & FILE_SYNCHRONOUS_IO_ALERT)?"SYNC_ALERT":"",
463         (params.CreateOptions & FILE_SYNCHRONOUS_IO_NONALERT)?"SYNC_NOALERT":"",
464         (params.CreateOptions & FILE_CREATE_TREE_CONNECTION)?"CREATE_TREE_CONN":"",
465         (params.CreateOptions & FILE_COMPLETE_IF_OPLOCKED)?"OPLOCKED":"",
466         (params.CreateOptions & FILE_NO_EA_KNOWLEDGE)?"NO_EA":"",
467         (params.CreateOptions & FILE_OPEN_REPARSE_POINT)?"OPEN_REPARSE":"",
468         (params.CreateOptions & FILE_OPEN_BY_FILE_ID)?"BY_ID":"",
469         (params.CreateOptions & FILE_OPEN_FOR_BACKUP_INTENT)?"4_BACKUP":"",
470         (params.CreateOptions & FILE_RESERVE_OPFILTER)?"OPFILTER":"");
471 
472     DbgP("Share Access: %s %s %s\n",
473         (params.ShareAccess & FILE_SHARE_READ)?"READ":"",
474         (params.ShareAccess & FILE_SHARE_WRITE)?"WRITE":"",
475         (params.ShareAccess & FILE_SHARE_DELETE)?"DELETE":"");
476 
477     DbgP("Desired Access: 0x%x %s %s %s %s %s %s %s %s %s %s %s\n",
478         params.DesiredAccess,
479         (params.DesiredAccess & FILE_READ_DATA)?"READ":"",
480         (params.DesiredAccess & STANDARD_RIGHTS_READ)?"READ_ACL":"",
481         (params.DesiredAccess & FILE_READ_ATTRIBUTES)?"GETATTR":"",
482         (params.DesiredAccess & FILE_READ_EA)?"READ_EA":"",
483         (params.DesiredAccess & FILE_WRITE_DATA)?"WRITE":"",
484         (params.DesiredAccess & FILE_WRITE_ATTRIBUTES)?"SETATTR":"",
485         (params.DesiredAccess & FILE_WRITE_EA)?"WRITE_EA":"",
486         (params.DesiredAccess & FILE_APPEND_DATA)?"APPEND":"",
487         (params.DesiredAccess & FILE_EXECUTE)?"EXEC":"",
488         (params.DesiredAccess & FILE_LIST_DIRECTORY)?"LSDIR":"",
489         (params.DesiredAccess & FILE_TRAVERSE)?"TRAVERSE":"",
490         (params.DesiredAccess & FILE_LIST_DIRECTORY)?"LSDIR":"",
491         (params.DesiredAccess & DELETE)?"DELETE":"",
492         (params.DesiredAccess & READ_CONTROL)?"READ_CONTROL":"",
493         (params.DesiredAccess & WRITE_DAC)?"WRITE_DAC":"",
494         (params.DesiredAccess & WRITE_OWNER)?"WRITE_OWNER":"",
495         (params.DesiredAccess & SYNCHRONIZE)?"SYNCHRONIZE":"");
496 }
497 
498 unsigned char * print_file_information_class(int InfoClass)
499 {
500     switch(InfoClass) {
501         case FileBothDirectoryInformation:
502             return (unsigned char *)"FileBothDirectoryInformation";
503         case FileDirectoryInformation:
504             return (unsigned char *)"FileDirectoryInformation";
505         case FileFullDirectoryInformation:
506             return (unsigned char *)"FileFullDirectoryInformation";
507         case FileIdBothDirectoryInformation:
508             return (unsigned char *)"FileIdBothDirectoryInformation";
509         case FileIdFullDirectoryInformation:
510             return (unsigned char *)"FileIdFullDirectoryInformation";
511         case FileNamesInformation:
512             return (unsigned char *)"FileNamesInformation";
513         case FileObjectIdInformation:
514             return (unsigned char *)"FileObjectIdInformation";
515         case FileQuotaInformation:
516             return (unsigned char *)"FileQuotaInformation";
517         case FileReparsePointInformation:
518             return (unsigned char *)"FileReparsePointInformation";
519         case FileAllInformation:
520             return (unsigned char *)"FileAllInformation";
521         case FileAttributeTagInformation:
522             return (unsigned char *)"FileAttributeTagInformation";
523         case FileBasicInformation:
524             return (unsigned char *)"FileBasicInformation";
525         case FileCompressionInformation:
526             return (unsigned char *)"FileCompressionInformation";
527         case FileEaInformation:
528             return (unsigned char *)"FileEaInformation";
529         case FileInternalInformation:
530             return (unsigned char *)"FileInternalInformation";
531         case FileNameInformation:
532             return (unsigned char *)"FileNameInformation";
533         case FileNetworkOpenInformation:
534             return (unsigned char *)"FileNetworkOpenInformation";
535         case FilePositionInformation:
536             return (unsigned char *)"FilePositionInformation";
537         case FileStandardInformation:
538             return (unsigned char *)"FileStandardInformation";
539         case FileStreamInformation:
540             return (unsigned char *)"FileStreamInformation";
541         case FileAllocationInformation:
542             return (unsigned char *)"FileAllocationInformation";
543         case FileDispositionInformation:
544             return (unsigned char *)"FileDispositionInformation";
545         case FileEndOfFileInformation:
546             return (unsigned char *)"FileEndOfFileInformation";
547         case FileLinkInformation:
548             return (unsigned char *)"FileLinkInformation";
549         case FileRenameInformation:
550             return (unsigned char *)"FileRenameInformation";
551         case FileValidDataLengthInformation:
552             return (unsigned char *)"FileValidDataLengthInformation";
553         default:
554             return (unsigned char *)"UNKNOWN";
555     }
556 }
557 
558 unsigned char *print_fs_information_class(int InfoClass)
559 {
560     switch (InfoClass) {
561         case FileFsAttributeInformation:
562             return (unsigned char *)"FileFsAttributeInformation";
563         case FileFsControlInformation:
564             return (unsigned char *)"FileFsControlInformation";
565         case FileFsDeviceInformation:
566             return (unsigned char *)"FileFsDeviceInformation";
567         case FileFsDriverPathInformation:
568             return (unsigned char *)"FileFsDriverPathInformation";
569         case FileFsFullSizeInformation:
570             return (unsigned char *)"FileFsFullSizeInformation";
571         case FileFsObjectIdInformation:
572             return (unsigned char *)"FileFsObjectIdInformation";
573         case FileFsSizeInformation:
574             return (unsigned char *)"FileFsSizeInformation";
575         case FileFsVolumeInformation:
576             return (unsigned char *)"FileFsVolumeInformation";
577         default:
578             return (unsigned char *)"UNKNOWN";
579     }
580 }
581 
582 void print_caching_level(int on, ULONG flag, PUNICODE_STRING name)
583 {
584     if (!on) return;
585     switch(flag) {
586         case 0:
587             DbgP("enable_caching: DISABLE_CACHING %wZ\n", name);
588             break;
589         case 1:
590             DbgP("enable_caching: ENABLE_READ_CACHING %wZ\n", name);
591             break;
592         case 2:
593             DbgP("enable_caching: ENABLE_WRITE_CACHING %wZ\n", name);
594             break;
595         case 3:
596             DbgP("enable_caching: ENABLE_READWRITE_CACHING %wZ\n", name);
597             break;
598     }
599 }
600 
601 const char *opcode2string(int opcode)
602 {
603     switch(opcode) {
604     case NFS41_SHUTDOWN: return "NFS41_SHUTDOWN";
605     case NFS41_MOUNT: return "NFS41_MOUNT";
606     case NFS41_UNMOUNT: return "NFS41_UNMOUNT";
607     case NFS41_OPEN: return "NFS41_OPEN";
608     case NFS41_CLOSE: return "NFS41_CLOSE";
609     case NFS41_READ: return "NFS41_READ";
610     case NFS41_WRITE: return "NFS41_WRITE";
611     case NFS41_LOCK: return "NFS41_LOCK";
612     case NFS41_UNLOCK: return "NFS41_UNLOCK";
613     case NFS41_DIR_QUERY: return "NFS41_DIR_QUERY";
614     case NFS41_FILE_QUERY: return "NFS41_FILE_QUERY";
615     case NFS41_FILE_SET: return "NFS41_FILE_SET";
616     case NFS41_EA_SET: return "NFS41_EA_SET";
617     case NFS41_EA_GET: return "NFS41_EA_GET";
618     case NFS41_SYMLINK: return "NFS41_SYMLINK";
619     case NFS41_VOLUME_QUERY: return "NFS41_VOLUME_QUERY";
620     case NFS41_ACL_QUERY: return "NFS41_ACL_QUERY";
621     case NFS41_ACL_SET: return "NFS41_ACL_SET";
622     default: return "UNKNOWN";
623     }
624 }
625 
626 void print_acl_args(
627     SECURITY_INFORMATION info)
628 {
629     DbgP("Security query: %s %s %s\n",
630         (info & OWNER_SECURITY_INFORMATION)?"OWNER":"",
631         (info & GROUP_SECURITY_INFORMATION)?"GROUP":"",
632         (info & DACL_SECURITY_INFORMATION)?"DACL":"",
633         (info & SACL_SECURITY_INFORMATION)?"SACL":"");
634 }
635 
636 void print_open_error(int on, int status)
637 {
638     if (!on) return;
639     switch (status) {
640     case STATUS_ACCESS_DENIED:
641         DbgP("[ERROR] nfs41_Create: STATUS_ACCESS_DENIED\n");
642         break;
643     case STATUS_NETWORK_ACCESS_DENIED:
644         DbgP("[ERROR] nfs41_Create: STATUS_NETWORK_ACCESS_DENIED\n");
645         break;
646     case STATUS_OBJECT_NAME_INVALID:
647         DbgP("[ERROR] nfs41_Create: STATUS_OBJECT_NAME_INVALID\n");
648         break;
649     case STATUS_OBJECT_NAME_COLLISION:
650         DbgP("[ERROR] nfs41_Create: STATUS_OBJECT_NAME_COLLISION\n");
651         break;
652     case STATUS_FILE_INVALID:
653         DbgP("[ERROR] nfs41_Create: STATUS_FILE_INVALID\n");
654         break;
655     case STATUS_OBJECT_NAME_NOT_FOUND:
656         DbgP("[ERROR] nfs41_Create: STATUS_OBJECT_NAME_NOT_FOUND\n");
657         break;
658     case STATUS_NAME_TOO_LONG:
659         DbgP("[ERROR] nfs41_Create: STATUS_NAME_TOO_LONG\n");
660         break;
661     case STATUS_OBJECT_PATH_NOT_FOUND:
662         DbgP("[ERROR] nfs41_Create: STATUS_OBJECT_PATH_NOT_FOUND\n");
663         break;
664     case STATUS_BAD_NETWORK_PATH:
665         DbgP("[ERROR] nfs41_Create: STATUS_BAD_NETWORK_PATH\n");
666         break;
667     case STATUS_SHARING_VIOLATION:
668         DbgP("[ERROR] nfs41_Create: STATUS_SHARING_VIOLATION\n");
669         break;
670     case ERROR_REPARSE:
671         DbgP("[ERROR] nfs41_Create: STATUS_REPARSE\n");
672         break;
673     case ERROR_TOO_MANY_LINKS:
674         DbgP("[ERROR] nfs41_Create: STATUS_TOO_MANY_LINKS\n");
675         break;
676     case ERROR_DIRECTORY:
677         DbgP("[ERROR] nfs41_Create: STATUS_FILE_IS_A_DIRECTORY\n");
678         break;
679     case ERROR_BAD_FILE_TYPE:
680         DbgP("[ERROR] nfs41_Create: STATUS_NOT_A_DIRECTORY\n");
681         break;
682     default:
683         DbgP("[ERROR] nfs41_Create: STATUS_INSUFFICIENT_RESOURCES\n");
684         break;
685     }
686 }
687 
688 void print_wait_status(int on, const char *prefix, NTSTATUS status,
689                        const char *opcode, PVOID entry, LONGLONG xid)
690 {
691     if (!on) return;
692     switch (status) {
693     case STATUS_SUCCESS:
694         if (opcode)
695             DbgP("%s Got a wakeup call, finishing %s entry=%p xid=%lld\n",
696                 prefix, opcode, entry, xid);
697         else
698             DbgP("%s Got a wakeup call\n", prefix);
699         break;
700     case STATUS_USER_APC:
701         DbgP("%s KeWaitForSingleObject returned STATUS_USER_APC\n", prefix);
702         break;
703     case STATUS_ALERTED:
704         DbgP("%s KeWaitForSingleObject returned STATUS_ALERTED\n", prefix);
705         break;
706     default:
707         DbgP("%s KeWaitForSingleObject returned %d\n", prefix, status);
708     }
709 }
710 /* This is taken from toaster/func.  Rumor says this should be replaced
711  * with a WMI interface???
712  */
713 ULONG
714 dprintk(
715     IN PCHAR func,
716     IN ULONG flags,
717     IN PCHAR format,
718     ...)
719 {
720     #define     TEMP_BUFFER_SIZE        1024
721     va_list    list;
722     CHAR      debugMessageBuffer[TEMP_BUFFER_SIZE];
723     NTSTATUS status, rv = STATUS_SUCCESS;
724 
725     va_start(list, format);
726 
727     if (format)
728     {
729         //
730         // Use the safe string function, RtlStringCbVPrintfA, instead of _vsnprintf.
731         // RtlStringCbVPrintfA NULL terminates the output buffer even if the message
732         // is longer than the buffer. This prevents malicious code from compromising
733         // the security of the system.
734         //
735         status = RtlStringCbVPrintfA(debugMessageBuffer, sizeof(debugMessageBuffer),
736                                     format, list);
737 
738         if (!NT_SUCCESS(status))
739             rv = DbgPrintEx(PNFS_FLTR_ID, DPFLTR_MASK | flags,
740                             "RtlStringCbVPrintfA failed %x \n", status);
741         else
742             rv = DbgPrintEx(PNFS_FLTR_ID, DPFLTR_MASK | flags, "%s    %s: %s\n",
743                     PNFS_TRACE_TAG, func, debugMessageBuffer);
744     }
745     va_end(list);
746 
747     return rv;
748 }
749 
750