https://git.reactos.org/?p=reactos.git;a=commitdiff;h=16e0cca7e13efe9a77905b846a8f92619ff99ec5

commit 16e0cca7e13efe9a77905b846a8f92619ff99ec5
Author:     Alex Ionescu <aione...@gmail.com>
AuthorDate: Sun Feb 4 09:33:32 2018 -0800
Commit:     Alex Ionescu <aione...@gmail.com>
CommitDate: Sun Feb 4 09:33:32 2018 -0800

    [RTL]: Document and flesh out Boot Status Data (BSD) API/Structures
    
    [NDK]: Document latest RTL_BSD_DATA as of RS3 based on ext.dll WinDBG
    extension "!blackboxbsd" which outputs the entire structure field by
    field :).
    [NDK]: Update RTL_BSD_ITEM_TYPE thanks to ole32 symbols
    [RTL]: Move system volume APIs to sysvol.c
    [RTL]: Fill out BsdItemTable based on actual field offsets/sizes and not
    hardcoded magic numbers which we won't ask where they came from.
    [RTL]: Make RtlCreateBootStatusDataFile use an appropriate structure for
    initializing the buffer instead of "UCHAR Buffer[12] = {0xC,0,0,0,
    1,0,0,0, 1, 0x1e, 1, 0};" which appears like magic knowledge.
    [RTL]: Rename "WriteMode" to "Read" in RtlGetSetBootStatusData since
    it's much less confusing.
    [RTL]: Some formatting fixes, SAL updates.
---
 sdk/include/ndk/rtltypes.h           | 100 ++++-
 sdk/lib/rtl/CMakeLists.txt           |   1 +
 sdk/lib/rtl/bootdata.c               | 820 +++++------------------------------
 sdk/lib/rtl/{bootdata.c => sysvol.c} | 194 ---------
 4 files changed, 213 insertions(+), 902 deletions(-)

diff --git a/sdk/include/ndk/rtltypes.h b/sdk/include/ndk/rtltypes.h
index 0abde3e0c0..1371f4c86f 100644
--- a/sdk/include/ndk/rtltypes.h
+++ b/sdk/include/ndk/rtltypes.h
@@ -414,9 +414,6 @@ C_ASSERT(FIELD_OFFSET(LARGE_INTEGER, LowPart) == 0);
 #define RTL_CONSTANT_LARGE_INTEGER(quad_part) { { (quad_part), (quad_part)>>32 
} }
 #define RTL_MAKE_LARGE_INTEGER(low_part, high_part) { { (low_part), 
(high_part) } }
 
-
-#ifdef NTOS_MODE_USER
-
 //
 // Boot Status Data Field Types
 //
@@ -428,9 +425,20 @@ typedef enum _RTL_BSD_ITEM_TYPE
     RtlBsdItemAabTimeout,
     RtlBsdItemBootGood,
     RtlBsdItemBootShutdown,
+    RtlBsdSleepInProgress,
+    RtlBsdPowerTransition,
+    RtlBsdItemBootAttemptCount,
+    RtlBsdItemBootCheckpoint,
+    RtlBsdItemBootId,
+    RtlBsdItemShutdownBootId,
+    RtlBsdItemReportedAbnormalShutdownBootId,
+    RtlBsdItemErrorInfo,
+    RtlBsdItemPowerButtonPressInfo,
+    RtlBsdItemChecksum,
     RtlBsdItemMax
 } RTL_BSD_ITEM_TYPE, *PRTL_BSD_ITEM_TYPE;
 
+#ifdef NTOS_MODE_USER
 //
 // Table and Compare result types
 //
@@ -1238,6 +1246,92 @@ typedef struct _RTL_HANDLE_TABLE
     PRTL_HANDLE_TABLE_ENTRY MaxReservedHandles;
 } RTL_HANDLE_TABLE, *PRTL_HANDLE_TABLE;
 
