Advertisement
Guest User

Untitled

a guest
Nov 23rd, 2015
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.92 KB | None | 0 0
  1. _When_(return == 0, _Post_satisfies_(String->Buffer != NULL))
  2. NTSTATUS
  3. RWBAllocateUnicodeString(
  4. _Inout_ PUNICODE_STRING String
  5. )
  6. /*++
  7.  
  8. Routine Description:
  9.  
  10. This routine allocates a unicode string
  11.  
  12. Arguments:
  13.  
  14. Size - the size in bytes needed for the string buffer
  15.  
  16. String - supplies the size of the string to be allocated in the MaximumLength field
  17. return the unicode string
  18.  
  19. Return Value:
  20.  
  21. STATUS_SUCCESS                  - success
  22. STATUS_INSUFFICIENT_RESOURCES   - failure
  23.  
  24. --*/
  25. {
  26.  
  27.     PAGED_CODE();
  28.  
  29.     String->Buffer = ExAllocatePoolWithTag(NonPagedPool,
  30.         String->MaximumLength,
  31.         RWB_STRING_TAG);
  32.  
  33.     if (String->Buffer == NULL) {
  34.  
  35.         PT_DBG_PRINT(PTDBG_TRACE_ROUTINES,
  36.             ("[SimRep]: Failed to allocate unicode string of size 0x%x\n",
  37.             String->MaximumLength));
  38.  
  39.         return STATUS_INSUFFICIENT_RESOURCES;
  40.     }
  41.  
  42.     String->Length = 0;
  43.  
  44.     return STATUS_SUCCESS;
  45. }
  46.  
  47. VOID
  48. RWBFreeUnicodeString(
  49. _Inout_ PUNICODE_STRING String
  50. )
  51. /*++
  52.  
  53. Routine Description:
  54.  
  55. This routine frees a unicode string
  56.  
  57. Arguments:
  58.  
  59. String - supplies the string to be freed
  60.  
  61. Return Value:
  62.  
  63. None
  64.  
  65. --*/
  66. {
  67.     PAGED_CODE();
  68.  
  69.     if (String->Buffer) {
  70.  
  71.         ExFreePoolWithTag(String->Buffer,
  72.             RWB_STRING_TAG);
  73.         String->Buffer = NULL;
  74.     }
  75.  
  76.     String->Length = String->MaximumLength = 0;
  77.     String->Buffer = NULL;
  78. }
  79.  
  80. NTSTATUS
  81. RWBRollPath(
  82.     _In_ UNICODE_STRING Path,
  83.     _In_ PFLT_FILTER Filter,
  84.     _In_ PFLT_INSTANCE Instance
  85. )
  86. /*
  87. Routine Description:
  88.  
  89. This routine creates the directory specified as input
  90.  
  91. Arguments:
  92.  
  93. Path - The path to create
  94.  
  95. Return Value:
  96.  
  97. STATUS_SUCCESS                  - success
  98.  
  99. */
  100. {
  101.     NTSTATUS status = STATUS_SUCCESS;
  102.     HANDLE directoryHandle = NULL;
  103.     OBJECT_ATTRIBUTES objectAttributes;
  104.     IO_STATUS_BLOCK ioStatusBlock;
  105.     UNICODE_STRING previousFolder;
  106.  
  107.     // Initialize object attributes to set the path
  108.     InitializeObjectAttributes(
  109.         &objectAttributes,
  110.         &Path,
  111.         OBJ_CASE_INSENSITIVE,
  112.         NULL,
  113.         NULL
  114.         );
  115.  
  116.     // Tries to create the directory.
  117.     status = FltCreateFile(
  118.         Filter,
  119.         Instance,
  120.         &directoryHandle,
  121.         FILE_LIST_DIRECTORY | FILE_TRAVERSE,
  122.         &objectAttributes,
  123.         &ioStatusBlock,
  124.         NULL,
  125.         FILE_ATTRIBUTE_NORMAL,
  126.         FILE_SHARE_READ | FILE_SHARE_WRITE,
  127.         FILE_OPEN_IF,
  128.         FILE_DIRECTORY_FILE,
  129.         NULL,
  130.         (ULONG) 0,
  131.         IO_IGNORE_SHARE_ACCESS_CHECK
  132.         );
  133.  
  134.     // If the directory already exists or it have been created, returns STATUS_SUCCESS
  135.     if (ioStatusBlock.Information == FILE_OPENED || ioStatusBlock.Information == FILE_CREATED){
  136.         status = STATUS_SUCCESS;
  137.         goto RWBRollPathCleanup;
  138.     }
  139.  
  140.     // If the create failed, it means that we have to create the previous directories and then try again to create this directory
  141.     if (!NT_SUCCESS(status)){
  142.         UNICODE_STRING finalComponent;
  143.         // Get the final component of the name and creates a new string without
  144.         // it in order to create the previous folder
  145.         FltParseFileName(&Path,
  146.             NULL,
  147.             NULL,
  148.             &finalComponent
  149.             );
  150.  
  151.         previousFolder.MaximumLength = Path.Length - finalComponent.Length - sizeof(WCHAR);
  152.         RWBAllocateUnicodeString(&previousFolder);
  153.         RtlCopyMemory(
  154.             previousFolder.Buffer,
  155.             Path.Buffer,
  156.             previousFolder.MaximumLength
  157.             );
  158.         previousFolder.Length = previousFolder.MaximumLength;
  159.  
  160.         // Creates the previous folders
  161.         RWBRollPath(
  162.             previousFolder,
  163.             Filter,
  164.             Instance
  165.             );
  166.  
  167.         // TODO: check status
  168.  
  169.         // Tries to create the directory again. This time should not fail since the previous folder have been created
  170.         status = FltCreateFile(
  171.             Filter,
  172.             Instance,
  173.             &directoryHandle,
  174.             FILE_LIST_DIRECTORY | FILE_TRAVERSE,
  175.             &objectAttributes,
  176.             &ioStatusBlock,
  177.             NULL,
  178.             FILE_ATTRIBUTE_NORMAL,
  179.             FILE_SHARE_READ | FILE_SHARE_WRITE,
  180.             FILE_OPEN_IF,
  181.             FILE_DIRECTORY_FILE,
  182.             NULL,
  183.             (ULONG)0,
  184.             IO_IGNORE_SHARE_ACCESS_CHECK
  185.             );
  186.         RWBFreeUnicodeString(&previousFolder);
  187.     }
  188.  
  189. RWBRollPathCleanup:
  190.  
  191.     if (directoryHandle != NULL)
  192.         FltClose(directoryHandle);
  193.  
  194.     return status;
  195. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement