WDK Mini Filter Example
ncmapping.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (c) 1999 - 2002 Microsoft Corporation
4 
5 Module Name:
6 
7  ncmapping.c
8 
9 Abstract:
10 
11  This module contains helper routines for manipulating mapping
12  objects.
13 
14 Environment:
15 
16  Kernel mode
17 
18 --*/
19 
20 #include "nc.h"
21 
22 BOOLEAN
24  _In_ PNC_MAPPING_PATH Path
25  );
26 
27 NTSTATUS
29  _In_ PUNICODE_STRING VolumeName,
30  _In_ PUNICODE_STRING ParentPath,
31  _In_ PUNICODE_STRING FinalComponent,
32  _Inout_ PNC_MAPPING_PATH Path
33  );
34 
35 NTSTATUS
37  _In_ PFILE_OBJECT Parent,
38  _In_ PUNICODE_STRING FinalComponent,
39  _In_ PFLT_INSTANCE Instance,
40  _In_ BOOLEAN Normalized,
41  _Inout_ PNC_MAPPING_PATH Path
42  );
43 
44 
45 //
46 // Functions to manage mapping entry
47 //
48 
49 BOOLEAN
51  PNC_MAPPING_ENTRY Entry
52  );
53 
54 VOID
56  _Inout_ PNC_MAPPING_ENTRY Entry
57  );
58 
59 VOID
61  _Inout_ PNC_MAPPING_ENTRY Path
62  );
63 
64 
65 #ifdef ALLOC_PRAGMA
66 #pragma alloc_text(PAGE, NcBuildMappingPath)
67 #pragma alloc_text(PAGE, NcBuildMappingPathFromFile)
68 #pragma alloc_text(PAGE, NcBuildMappingPathFromVolume)
69 #pragma alloc_text(PAGE, NcInitMappingPath)
70 #pragma alloc_text(PAGE, NcIsMappingPathZeroed)
71 #pragma alloc_text(PAGE, NcTeardownMappingPath)
72 #pragma alloc_text(PAGE, NcInitMappingEntry)
73 #pragma alloc_text(PAGE, NcIsMappingEntryZeroed)
74 #pragma alloc_text(PAGE, NcTeardownMappingEntry)
75 #pragma alloc_text(PAGE, NcInitMapping)
76 #pragma alloc_text(PAGE, NcIsMappingZeroed)
77 #pragma alloc_text(PAGE, NcTeardownMapping)
78 #pragma alloc_text(PAGE, NcBuildMapping)
79 #endif
80 
81 //
82 // Functions to manage the mapping path.
83 //
84 
85 BOOLEAN
87  _In_ PNC_MAPPING_PATH Path
88  )
89 {
90  PAGED_CODE();
91 
92  if (Path->FullPath.Buffer != NULL ||
93  Path->FullPath.Length != 0 ||
94  Path->FullPath.MaximumLength != 0) {
95 
96  return FALSE;
97  }
98 
99  if (Path->VolumePath.Buffer != NULL ||
100  Path->VolumePath.Length != 0 ||
101  Path->VolumePath.MaximumLength != 0) {
102 
103  return FALSE;
104  }
105 
106  if (Path->ParentPath.Buffer != NULL ||
107  Path->ParentPath.Length != 0 ||
108  Path->ParentPath.MaximumLength != 0) {
109 
110  return FALSE;
111  }
112 
113  if (Path->FinalComponentName.Buffer != NULL ||
114  Path->FinalComponentName.Length != 0 ||
115  Path->FinalComponentName.MaximumLength != 0) {
116 
117  return FALSE;
118  }
119 
120  if (Path->VolumelessName.Buffer != NULL ||
121  Path->VolumelessName.Length != 0 ||
122  Path->VolumelessName.MaximumLength != 0) {
123 
124  return FALSE;
125  }
126 
127  return TRUE;
128 }
129 
130 VOID
132  _Out_ PNC_MAPPING_PATH Path
133  )
134 /*++
135 
136 Routine Description:
137 
138  Routine to initialize a mapping path.
139 
140 Arguments:
141 
142  Path - Pointer to a user allocated NC_MAPPING_PATH.
143 
144 Return Value:
145 
146  None.
147 
148 --*/
149 {
150  PAGED_CODE();
151  RtlZeroMemory( Path, sizeof( NC_MAPPING_PATH ) );
152 }
153 
154 VOID
156  _Inout_ PNC_MAPPING_PATH Path
157  )
158 /*++
159 
160 Routine Description:
161 
162  Frees the allocations in a NC_MAPPING_PATH.
163 
164 Arguments:
165 
166  Path - The mapping which you want to clean up.
167 
168 Return Value:
169 
170  None.
171 
172 --*/
173 {
174 
175  PAGED_CODE();
176 
177  if (Path->FullPath.Buffer != NULL) {
178 
179  ExFreePoolWithTag( Path->FullPath.Buffer, NC_MAPPING_TAG );
180  }
181 
182  //
183  // All of the strings point at the same buffer allocation.
184  // So once we free the buffer in the FullPath, we just zero out
185  // all of the other strings.
186  //
187 
188  NcInitMappingPath( Path );
189 }
190 
191 NTSTATUS
193  _In_ PUNICODE_STRING VolumeName,
194  _In_ PUNICODE_STRING ParentPath,
195  _In_ PUNICODE_STRING FinalComponent,
196  _Inout_ PNC_MAPPING_PATH Path
197  )
198 /*++
199 
200 Routine Description:
201 
202  Builds a NC_MAPPING_PATH from a collection of Unicode strings.
203 
204 Arguments:
205 
206  VolumeName - Name of the volume.
207 
208  ParentPath - string for the parent of mapping.
209 
210  FinalComponent - The final component of the mapping path.
211 
212  Path - Pointer to a used allocated and zeroed NC_MAPPING_PATH.
213 
214 Return Value:
215 
216  Returns STATUS_SUCCESS on success. Otherwise returns an error code.
217 
218 
219 --*/
220 {
221  NTSTATUS Status = STATUS_SUCCESS;
222  USHORT NameLength;
223  PWCHAR NameBuffer = NULL;
224  UNICODE_STRING NameString;
225  USHORT SeparatorLength;
226  WCHAR ParentEnd;
227  USHORT Index;
228 
229  PAGED_CODE();
230 
232 
233  //
234  // We cannot remap to/from the root of the volume.
235  //
236 
237  FLT_ASSERT( FinalComponent->Length > 0 );
238 
239  //
240  // If the parent path does not end with a '\' then we insert one
241  // between the parent and the final component.
242  //
243 
244  ParentEnd = ParentPath->Buffer[(ParentPath->Length / sizeof(WCHAR)) - 1];
245 
246  if (ParentEnd != NC_SEPARATOR) {
247 
248  SeparatorLength = sizeof(WCHAR);
249  } else {
250 
251  SeparatorLength = 0;
252  }
253 
254  //
255  // Allocate Buffer for Name.
256  //
257 
258  NameLength = VolumeName->Length + ParentPath->Length + SeparatorLength + FinalComponent->Length;
259 
260  NameBuffer = ExAllocatePoolWithTag( PagedPool,
261  NameLength,
262  NC_MAPPING_TAG );
263 
264  if (NameBuffer == NULL) {
265 
266  Status = STATUS_INSUFFICIENT_RESOURCES;
267  goto NcBuildMappingPathCleanup;
268  }
269 
270  //
271  // Create String
272  //
273 
274  NameString.Length = 0;
275  NameString.MaximumLength = NameLength;
276  NameString.Buffer = NameBuffer;
277 
278  //
279  // Copy Volume Name
280  //
281 
282  RtlCopyUnicodeString( &NameString, VolumeName );
283 
284  //
285  // Copy Parent Path
286  //
287 
288  RtlAppendUnicodeStringToString( &NameString,ParentPath );
289 
290  //
291  // Add separator
292  //
293 
294  if (SeparatorLength != 0) {
295 
296  NameString.Buffer[NameString.Length/SeparatorLength] = NC_SEPARATOR;
297  NameString.Length = NameString.Length + SeparatorLength;
298  FLT_ASSERT( NameString.Length <= NameString.MaximumLength );
299  }
300 
301  //
302  // Copy Final Component
303  //
304 
305  RtlAppendUnicodeStringToString( &NameString, FinalComponent );
306 
307  //
308  // Setup Unicode Strings
309  //
310 
311  Path->FullPath.Buffer = NameString.Buffer;
312  Path->FullPath.Length = NameString.Length;
313  Path->FullPath.MaximumLength = NameString.MaximumLength;
314 
315  Path->VolumePath.Buffer = NameString.Buffer;
316  Path->VolumePath.Length = VolumeName->Length;
317  Path->VolumePath.MaximumLength = VolumeName->Length;
318 
319  Path->ParentPath.Buffer = NameString.Buffer;
320  Path->ParentPath.Length = SeparatorLength == sizeof(WCHAR) ?
321  VolumeName->Length+ParentPath->Length :
322  VolumeName->Length+ParentPath->Length-sizeof(WCHAR);
323  Path->ParentPath.MaximumLength = SeparatorLength == sizeof(WCHAR) ?
324  VolumeName->Length+ParentPath->Length :
325  VolumeName->Length+ParentPath->Length-sizeof(WCHAR);
326 
327  Path->FinalComponentName.Buffer = (PWSTR)Add2Ptr( NameString.Buffer,
328  VolumeName->Length+ParentPath->Length+SeparatorLength );
329 
330  Path->FinalComponentName.Length = FinalComponent->Length;
331  Path->FinalComponentName.MaximumLength = FinalComponent->Length;
332 
333  Path->VolumelessName.Buffer = (PWSTR)Add2Ptr( NameString.Buffer, VolumeName->Length );
334  Path->VolumelessName.Length = NameString.Length - VolumeName->Length;
335  Path->VolumelessName.MaximumLength = Path->VolumelessName.Length;
336 
337  Path->NumberComponentsInVolumePath = 0;
338 
339  for (Index = 0; Index < Path->VolumePath.Length/sizeof(WCHAR); Index++) {
340  if (Path->VolumePath.Buffer[Index] == L'\\') {
341  Path->NumberComponentsInVolumePath++;
342  }
343  }
344 
345  Path->NumberComponentsInFullPath = 0;
346 
347  for (Index = 0; Index < Path->FullPath.Length/sizeof(WCHAR); Index++) {
348  if (Path->FullPath.Buffer[Index] == L'\\') {
349  Path->NumberComponentsInFullPath++;
350  }
351  }
352 
353  FLT_ASSERT( Path->NumberComponentsInFullPath > Path->NumberComponentsInVolumePath );
354 
355  //
356  // We reached the end without incident.
357  //
358 
359  Status = STATUS_SUCCESS;
360 
361 NcBuildMappingPathCleanup:
362 
363  if (!NT_SUCCESS( Status )) {
364 
365  if (NameBuffer != NULL) {
366  ExFreePoolWithTag( NameBuffer, NC_MAPPING_TAG );
367  }
368 
369  NcInitMappingPath( Path );
370  }
371 
372  return Status;
373 }
374 
375 NTSTATUS
377  _In_ PFLT_VOLUME CONST Volume,
378  _In_ PUNICODE_STRING ParentPath,
379  _In_ PUNICODE_STRING FinalComponentName,
380  _Inout_ PNC_MAPPING_PATH Entry
381  )
382 /*++
383 
384 Routine Description:
385 
386  Constructs a path from a Volume and a Caller Specified Path.
387 
388 Arguments:
389 
390  Volume - Pointer to the volume which the mapping path will be used on.
391 
392  ParentPath - Path to the parent of the mapping.
393 
394  FinalComponentName - The final component name.
395 
396  Entry - Pointer to a user allocated NC_MAPPING_PATH.
397 
398 Return Value:
399 
400  Returns STATUS_SUCCESS on success. Otherwise returns an error code.
401 
402 --*/
403 {
404  NTSTATUS Status;
405  ULONG VolumeNameLength;
406  PVOID VolumeNameBuffer = NULL;
407  UNICODE_STRING VolumeNameString;
408 
409  PAGED_CODE();
410 
411  FLT_ASSERT( NcIsMappingPathZeroed( Entry ) );
412 
413  //
414  // Query the volume name length.
415  //
416 
417  Status = FltGetVolumeName( Volume,
418  NULL,
419  &VolumeNameLength);
420 
421  if (!NT_SUCCESS( Status ) && Status != STATUS_BUFFER_TOO_SMALL) {
422 
423  goto NcBuildPathCleanup;
424  }
425 
426  //
427  // Allocate a buffer for the name.
428  //
429 
430  Status = STATUS_SUCCESS;
431 
432  VolumeNameBuffer = ExAllocatePoolWithTag( PagedPool,
433  VolumeNameLength,
434  NC_MAPPING_TAG );
435 
436  if (VolumeNameBuffer == NULL) {
437 
438  Status = STATUS_INSUFFICIENT_RESOURCES;
439  goto NcBuildPathCleanup;
440  }
441 
442  RtlInitEmptyUnicodeString( &VolumeNameString, VolumeNameBuffer, (USHORT) VolumeNameLength );
443 
444  //
445  // Query the volume name
446  //
447 
448  Status = FltGetVolumeName( Volume,
449  &VolumeNameString,
450  NULL );
451 
452  if (!NT_SUCCESS( Status )) {
453 
454  goto NcBuildPathCleanup;
455  }
456 
457  //
458  // Generate Mapping Path
459  //
460 
461  Status = NcBuildMappingPath( &VolumeNameString,
462  ParentPath,
463  FinalComponentName,
464  Entry );
465 
466  if (!NT_SUCCESS( Status )) {
467 
468  goto NcBuildPathCleanup;
469  }
470 
471 NcBuildPathCleanup:
472 
473  if (!NT_SUCCESS( Status )) {
474 
475  NcTeardownMappingPath( Entry );
476  }
477 
478  if (VolumeNameBuffer != NULL) {
479 
480  ExFreePoolWithTag( VolumeNameBuffer, NC_MAPPING_TAG );
481  }
482 
483  return Status;
484 }
485 
486 NTSTATUS
488  _In_ PFILE_OBJECT Parent,
489  _In_ PUNICODE_STRING FinalComponent,
490  _In_ PFLT_INSTANCE Instance,
491  _In_ BOOLEAN Normalized,
492  _Inout_ PNC_MAPPING_PATH Path
493  )
494 /*++
495 
496 Routine Description:
497 
498  Builds a path from the parent of the mapping and string for the final component.
499 
500 Arguments:
501 
502  Parent - The file object for the parent of the mapping.
503 
504  FinalComponent - A string which is to be used as the final component of the name.
505 
506  Instance - The instance for which we are building the mapping.
507 
508  NameFlags - Parameters which we will use when checking the name from the file object.
509 
510  Path - Pointer to a user allocated NC_MAPPING_PATH which will be populated.
511 
512 Return Value
513 
514  On success, returns STATUS_SUCCESS, otherwise returns an error code.
515 
516 --*/
517 {
518  NTSTATUS Status;
519  UNICODE_STRING ParentPath;
520  PFLT_FILE_NAME_INFORMATION ParentNameInfo = NULL;
521  FLT_FILE_NAME_OPTIONS NameFlags;
522 
523  PAGED_CODE();
524 
526 
527  if (Normalized) {
528 
529  NameFlags = FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT;
530 
531  } else {
532 
533  NameFlags = FLT_FILE_NAME_OPENED | FLT_FILE_NAME_QUERY_DEFAULT;
534 
535  }
536 
537  //
538  // Get File parent's name info.
539  //
540 
541  Status = NcGetFileNameInformation( NULL,
542  Parent,
543  Instance,
544  NameFlags,
545  &ParentNameInfo );
546 
547  if (!NT_SUCCESS( Status )) {
548 
549  goto NcBuildMappingPathFromFileCleanup;
550  }
551 
552  Status = FltParseFileNameInformation( ParentNameInfo );
553 
554  if (!NT_SUCCESS( Status )) {
555 
556  goto NcBuildMappingPathFromFileCleanup;
557  }
558 
559 
560  FLT_ASSERT( ParentNameInfo->Format == FLT_FILE_NAME_NORMALIZED ||
561  ParentNameInfo->Format == FLT_FILE_NAME_OPENED );
562 
563 
564  //
565  // Format Parent Name
566  //
567 
568  ParentPath.Buffer = ParentNameInfo->ParentDir.Buffer;
569  ParentPath.Length = ParentNameInfo->ParentDir.Length+ParentNameInfo->FinalComponent.Length;
570  ParentPath.MaximumLength = ParentPath.Length;
571 
572  //
573  // Generate name
574  //
575 
576  Status = NcBuildMappingPath( &ParentNameInfo->Volume,
577  &ParentPath,
578  FinalComponent,
579  Path );
580 
581 NcBuildMappingPathFromFileCleanup:
582 
583  if (!NT_SUCCESS( Status )) {
584 
585  NcTeardownMappingPath( Path );
586  }
587 
588  if (ParentNameInfo != NULL) {
589 
590  FltReleaseFileNameInformation( ParentNameInfo );
591  }
592 
593  return Status;
594 }
595 
596 //
597 // Functions to manage mapping entry
598 //
599 
600 BOOLEAN
602  PNC_MAPPING_ENTRY Entry
603  )
604 {
605  PAGED_CODE();
606 
607  if (!NcIsMappingPathZeroed( &Entry->LongNamePath ))
608  return FALSE;
609 
610  if (!NcIsMappingPathZeroed( &Entry->ShortNamePath ))
611  return FALSE;
612 
613  return TRUE;
614 }
615 
616 VOID
618  _Inout_ PNC_MAPPING_ENTRY Entry
619  )
620 {
621  PAGED_CODE();
622 
623  NcInitMappingPath( &Entry->LongNamePath );
624  NcInitMappingPath( &Entry->ShortNamePath );
625 }
626 
627 VOID
629  _Inout_ PNC_MAPPING_ENTRY Path
630  )
631 {
632  PWCHAR StrBuff = Path->LongNamePath.FullPath.Buffer;
633 
634  PAGED_CODE();
635 
636  NcTeardownMappingPath( &Path->LongNamePath );
637 
638  if (StrBuff != Path->ShortNamePath.FullPath.Buffer) {
639 
640  //
641  // There are situations where the two paths point to the
642  // same buffer. We do this check to make sure that
643  // we don't double free it.
644  //
645 
646  NcTeardownMappingPath( &Path->ShortNamePath );
647 
648  } else {
649 
650  NcInitMappingPath( &Path->ShortNamePath );
651  }
652 }
653 
654 //
655 // Functions to manage mapping
656 //
657 
658 BOOLEAN
660  PNC_MAPPING Mapping
661  )
662 {
663  PAGED_CODE();
664  if (!NcIsMappingEntryZeroed( &Mapping->RealMapping )) {
665 
666  return FALSE;
667  }
668 
669  if (!NcIsMappingEntryZeroed( &Mapping->UserMapping )) {
670 
671  return FALSE;
672  }
673 
674  return TRUE;
675 }
676 
677 VOID
679  PNC_MAPPING Mapping
680  )
681 {
682  PAGED_CODE();
683  NcInitMappingEntry( &Mapping->RealMapping );
684  NcInitMappingEntry( &Mapping->UserMapping );
685 }
686 
687 VOID
689  _Inout_ PNC_MAPPING Mapping
690  )
691 {
692  PAGED_CODE();
693  NcTeardownMappingEntry( &Mapping->RealMapping );
694  NcTeardownMappingEntry( &Mapping->UserMapping );
695 }
696 
697 NTSTATUS
699  _In_ PFILE_OBJECT UserParent,
700  _In_ PFILE_OBJECT RealParent,
701  _In_ PUNICODE_STRING UserFinalComponentShortName,
702  _In_ PUNICODE_STRING UserFinalComponentLongName,
703  _In_ PUNICODE_STRING RealFinalComponentName,
704  _In_ PFLT_INSTANCE Instance,
705  _Out_ PNC_MAPPING Mapping
706  )
707 /*++
708 
709 Routine Description:
710 
711  Constructs the mapping for instance setup.
712 
713 Arguments:
714 
715  UserParent - File object of the parent of the user mapping.
716 
717  RealParent - File object of the parent of the real mapping.
718 
719  UserFinalComponentShortName - Short name for the user mapping's final component.
720 
721  UserFinalComponentLongName - Long name for the user mapping's final component.
722 
723  RealFinalComponentName - Final component name for the real mapping (either long or short).
724 
725  Instance - Instance for which we are constructing the mapping.
726 
727  Mapping - Pointer to a user allocated NC_MAPPING which will be populated.
728 
729 --*/
730 {
731 
732  NTSTATUS Status;
733  PAGED_CODE();
734 
735  FLT_ASSERT( NcIsMappingZeroed( Mapping ) );
736 
737  //
738  // Build the Real Path.
739  //
740 
741  Status = NcBuildMappingPathFromFile( RealParent,
742  RealFinalComponentName,
743  Instance,
744  TRUE,
745  &Mapping->RealMapping.LongNamePath );
746 
747  if (!NT_SUCCESS( Status )) {
748 
749  goto NcBuildMappingCleanup;
750  }
751 
752  // TODO: Do we really know that the real path is 8dot3 compliant?
753 
754  //
755  // Reuse the real path for long and short name.
756  //
757 
758  Mapping->RealMapping.ShortNamePath =
759  Mapping->RealMapping.LongNamePath;
760 
761  //
762  // Build the user short path.
763  //
764 
765  Status = NcBuildMappingPathFromFile( UserParent,
766  UserFinalComponentShortName,
767  Instance,
768  FALSE,
769  &Mapping->UserMapping.ShortNamePath );
770 
771  if (!NT_SUCCESS( Status )) {
772 
773  goto NcBuildMappingCleanup;
774  }
775 
776  //
777  // Build the user long path.
778  //
779 
780  Status = NcBuildMappingPathFromFile( UserParent,
781  UserFinalComponentLongName,
782  Instance,
783  TRUE,
784  &Mapping->UserMapping.LongNamePath );
785 
786  if (!NT_SUCCESS( Status )) {
787 
788  goto NcBuildMappingCleanup;
789  }
790 
791 NcBuildMappingCleanup:
792 
793  return Status;
794 }
795 
796 
VOID NcInitMappingEntry(_Inout_ PNC_MAPPING_ENTRY Entry)
Definition: ncmapping.c:617
NTSTATUS NcBuildMapping(_In_ PFILE_OBJECT UserParent, _In_ PFILE_OBJECT RealParent, _In_ PUNICODE_STRING UserFinalComponentShortName, _In_ PUNICODE_STRING UserFinalComponentLongName, _In_ PUNICODE_STRING RealFinalComponentName, _In_ PFLT_INSTANCE Instance, _Out_ PNC_MAPPING Mapping)
Definition: ncmapping.c:698
NTSTATUS NcBuildMappingPath(_In_ PUNICODE_STRING VolumeName, _In_ PUNICODE_STRING ParentPath, _In_ PUNICODE_STRING FinalComponent, _Inout_ PNC_MAPPING_PATH Path)
Definition: ncmapping.c:192
NC_MAPPING_ENTRY RealMapping
Definition: nc.h:186
VOID NcTeardownMapping(_Inout_ PNC_MAPPING Mapping)
Definition: ncmapping.c:688
BOOLEAN NcIsMappingPathZeroed(_In_ PNC_MAPPING_PATH Path)
Definition: ncmapping.c:86
#define Add2Ptr(P, I)
Definition: minispy.h:238
_In_opt_ PFILE_OBJECT _In_opt_ PFLT_INSTANCE Instance
Definition: nc.h:493
NC_MAPPING_PATH ShortNamePath
Definition: nc.h:176
NC_MAPPING_PATH LongNamePath
Definition: nc.h:173
#define NC_SEPARATOR
Definition: nc.h:32
FLT_ASSERT(IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
NTSTATUS NcBuildMappingPathFromFile(_In_ PFILE_OBJECT Parent, _In_ PUNICODE_STRING FinalComponent, _In_ PFLT_INSTANCE Instance, _In_ BOOLEAN Normalized, _Inout_ PNC_MAPPING_PATH Path)
Definition: ncmapping.c:487
return TRUE
VOID NcInitMapping(PNC_MAPPING Mapping)
Definition: ncmapping.c:678
NTSTATUS NcBuildMappingPathFromVolume(_In_ PFLT_VOLUME CONST Volume, _In_ PUNICODE_STRING ParentPath, _In_ PUNICODE_STRING FinalComponentName, _Inout_ PNC_MAPPING_PATH Entry)
Definition: ncmapping.c:376
NC_MAPPING_ENTRY UserMapping
Definition: nc.h:187
VOID NcTeardownMappingPath(_Inout_ PNC_MAPPING_PATH Path)
Definition: ncmapping.c:155
BOOLEAN NcIsMappingZeroed(PNC_MAPPING Mapping)
Definition: ncmapping.c:659
NcLoadRegistryStringRetry NULL
Definition: ncinit.c:53
PAGED_CODE()
IoStatus Status
VOID NcInitMappingPath(_Out_ PNC_MAPPING_PATH Path)
Definition: ncmapping.c:131
#define NC_MAPPING_TAG
Definition: nc.h:14
VOID NcTeardownMappingEntry(_Inout_ PNC_MAPPING_ENTRY Path)
Definition: ncmapping.c:628
BOOLEAN NcIsMappingEntryZeroed(PNC_MAPPING_ENTRY Entry)
Definition: ncmapping.c:601

Social Network


Services Overview

Architect, implement and test file system filter drivers for a wide range of functionality. We can offer several levels of assistance to meet your specific.

Contact Us

You are welcome to contact us for salse or partnership.

Sales: sales@easefilter.com
Support: support@easefilter.com
Info: info@easefilter.com