+//
+// RTL Boot Status Data Item
+//
+typedef struct _RTL_BSD_ITEM
+{
+    RTL_BSD_ITEM_TYPE Type;
+    PVOID DataBuffer;
+    ULONG DataLength;
+} RTL_BSD_ITEM, *PRTL_BSD_ITEM;
+
+//
+// Data Sub-Structures for "bootstat.dat" RTL Data File
+//
+typedef struct _RTL_BSD_DATA_POWER_TRANSITION
+{
+    LARGE_INTEGER PowerButtonTimestamp;
+    struct
+    {
+        UCHAR SystemRunning : 1;
+        UCHAR ConnectedStandbyInProgress : 1;
+        UCHAR UserShutdownInProgress : 1;
+        UCHAR SystemShutdownInProgress : 1;
+        UCHAR SleepInProgress : 4;
+    } Flags;
+    UCHAR ConnectedStandbyScenarioInstanceId;
+    UCHAR ConnectedStandbyEntryReason;
+    UCHAR ConnectedStandbyExitReason;
+    USHORT SystemSleepTransitionCount;
+    LARGE_INTEGER LastReferenceTime;
+    ULONG LastReferenceTimeChecksum;
+    ULONG LastUpdateBootId;
+} RTL_BSD_DATA_POWER_TRANSITION, *PRTL_BSD_DATA_POWER_TRANSITION;
+
+typedef struct _RTL_BSD_DATA_ERROR_INFO
+{
+    ULONG BootId;
+    ULONG RepeatCount;
+    ULONG OtherErrorCount;
+    ULONG Code;
+    ULONG OtherErrorCount2;
+} RTL_BSD_DATA_ERROR_INFO, *PRTL_BSD_DATA_ERROR_INFO;
+
+typedef struct _RTL_BSD_POWER_BUTTON_PRESS_INFO
+{
+    LARGE_INTEGER LastPressTime;
+    ULONG CumulativePressCount;
+    USHORT LastPressBootId;
+    UCHAR LastPowerWatchdogStage;
+    struct
+    {
+        UCHAR WatchdogArmed : 1;
+        UCHAR ShutdownInProgress : 1;
+    } Flags;
+    LARGE_INTEGER LastReleaseTime;
+    ULONG CumulativeReleaseCount;
+    USHORT LastReleaseBootId;
+    USHORT ErrorCount;
+    UCHAR CurrentConnectedStandbyPhase;
+    ULONG TransitionLatestCheckpointId;
+    ULONG TransitionLatestCheckpointType;
+    ULONG TransitionLatestCheckpointSequenceNumber;
+} RTL_BSD_POWER_BUTTON_PRESS_INFO, *PRTL_BSD_POWER_BUTTON_PRESS_INFO;
+
+//
+// Main Structure for "bootstat.dat" RTL Data File
+//
+typedef struct _RTL_BSD_DATA
+{
+    ULONG Version;                                          // 
RtlBsdItemVersionNumber
+    ULONG ProductType;                                      // 
RtlBsdItemProductType
+    BOOLEAN AabEnabled;                                     // 
RtlBsdItemAabEnabled
+    UCHAR AabTimeout;                                       // 
RtlBsdItemAabTimeout
+    BOOLEAN LastBootSucceeded;                              // 
RtlBsdItemBootGood
+    BOOLEAN LastBootShutdown;                               // 
RtlBsdItemBootShutdown
+    BOOLEAN SleepInProgress;                                // 
RtlBsdSleepInProgress
+    RTL_BSD_DATA_POWER_TRANSITION PowerTransition;          // 
RtlBsdPowerTransition
+    UCHAR BootAttemptCount;                                 // 
RtlBsdItemBootAttemptCount
+    UCHAR LastBootCheckpoint;                               // 
RtlBsdItemBootCheckpoint
+    UCHAR Checksum;                                         // 
RtlBsdItemChecksum
+    ULONG LastBootId;                                       // RtlBsdItemBootId
+    ULONG LastSuccessfulShutdownBootId;                     // 
RtlBsdItemShutdownBootId
+    ULONG LastReportedAbnormalShutdownBootId;               // 
RtlBsdItemReportedAbnormalShutdownBootId
+    RTL_BSD_DATA_ERROR_INFO ErrorInfo;                      // 
RtlBsdItemErrorInfo
+    RTL_BSD_POWER_BUTTON_PRESS_INFO PowerButtonPressInfo;   // 
RtlBsdItemPowerButtonPressInfo
+} RTL_BSD_DATA, *PRTL_BSD_DATA;
+
 #ifdef NTOS_MODE_USER
 //
 // Exception Record
diff --git a/sdk/lib/rtl/CMakeLists.txt b/sdk/lib/rtl/CMakeLists.txt
index 7279a2e2ea..573e4c0802 100644
--- a/sdk/lib/rtl/CMakeLists.txt
+++ b/sdk/lib/rtl/CMakeLists.txt
@@ -56,6 +56,7 @@ list(APPEND SOURCE
     slist.c
     sid.c
     splaytree.c
+    sysvol.c
     thread.c
     time.c
     timezone.c
diff --git a/sdk/lib/rtl/bootdata.c b/sdk/lib/rtl/bootdata.c
index 77d367426d..b674eb2545 100644
--- a/sdk/lib/rtl/bootdata.c
+++ b/sdk/lib/rtl/bootdata.c
@@ -1,715 +1,118 @@
 /*
- * COPYRIGHT:       See COPYING in the top level directory
- * PROJECT:         ReactOS system libraries
- * PURPOSE:         Boot Data implementation
+ * PROJECT:         ReactOS Runtime Library
+ * LICENSE:         See COPYING in the top level directory
  * FILE:            lib/rtl/bootdata.c
- * PROGRAMMERS:
+ * PURPOSE:         Boot Status Data Implementation
+ * PROGRAMMERS:     Alex Ionescu (alex.ione...@reactos.org)
+ *                  Eric Kohl
  */
 
 /* INCLUDES *****************************************************************/
 
 #include <rtl.h>
-
 #define NDEBUG
 #include <debug.h>
 
-typedef struct _RTL_BSD_ITEM
+typedef struct _RTL_BSD_ITEM_TABLE_ENTRY
 {
-    ULONG Offset;
-    ULONG Size;
-} RTL_BSD_ITEM, *PRTL_BSD_ITEM;
+    UCHAR Offset;
+    UCHAR Size;
+} RTL_BSD_ITEM_TABLE_ENTRY;
 
 /* FUNCTIONS *****************************************************************/
 
-static SID_IDENTIFIER_AUTHORITY LocalSystemAuthority = {SECURITY_NT_AUTHORITY};
-
-static RTL_BSD_ITEM BsdItemTable[6] = {{0, 4}, {4, 4,}, {8, 1}, {9, 1}, {10, 
1}, {11, 1}};
-
-static NTSTATUS
-RtlpSysVolCreateSecurityDescriptor(OUT PISECURITY_DESCRIPTOR 
*SecurityDescriptor,
-                                   OUT PSID *SystemSid)
-{
-    PSECURITY_DESCRIPTOR AbsSD = NULL;
-    PSID LocalSystemSid = NULL;
-    PACL Dacl = NULL;
-    ULONG DaclSize;
-    NTSTATUS Status;
-
-    /* create the local SYSTEM SID */
-    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
-                                         1,
-                                         SECURITY_LOCAL_SYSTEM_RID,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         &LocalSystemSid);
-    if (!NT_SUCCESS(Status))
-    {
-        return Status;
-    }
-
-    /* allocate and initialize the security descriptor */
-    AbsSD = RtlpAllocateMemory(sizeof(SECURITY_DESCRIPTOR),
-                               'dSeS');
-    if (AbsSD == NULL)
-    {
-        Status = STATUS_NO_MEMORY;
-        goto Cleanup;
-    }
-
-    Status = RtlCreateSecurityDescriptor(AbsSD,
-                                         SECURITY_DESCRIPTOR_REVISION);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Cleanup;
-    }
-
-    /* allocate and create the DACL */
-    DaclSize = sizeof(ACL) + sizeof(ACE) +
-               RtlLengthSid(LocalSystemSid);
-    Dacl = RtlpAllocateMemory(DaclSize,
-                              'cAeS');
-    if (Dacl == NULL)
-    {
-        Status = STATUS_NO_MEMORY;
-        goto Cleanup;
-    }
-
-    Status = RtlCreateAcl(Dacl,
-                          DaclSize,
-                          ACL_REVISION);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Cleanup;
-    }
-
-    Status = RtlAddAccessAllowedAceEx(Dacl,
-                                      ACL_REVISION,
-                                      OBJECT_INHERIT_ACE | 
CONTAINER_INHERIT_ACE,
-                                      STANDARD_RIGHTS_ALL | 
SPECIFIC_RIGHTS_ALL,
-                                      LocalSystemSid);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Cleanup;
-    }
-
-    /* set the DACL in the security descriptor */
-    Status = RtlSetDaclSecurityDescriptor(AbsSD,
-                                          TRUE,
-                                          Dacl,
-                                          FALSE);
-
-    /* all done */
-    if (NT_SUCCESS(Status))
-    {
-        *SecurityDescriptor = AbsSD;
-        *SystemSid = LocalSystemSid;
-    }
-    else
-    {
-Cleanup:
-        if (LocalSystemSid != NULL)
-        {
-            RtlFreeSid(LocalSystemSid);
-        }
-
-        if (Dacl != NULL)
-        {
-            RtlpFreeMemory(Dacl,
-                           'cAeS');
-        }
-
-        if (AbsSD != NULL)
-        {
-            RtlpFreeMemory(AbsSD,
-                           'dSeS');
-        }
-    }
-
-    return Status;
-}
-
-static NTSTATUS
-RtlpSysVolCheckOwnerAndSecurity(IN HANDLE DirectoryHandle,
-                                IN PISECURITY_DESCRIPTOR SecurityDescriptor)
+PRTL_BSD_DATA DummyBsd;
+RTL_BSD_ITEM_TABLE_ENTRY BsdItemTable[RtlBsdItemMax] =
 {
-    PSECURITY_DESCRIPTOR RelSD = NULL;
-    PSECURITY_DESCRIPTOR NewRelSD = NULL;
-    PSECURITY_DESCRIPTOR AbsSD = NULL;
-#ifdef _WIN64
-    BOOLEAN AbsSDAllocated = FALSE;
-#endif
-    PSID AdminSid = NULL;
-    PSID LocalSystemSid = NULL;
-    ULONG DescriptorSize;
-    ULONG AbsSDSize, RelSDSize = 0;
-    PACL Dacl;
-    BOOLEAN DaclPresent, DaclDefaulted;
-    PSID OwnerSid;
-    BOOLEAN OwnerDefaulted;
-    ULONG AceIndex;
-    PACE Ace = NULL;
-    NTSTATUS Status;
-
-    /* find out how much memory we need to allocate for the self-relative
-       descriptor we're querying */
-    Status = ZwQuerySecurityObject(DirectoryHandle,
-                                   OWNER_SECURITY_INFORMATION | 
DACL_SECURITY_INFORMATION,
-                                   NULL,
-                                   0,
-                                   &DescriptorSize);
-    if (Status != STATUS_BUFFER_TOO_SMALL)
-    {
-        /* looks like the FS doesn't support security... return success */
-        Status = STATUS_SUCCESS;
-        goto Cleanup;
-    }
-
-    /* allocate enough memory for the security descriptor */
-    RelSD = RtlpAllocateMemory(DescriptorSize,
-                               'dSeS');
-    if (RelSD == NULL)
-    {
-        Status = STATUS_NO_MEMORY;
-        goto Cleanup;
-    }
-
-    /* query the self-relative security descriptor */
-    Status = ZwQuerySecurityObject(DirectoryHandle,
-                                   OWNER_SECURITY_INFORMATION | 
DACL_SECURITY_INFORMATION,
-                                   RelSD,
-                                   DescriptorSize,
-                                   &DescriptorSize);
-    if (!NT_SUCCESS(Status))
-    {
-        /* FIXME - handle the case where someone else modified the owner and/or
-                   DACL while we allocated memory. But that should be *very*
-                   unlikely.... */
-        goto Cleanup;
-    }
-
-    /* query the owner and DACL from the descriptor */
-    Status = RtlGetOwnerSecurityDescriptor(RelSD,
-                                           &OwnerSid,
-                                           &OwnerDefaulted);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Cleanup;
-    }
-
-    Status = RtlGetDaclSecurityDescriptor(RelSD,
-                                          &DaclPresent,
-                                          &Dacl,
-                                          &DaclDefaulted);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Cleanup;
-    }
-
-    /* create the Administrators SID */
-    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
-                                         2,
-                                         SECURITY_BUILTIN_DOMAIN_RID,
-                                         DOMAIN_ALIAS_RID_ADMINS,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         &AdminSid);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Cleanup;
-    }
-
-    /* create the local SYSTEM SID */
-    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
-                                         1,
-                                         SECURITY_LOCAL_SYSTEM_RID,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         &LocalSystemSid);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Cleanup;
-    }
-
-    /* check if the Administrators are the owner and at least a not-NULL DACL
-       is present */
-    if (OwnerSid != NULL &&
-        RtlEqualSid(OwnerSid,
-                    AdminSid) &&
-        DaclPresent && Dacl != NULL)
-    {
-        /* check the DACL for an Allowed ACE for the SYSTEM account */
-        AceIndex = 0;
-        do
-        {
-            Status = RtlGetAce(Dacl,
-                               AceIndex++,
-                               (PVOID*)&Ace);
-            if (!NT_SUCCESS(Status))
-            {
-                Ace = NULL;
-            }
-            else if (Ace != NULL && Ace->Header.AceType == 
ACCESS_ALLOWED_ACE_TYPE)
-            {
-                /* check if the the ACE is a set of allowed permissions for the
-                   local SYSTEM account */
-                if (RtlEqualSid((PSID)(Ace + 1),
-                                LocalSystemSid))
-                {
-                    /* check if the ACE is inherited by noncontainer and
-                       container objects, if not attempt to change that */
-                    if (!(Ace->Header.AceFlags & OBJECT_INHERIT_ACE) ||
-                        !(Ace->Header.AceFlags & CONTAINER_INHERIT_ACE))
-                    {
-                        Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | 
CONTAINER_INHERIT_ACE;
-                        Status = ZwSetSecurityObject(DirectoryHandle,
-                                                     DACL_SECURITY_INFORMATION,
-                                                     RelSD);
-                    }
-                    else
-                    {
-                        /* all done, we have access */
-                        Status = STATUS_SUCCESS;
-                    }
-
-                    goto Cleanup;
-                }
-            }
-        } while (Ace != NULL);
-    }
-
-    AbsSDSize = DescriptorSize;
-
-    /* because we need to change any existing data we need to convert it to
-       an absolute security descriptor first */
-    Status = RtlSelfRelativeToAbsoluteSD2(RelSD,
-                                          &AbsSDSize);
-#ifdef _WIN64
-    if (Status == STATUS_BUFFER_TOO_SMALL)
-    {
-        /* this error code can only be returned on 64 bit builds because
-           the size of an absolute security descriptor is greater than the
-           size of a self-relative security descriptor */
-        ASSERT(AbsSDSize > DescriptorSize);
-
-        AbsSD = RtlpAllocateMemory(DescriptorSize,
-                                   'dSeS');
-        if (AbsSD == NULL)
-        {
-            Status = STATUS_NO_MEMORY;
-            goto Cleanup;
-        }
-
-        AbsSDAllocated = TRUE;
-
-        /* make a raw copy of the self-relative descriptor */
-        RtlCopyMemory(AbsSD,
-                      RelSD,
-                      DescriptorSize);
-
-        /* finally convert it */
-        Status = RtlSelfRelativeToAbsoluteSD2(AbsSD,
-                                              &AbsSDSize);
-    }
-    else
-#endif
-    {
-        AbsSD = RelSD;
-    }
-
-    if (!NT_SUCCESS(Status))
-    {
-        goto Cleanup;
-    }
-
-    /* set the owner SID */
-    Status = RtlSetOwnerSecurityDescriptor(AbsSD,
-                                           AdminSid,
-                                           FALSE);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Cleanup;
-    }
-
-    /* set the DACL in the security descriptor */
-    Status = RtlSetDaclSecurityDescriptor(AbsSD,
-                                          TRUE,
-                                          SecurityDescriptor->Dacl,
-                                          FALSE);
-    if (!NT_SUCCESS(Status))
-    {
-        goto Cleanup;
-    }
-
-    /* convert it back to a self-relative descriptor, find out how much
-       memory we need */
-    Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
-                                         NULL,
-                                         &RelSDSize);
-    if (Status != STATUS_BUFFER_TOO_SMALL)
-    {
-        goto Cleanup;
-    }
-
-    /* allocate enough memory for the new self-relative descriptor */
-    NewRelSD = RtlpAllocateMemory(RelSDSize,
-                                  'dSeS');
-    if (NewRelSD == NULL)
-    {
-        Status = STATUS_NO_MEMORY;
-        goto Cleanup;
-    }
-
-    /* convert the security descriptor to self-relative format */
-    Status = RtlAbsoluteToSelfRelativeSD(AbsSD,
-                                         NewRelSD,
-                                         &RelSDSize);
-    if (Status == STATUS_BUFFER_TOO_SMALL)
-    {
-        goto Cleanup;
-    }
-
-    /* finally attempt to change the security information */
-    Status = ZwSetSecurityObject(DirectoryHandle,
-                                 OWNER_SECURITY_INFORMATION | 
DACL_SECURITY_INFORMATION,
-                                 NewRelSD);
-
-Cleanup:
-    if (AdminSid != NULL)
     {
-        RtlFreeSid(AdminSid);
-    }
-
-    if (LocalSystemSid != NULL)
+        FIELD_OFFSET(RTL_BSD_DATA, Version),
+        sizeof(&DummyBsd->Version)
+    },  // RtlBsdItemVersionNumber
     {
-        RtlFreeSid(LocalSystemSid);
-    }
-
-    if (RelSD != NULL)
+        FIELD_OFFSET(RTL_BSD_DATA, ProductType),
+        sizeof(&DummyBsd->ProductType)
+    },  // RtlBsdItemProductType
     {
-        RtlpFreeMemory(RelSD,
-                       'dSeS');
-    }
-
-    if (NewRelSD != NULL)
+        FIELD_OFFSET(RTL_BSD_DATA, AabEnabled),
+        sizeof(&DummyBsd->AabEnabled)
+    },  // RtlBsdItemAabEnabled
     {
-        RtlpFreeMemory(NewRelSD,
-                       'dSeS');
-    }
-
-#ifdef _WIN64
-    if (AbsSDAllocated)
+        FIELD_OFFSET(RTL_BSD_DATA, AabTimeout),
+        sizeof(&DummyBsd->AabTimeout)
+    },  // RtlBsdItemAabTimeout
     {
-        RtlpFreeMemory(AbsSD,
-                       'dSeS');
-    }
-#endif
-
-    return Status;
-}
-
-static NTSTATUS
-RtlpSysVolTakeOwnership(IN PUNICODE_STRING DirectoryPath,
-                        IN PSECURITY_DESCRIPTOR SecurityDescriptor)
-{
-    TOKEN_PRIVILEGES TokenPrivileges;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    SECURITY_DESCRIPTOR AbsSD;
-    PSID AdminSid = NULL;
-    IO_STATUS_BLOCK IoStatusBlock;
-    BOOLEAN TokenEnabled = FALSE;
-    HANDLE hToken = NULL;
-    HANDLE hDirectory = NULL;
-    NTSTATUS Status;
-    ULONG ReturnLength;
-
-    Status = ZwOpenProcessToken(NtCurrentProcess(),
-                                TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
-                                &hToken);
-    if (!NT_SUCCESS(Status))
+        FIELD_OFFSET(RTL_BSD_DATA, LastBootSucceeded),
+        sizeof(&DummyBsd->LastBootSucceeded)
+    },  // RtlBsdItemBootGood
     {
-        goto Cleanup;
-    }
-
-    /* attempt to enable the SE_TAKE_OWNERSHIP_PRIVILEGE privilege */
-    TokenPrivileges.PrivilegeCount = 1;
-    TokenPrivileges.Privileges[0].Luid.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE;
-    TokenPrivileges.Privileges[0].Luid.HighPart = 0;
-    TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
-    Status = ZwAdjustPrivilegesToken(hToken,
-                                     FALSE,
-                                     &TokenPrivileges,
-                                     sizeof(TokenPrivileges),
-                                     &TokenPrivileges,
-                                     &ReturnLength);
-    if (!NT_SUCCESS(Status))
+        FIELD_OFFSET(RTL_BSD_DATA, LastBootShutdown),
+        sizeof(&DummyBsd->LastBootShutdown)
+    },  // RtlBsdItemBootShutdown
     {
-        goto Cleanup;
-    }
-    TokenEnabled = (TokenPrivileges.PrivilegeCount != 0);
-
-    /* open the directory */
-    InitializeObjectAttributes(&ObjectAttributes,
-                               DirectoryPath,
-                               0,
-                               NULL,
-                               SecurityDescriptor);
-
-    Status = ZwOpenFile(&hDirectory,
-                        SYNCHRONIZE | WRITE_OWNER,
-                        &ObjectAttributes,
-                        &IoStatusBlock,
-                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
-                        FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
-    if (!NT_SUCCESS(Status))
+        FIELD_OFFSET(RTL_BSD_DATA, SleepInProgress),
+        sizeof(&DummyBsd->SleepInProgress)
+    },  // RtlBsdSleepInProgress
     {
-        goto Cleanup;
-    }
-
-    /* create the Administrators SID */
-    Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority,
-                                         2,
-                                         SECURITY_BUILTIN_DOMAIN_RID,
-                                         DOMAIN_ALIAS_RID_ADMINS,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         0,
-                                         &AdminSid);
-    if (!NT_SUCCESS(Status))
+        FIELD_OFFSET(RTL_BSD_DATA, PowerTransition),
+        sizeof(&DummyBsd->PowerTransition)
+    },  // RtlBsdPowerTransition
     {
-        goto Cleanup;
-    }
-
-    /* create the security descriptor */
-    Status = RtlCreateSecurityDescriptor(&AbsSD,
-                                         SECURITY_DESCRIPTOR_REVISION);
-    if (!NT_SUCCESS(Status))
+        FIELD_OFFSET(RTL_BSD_DATA, BootAttemptCount),
+        sizeof(&DummyBsd->BootAttemptCount)
+    },  // RtlBsdItemBootAttemptCount
     {
-        goto Cleanup;
-    }
-
-    Status = RtlSetOwnerSecurityDescriptor(&AbsSD,
-                                           AdminSid,
-                                           FALSE);
-    if (!NT_SUCCESS(Status))
+        FIELD_OFFSET(RTL_BSD_DATA, LastBootCheckpoint),
+        sizeof(&DummyBsd->LastBootCheckpoint)
+    },  // RtlBsdItemBootCheckpoint
     {
-        goto Cleanup;
-    }
-
-    /* attempt to take ownership */
-    Status = ZwSetSecurityObject(hDirectory,
-                                 OWNER_SECURITY_INFORMATION,
-                                 &AbsSD);
-
-Cleanup:
-    if (TokenEnabled)
+        FIELD_OFFSET(RTL_BSD_DATA, LastBootId),
+        sizeof(&DummyBsd->LastBootId)
+    },  // RtlBsdItemBootId
     {
-        ZwAdjustPrivilegesToken(hToken,
-                                FALSE,
-                                &TokenPrivileges,
-                                0,
-                                NULL,
-                                NULL);
-    }
-
-    if (AdminSid != NULL)
+        FIELD_OFFSET(RTL_BSD_DATA, LastSuccessfulShutdownBootId),
+        sizeof(&DummyBsd->LastSuccessfulShutdownBootId)
+    },  // RtlBsdItemShutdownBootId
     {
-        RtlFreeSid(AdminSid);
-    }
-
-    if (hDirectory != NULL)
+        FIELD_OFFSET(RTL_BSD_DATA, LastReportedAbnormalShutdownBootId),
+        sizeof(&DummyBsd->LastReportedAbnormalShutdownBootId)
+    },  // RtlBsdItemReportedAbnormalShutdownBootId
     {
-        ZwClose(hDirectory);
-    }
-
-    if (hToken != NULL)
+        FIELD_OFFSET(RTL_BSD_DATA, ErrorInfo),
+        sizeof(&DummyBsd->ErrorInfo)
+    },  // RtlBsdItemErrorInfo
     {
-        ZwClose(hToken);
-    }
-
-    return Status;
-}
-
-/*
-* @implemented
-*/
-NTSTATUS
-NTAPI
-RtlCreateSystemVolumeInformationFolder(IN PUNICODE_STRING VolumeRootPath)
-{
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    IO_STATUS_BLOCK IoStatusBlock;
-    HANDLE hDirectory;
-    UNICODE_STRING DirectoryName, NewPath;
-    ULONG PathLen;
-    PISECURITY_DESCRIPTOR SecurityDescriptor = NULL;
-    PSID SystemSid = NULL;
-    BOOLEAN AddSep = FALSE;
-    NTSTATUS Status;
-
-    PAGED_CODE_RTL();
-
-    RtlInitUnicodeString(&DirectoryName,
-                         L"System Volume Information");
-
-    PathLen = VolumeRootPath->Length + DirectoryName.Length;
-
-    /* make sure we don't overflow while appending the strings */
-    if (PathLen > 0xFFFC)
-    {
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    if (VolumeRootPath->Buffer[(VolumeRootPath->Length / sizeof(WCHAR)) - 1] 
!= L'\\')
-    {
-        AddSep = TRUE;
-        PathLen += sizeof(WCHAR);
-    }
-
-    /* allocate the new string */
-    NewPath.MaximumLength = (USHORT)PathLen + sizeof(WCHAR);
-    NewPath.Buffer = RtlpAllocateStringMemory(NewPath.MaximumLength,
-                                              TAG_USTR);
-    if (NewPath.Buffer == NULL)
-    {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* create the new path string */
-    NewPath.Length = VolumeRootPath->Length;
-    RtlCopyMemory(NewPath.Buffer,
-                  VolumeRootPath->Buffer,
-                  NewPath.Length);
-    if (AddSep)
-    {
-        NewPath.Buffer[NewPath.Length / sizeof(WCHAR)] = L'\\';
-        NewPath.Length += sizeof(WCHAR);
-    }
-    RtlCopyMemory(NewPath.Buffer + (NewPath.Length / sizeof(WCHAR)),
-                  DirectoryName.Buffer,
-                  DirectoryName.Length);
-    NewPath.Length += DirectoryName.Length;
-    NewPath.Buffer[NewPath.Length / sizeof(WCHAR)] = L'\0';
-
-    ASSERT(NewPath.Length == PathLen);
-    ASSERT(NewPath.Length == NewPath.MaximumLength - sizeof(WCHAR));
-
-    /* create the security descriptor for the new directory */
-    Status = RtlpSysVolCreateSecurityDescriptor(&SecurityDescriptor,
-                                                &SystemSid);
-    if (NT_SUCCESS(Status))
+        FIELD_OFFSET(RTL_BSD_DATA, PowerButtonPressInfo),
+        sizeof(&DummyBsd->PowerButtonPressInfo)
+    },  // RtlBsdItemPowerButtonPressInfo
     {
-        /* create or open the directory */
-        InitializeObjectAttributes(&ObjectAttributes,
-                                   &NewPath,
-                                   0,
-                                   NULL,
-                                   SecurityDescriptor);
-
-        Status = ZwCreateFile(&hDirectory,
-                              SYNCHRONIZE | WRITE_OWNER | WRITE_DAC | 
READ_CONTROL,
-                              &ObjectAttributes,
-                              &IoStatusBlock,
-                              NULL,
-                              FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN,
-                              FILE_SHARE_READ | FILE_SHARE_WRITE | 
FILE_SHARE_DELETE,
-                              FILE_OPEN_IF,
-                              FILE_DIRECTORY_FILE | 
FILE_SYNCHRONOUS_IO_NONALERT,
-                              NULL,
-                              0);
-        if (!NT_SUCCESS(Status))
-        {
-            Status = RtlpSysVolTakeOwnership(&NewPath,
-                                             SecurityDescriptor);
-
-            if (NT_SUCCESS(Status))
-            {
-                /* successfully took ownership, attempt to open it */
-                Status = ZwCreateFile(&hDirectory,
-                                      SYNCHRONIZE | WRITE_OWNER | WRITE_DAC | 
READ_CONTROL,
-                                      &ObjectAttributes,
-                                      &IoStatusBlock,
-                                      NULL,
-                                      FILE_ATTRIBUTE_SYSTEM | 
FILE_ATTRIBUTE_HIDDEN,
-                                      FILE_SHARE_READ | FILE_SHARE_WRITE | 
FILE_SHARE_DELETE,
-                                      FILE_OPEN_IF,
-                                      FILE_DIRECTORY_FILE | 
FILE_SYNCHRONOUS_IO_NONALERT,
-                                      NULL,
-                                      0);
-            }
-        }
-
-        if (NT_SUCCESS(Status))
-        {
-            /* check security now and adjust it if neccessary */
-            Status = RtlpSysVolCheckOwnerAndSecurity(hDirectory,
-                                                     SecurityDescriptor);
-            ZwClose(hDirectory);
-        }
-
-        /* free allocated memory */
-        ASSERT(SecurityDescriptor != NULL);
-        ASSERT(SecurityDescriptor->Dacl != NULL);
-
-        RtlpFreeMemory(SecurityDescriptor->Dacl,
-                       'cAeS');
-        RtlpFreeMemory(SecurityDescriptor,
-                       'dSeS');
-
-        RtlFreeSid(SystemSid);
-    }
-
-    RtlpFreeStringMemory(NewPath.Buffer,
-                         TAG_USTR);
-    return Status;
-}
+        FIELD_OFFSET(RTL_BSD_DATA, Checksum),
+        sizeof(&DummyBsd->Checksum)
+    },  // RtlBsdItemChecksum
+};
 
 /*
-* @implemented
-*/
+ * @implemented
+ */
 NTSTATUS
 NTAPI
-RtlCreateBootStatusDataFile(VOID)
+RtlCreateBootStatusDataFile (
+    VOID
+    )
 {
-    OBJECT_ATTRIBUTES ObjectAttributes;
     IO_STATUS_BLOCK IoStatusBlock;
     LARGE_INTEGER AllocationSize;
     LARGE_INTEGER ByteOffset;
-    UNICODE_STRING FileName;
+    UNICODE_STRING FileName =
+        RTL_CONSTANT_STRING(L"\\SystemRoot\\bootstat.dat");
+    OBJECT_ATTRIBUTES ObjectAttributes =
+        RTL_CONSTANT_OBJECT_ATTRIBUTES(&FileName, OBJ_CASE_INSENSITIVE);
     HANDLE FileHandle;
     NTSTATUS Status;
+    RTL_BSD_DATA InitialBsd;
 
-    /* Initialize the file name */
-    RtlInitUnicodeString(&FileName,
-                         L"\\SystemRoot\\bootstat.dat");
-
-    /* Initialize the object attributes */
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &FileName,
-                               OBJ_CASE_INSENSITIVE,
-                               NULL,
-                               NULL);
-
+    /* Create the boot status data file */
     AllocationSize.QuadPart = 0x800;
     DBG_UNREFERENCED_LOCAL_VARIABLE(AllocationSize);
-
-    /* Create the boot status data file */
     Status = ZwCreateFile(&FileHandle,
                           FILE_GENERIC_READ | FILE_GENERIC_WRITE,
                           &ObjectAttributes,
@@ -723,17 +126,23 @@ RtlCreateBootStatusDataFile(VOID)
                           0);
     if (NT_SUCCESS(Status))
     {
-        // FIXME: Initialize the buffer in a better way.
-        UCHAR Buffer[12] = {0xC,0,0,0, 1,0,0,0, 1, 0x1e, 1, 0};
+        /* Setup a sane looking initial BSD */
+        RtlZeroMemory(&InitialBsd, sizeof(InitialBsd));
+        InitialBsd.Version = sizeof(InitialBsd);
+        InitialBsd.ProductType = NtProductWinNt;
+        InitialBsd.AabEnabled = 1;
+        InitialBsd.AabTimeout = 30;
+        InitialBsd.LastBootSucceeded = TRUE;
 
+        /* Write it to disk */
         ByteOffset.QuadPart = 0;
         Status = ZwWriteFile(FileHandle,
                              NULL,
                              NULL,
                              NULL,
                              &IoStatusBlock,
-                             &Buffer,
-                             12, //BufferSize,
+                             &InitialBsd,
+                             sizeof(InitialBsd),
                              &ByteOffset,
                              NULL);
     }
@@ -745,34 +154,40 @@ RtlCreateBootStatusDataFile(VOID)
 }
 
 /*
-* @implemented
-*/
+ * @implemented
+ */
 NTSTATUS
 NTAPI
-RtlGetSetBootStatusData(IN HANDLE FileHandle,
-                        IN BOOLEAN WriteMode,
-                        IN RTL_BSD_ITEM_TYPE DataClass,
-                        IN PVOID Buffer,
-                        IN ULONG BufferSize,
-                        OUT PULONG ReturnLength)
+RtlGetSetBootStatusData (
+    _In_ HANDLE FileHandle,
+    _In_ BOOLEAN Read,
+    _In_ RTL_BSD_ITEM_TYPE DataClass,
+    _In_ PVOID Buffer,
+    _In_ ULONG BufferSize,
+    _Out_opt_ PULONG ReturnLength
+    )
 {
     IO_STATUS_BLOCK IoStatusBlock;
     LARGE_INTEGER ByteOffset;
     NTSTATUS Status;
 
     DPRINT("RtlGetSetBootStatusData (%p %u %d %p %lu %p)\n",
-           FileHandle, WriteMode, DataClass, Buffer, BufferSize, ReturnLength);
+           FileHandle, Read, DataClass, Buffer, BufferSize, ReturnLength);
 
     if (DataClass >= RtlBsdItemMax)
+    {
         return STATUS_INVALID_PARAMETER;
+    }
 
     if (BufferSize > BsdItemTable[DataClass].Size)
+    {
         return STATUS_BUFFER_TOO_SMALL;
+    }
 
     ByteOffset.HighPart = 0;
     ByteOffset.LowPart = BsdItemTable[DataClass].Offset;
 
-    if (WriteMode)
+    if (Read)
     {
         Status = ZwReadFile(FileHandle,
                             NULL,
@@ -800,39 +215,34 @@ RtlGetSetBootStatusData(IN HANDLE FileHandle,
     if (NT_SUCCESS(Status))
     {
         if (ReturnLength)
+        {
             *ReturnLength = BsdItemTable[DataClass].Size;
+        }
     }
 
     return Status;
 }
 
 /*
-* @implemented
-*/
+ * @implemented
+ */
 NTSTATUS
 NTAPI
-RtlLockBootStatusData(OUT PHANDLE FileHandle)
+RtlLockBootStatusData (
+    _Out_ PHANDLE FileHandle
+    )
 {
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    IO_STATUS_BLOCK IoStatusBlock;
-    UNICODE_STRING FileName;
+    UNICODE_STRING FileName =
+        RTL_CONSTANT_STRING(L"\\SystemRoot\\bootstat.dat");
+    OBJECT_ATTRIBUTES ObjectAttributes =
+        RTL_CONSTANT_OBJECT_ATTRIBUTES(&FileName, OBJ_CASE_INSENSITIVE);
     HANDLE LocalFileHandle;
     NTSTATUS Status;
+    IO_STATUS_BLOCK IoStatusBlock;
 
     /* Intialize the file handle */
     *FileHandle = NULL;
 
-    /* Initialize the file name */
-    RtlInitUnicodeString(&FileName,
-                         L"\\SystemRoot\\bootstat.dat");
-
-    /* Initialize the object attributes */
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &FileName,
-                               0,
-                               NULL,
-                               NULL);
-
     /* Open the boot status data file */
     Status = ZwOpenFile(&LocalFileHandle,
                         FILE_ALL_ACCESS,
@@ -850,18 +260,18 @@ RtlLockBootStatusData(OUT PHANDLE FileHandle)
 }
 
 /*
-* @implemented
-*/
+ * @implemented
+ */
 NTSTATUS
 NTAPI
-RtlUnlockBootStatusData(IN HANDLE FileHandle)
+RtlUnlockBootStatusData (
+    _In_ HANDLE FileHandle
+    )
 {
     IO_STATUS_BLOCK IoStatusBlock;
 
     /* Flush the file and close it */
-    ZwFlushBuffersFile(FileHandle,
-                       &IoStatusBlock);
-
+    ZwFlushBuffersFile(FileHandle, &IoStatusBlock);
     return ZwClose(FileHandle);
 }
 
diff --git a/sdk/lib/rtl/bootdata.c b/sdk/lib/rtl/sysvol.c
similarity index 80%
copy from sdk/lib/rtl/bootdata.c
copy to sdk/lib/rtl/sysvol.c
index 77d367426d..67c79df065 100644
--- a/sdk/lib/rtl/bootdata.c
+++ b/sdk/lib/rtl/sysvol.c
@@ -9,22 +9,13 @@
 /* INCLUDES *****************************************************************/
 
 #include <rtl.h>
-
 #define NDEBUG
 #include <debug.h>
 
-typedef struct _RTL_BSD_ITEM
-{
-    ULONG Offset;
-    ULONG Size;
-} RTL_BSD_ITEM, *PRTL_BSD_ITEM;
-
 /* FUNCTIONS *****************************************************************/
 
 static SID_IDENTIFIER_AUTHORITY LocalSystemAuthority = {SECURITY_NT_AUTHORITY};
 
-static RTL_BSD_ITEM BsdItemTable[6] = {{0, 4}, {4, 4,}, {8, 1}, {9, 1}, {10, 
1}, {11, 1}};
-
 static NTSTATUS
 RtlpSysVolCreateSecurityDescriptor(OUT PISECURITY_DESCRIPTOR 
*SecurityDescriptor,
                                    OUT PSID *SystemSid)
@@ -680,189 +671,4 @@ RtlCreateSystemVolumeInformationFolder(IN PUNICODE_STRING 
VolumeRootPath)
     return Status;
 }
 
-/*
-* @implemented
-*/
-NTSTATUS
-NTAPI
-RtlCreateBootStatusDataFile(VOID)
-{
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    IO_STATUS_BLOCK IoStatusBlock;
-    LARGE_INTEGER AllocationSize;
-    LARGE_INTEGER ByteOffset;
-    UNICODE_STRING FileName;
-    HANDLE FileHandle;
-    NTSTATUS Status;
-
-    /* Initialize the file name */
-    RtlInitUnicodeString(&FileName,
-                         L"\\SystemRoot\\bootstat.dat");
-
-    /* Initialize the object attributes */
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &FileName,
-                               OBJ_CASE_INSENSITIVE,
-                               NULL,
-                               NULL);
-
-    AllocationSize.QuadPart = 0x800;
-    DBG_UNREFERENCED_LOCAL_VARIABLE(AllocationSize);
-
-    /* Create the boot status data file */
-    Status = ZwCreateFile(&FileHandle,
-                          FILE_GENERIC_READ | FILE_GENERIC_WRITE,
-                          &ObjectAttributes,
-                          &IoStatusBlock,
-                          NULL, //&AllocationSize,
-                          FILE_ATTRIBUTE_SYSTEM,
-                          0,
-                          FILE_CREATE,
-                          FILE_SYNCHRONOUS_IO_NONALERT,
-                          NULL,
-                          0);
-    if (NT_SUCCESS(Status))
-    {
-        // FIXME: Initialize the buffer in a better way.
-        UCHAR Buffer[12] = {0xC,0,0,0, 1,0,0,0, 1, 0x1e, 1, 0};
-
-        ByteOffset.QuadPart = 0;
-        Status = ZwWriteFile(FileHandle,
-                             NULL,
-                             NULL,
-                             NULL,
-                             &IoStatusBlock,
-                             &Buffer,
-                             12, //BufferSize,
-                             &ByteOffset,
-                             NULL);
-    }
-
-    /* Close the file */
-    ZwClose(FileHandle);
-
-    return Status;
-}
-
-/*
-* @implemented
-*/
-NTSTATUS
-NTAPI
-RtlGetSetBootStatusData(IN HANDLE FileHandle,
-                        IN BOOLEAN WriteMode,
-                        IN RTL_BSD_ITEM_TYPE DataClass,
-                        IN PVOID Buffer,
-                        IN ULONG BufferSize,
-                        OUT PULONG ReturnLength)
-{
-    IO_STATUS_BLOCK IoStatusBlock;
-    LARGE_INTEGER ByteOffset;
-    NTSTATUS Status;
-
-    DPRINT("RtlGetSetBootStatusData (%p %u %d %p %lu %p)\n",
-           FileHandle, WriteMode, DataClass, Buffer, BufferSize, ReturnLength);
-
-    if (DataClass >= RtlBsdItemMax)
-        return STATUS_INVALID_PARAMETER;
-
-    if (BufferSize > BsdItemTable[DataClass].Size)
-        return STATUS_BUFFER_TOO_SMALL;
-
-    ByteOffset.HighPart = 0;
-    ByteOffset.LowPart = BsdItemTable[DataClass].Offset;
-
-    if (WriteMode)
-    {
-        Status = ZwReadFile(FileHandle,
-                            NULL,
-                            NULL,
-                            NULL,
-                            &IoStatusBlock,
-                            Buffer,
-                            BufferSize,
-                            &ByteOffset,
-                            NULL);
-    }
-    else
-    {
-        Status = ZwWriteFile(FileHandle,
-                             NULL,
-                             NULL,
-                             NULL,
-                             &IoStatusBlock,
-                             Buffer,
-                             BufferSize,
-                             &ByteOffset,
-                             NULL);
-    }
-
-    if (NT_SUCCESS(Status))
-    {
-        if (ReturnLength)
-            *ReturnLength = BsdItemTable[DataClass].Size;
-    }
-
-    return Status;
-}
-
-/*
-* @implemented
-*/
-NTSTATUS
-NTAPI
-RtlLockBootStatusData(OUT PHANDLE FileHandle)
-{
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    IO_STATUS_BLOCK IoStatusBlock;
-    UNICODE_STRING FileName;
-    HANDLE LocalFileHandle;
-    NTSTATUS Status;
-
-    /* Intialize the file handle */
-    *FileHandle = NULL;
-
-    /* Initialize the file name */
-    RtlInitUnicodeString(&FileName,
-                         L"\\SystemRoot\\bootstat.dat");
-
-    /* Initialize the object attributes */
-    InitializeObjectAttributes(&ObjectAttributes,
-                               &FileName,
-                               0,
-                               NULL,
-                               NULL);
-
-    /* Open the boot status data file */
-    Status = ZwOpenFile(&LocalFileHandle,
-                        FILE_ALL_ACCESS,
-                        &ObjectAttributes,
-                        &IoStatusBlock,
-                        0,
-                        FILE_SYNCHRONOUS_IO_NONALERT);
-    if (NT_SUCCESS(Status))
-    {
-        /* Return the file handle */
-        *FileHandle = LocalFileHandle;
-    }
-
-    return Status;
-}
-
-/*
-* @implemented
-*/
-NTSTATUS
-NTAPI
-RtlUnlockBootStatusData(IN HANDLE FileHandle)
-{
-    IO_STATUS_BLOCK IoStatusBlock;
-
-    /* Flush the file and close it */
-    ZwFlushBuffersFile(FileHandle,
-                       &IoStatusBlock);
-
-    return ZwClose(FileHandle);
-}
-
 /* EOF */

Reply via email to