Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbootdata.c
Go to the documentation of this file.
00001 /* COPYRIGHT: See COPYING in the top level directory 00002 * PROJECT: ReactOS system libraries 00003 * PURPOSE: Boot Data implementation 00004 * FILE: lib/rtl/bootdata.c 00005 * PROGRAMMERS: 00006 */ 00007 00008 /* INCLUDES *****************************************************************/ 00009 00010 #include <rtl.h> 00011 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 typedef struct _RTL_BSD_ITEM 00016 { 00017 ULONG Offset; 00018 ULONG Size; 00019 } RTL_BSD_ITEM, *PRTL_BSD_ITEM; 00020 00021 /* FUNCTIONS *****************************************************************/ 00022 00023 static SID_IDENTIFIER_AUTHORITY LocalSystemAuthority = {SECURITY_NT_AUTHORITY}; 00024 00025 static RTL_BSD_ITEM BsdItemTable[6] = {{0, 4}, {4, 4,}, {8, 1}, {9, 1}, {10, 1}, {11, 1}}; 00026 00027 static NTSTATUS 00028 RtlpSysVolCreateSecurityDescriptor(OUT PISECURITY_DESCRIPTOR *SecurityDescriptor, 00029 OUT PSID *SystemSid) 00030 { 00031 PSECURITY_DESCRIPTOR AbsSD = NULL; 00032 PSID LocalSystemSid = NULL; 00033 PACL Dacl = NULL; 00034 ULONG DaclSize; 00035 NTSTATUS Status; 00036 00037 /* create the local SYSTEM SID */ 00038 Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority, 00039 1, 00040 SECURITY_LOCAL_SYSTEM_RID, 00041 0, 00042 0, 00043 0, 00044 0, 00045 0, 00046 0, 00047 0, 00048 &LocalSystemSid); 00049 if (!NT_SUCCESS(Status)) 00050 { 00051 return Status; 00052 } 00053 00054 /* allocate and initialize the security descriptor */ 00055 AbsSD = RtlpAllocateMemory(sizeof(SECURITY_DESCRIPTOR), 00056 'dSeS'); 00057 if (AbsSD == NULL) 00058 { 00059 Status = STATUS_NO_MEMORY; 00060 goto Cleanup; 00061 } 00062 00063 Status = RtlCreateSecurityDescriptor(AbsSD, 00064 SECURITY_DESCRIPTOR_REVISION); 00065 if (!NT_SUCCESS(Status)) 00066 { 00067 goto Cleanup; 00068 } 00069 00070 /* allocate and create the DACL */ 00071 DaclSize = sizeof(ACL) + sizeof(ACE) + 00072 RtlLengthSid(LocalSystemSid); 00073 Dacl = RtlpAllocateMemory(DaclSize, 00074 'cAeS'); 00075 if (Dacl == NULL) 00076 { 00077 Status = STATUS_NO_MEMORY; 00078 goto Cleanup; 00079 } 00080 00081 Status = RtlCreateAcl(Dacl, 00082 DaclSize, 00083 ACL_REVISION); 00084 if (!NT_SUCCESS(Status)) 00085 { 00086 goto Cleanup; 00087 } 00088 00089 Status = RtlAddAccessAllowedAceEx(Dacl, 00090 ACL_REVISION, 00091 OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, 00092 STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL, 00093 LocalSystemSid); 00094 if (!NT_SUCCESS(Status)) 00095 { 00096 goto Cleanup; 00097 } 00098 00099 /* set the DACL in the security descriptor */ 00100 Status = RtlSetDaclSecurityDescriptor(AbsSD, 00101 TRUE, 00102 Dacl, 00103 FALSE); 00104 00105 /* all done */ 00106 if (NT_SUCCESS(Status)) 00107 { 00108 *SecurityDescriptor = AbsSD; 00109 *SystemSid = LocalSystemSid; 00110 } 00111 else 00112 { 00113 Cleanup: 00114 if (LocalSystemSid != NULL) 00115 { 00116 RtlFreeSid(LocalSystemSid); 00117 } 00118 00119 if (Dacl != NULL) 00120 { 00121 RtlpFreeMemory(Dacl, 00122 'cAeS'); 00123 } 00124 00125 if (AbsSD != NULL) 00126 { 00127 RtlpFreeMemory(AbsSD, 00128 'dSeS'); 00129 } 00130 } 00131 00132 return Status; 00133 } 00134 00135 static NTSTATUS 00136 RtlpSysVolCheckOwnerAndSecurity(IN HANDLE DirectoryHandle, 00137 IN PISECURITY_DESCRIPTOR SecurityDescriptor) 00138 { 00139 PSECURITY_DESCRIPTOR RelSD = NULL; 00140 PSECURITY_DESCRIPTOR NewRelSD = NULL; 00141 PSECURITY_DESCRIPTOR AbsSD = NULL; 00142 #ifdef _WIN64 00143 BOOLEAN AbsSDAllocated = FALSE; 00144 #endif 00145 PSID AdminSid = NULL; 00146 PSID LocalSystemSid = NULL; 00147 ULONG DescriptorSize; 00148 ULONG AbsSDSize, RelSDSize = 0; 00149 PACL Dacl; 00150 BOOLEAN DaclPresent, DaclDefaulted; 00151 PSID OwnerSid; 00152 BOOLEAN OwnerDefaulted; 00153 ULONG AceIndex; 00154 PACE Ace = NULL; 00155 NTSTATUS Status; 00156 00157 /* find out how much memory we need to allocate for the self-relative 00158 descriptor we're querying */ 00159 Status = ZwQuerySecurityObject(DirectoryHandle, 00160 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 00161 NULL, 00162 0, 00163 &DescriptorSize); 00164 if (Status != STATUS_BUFFER_TOO_SMALL) 00165 { 00166 /* looks like the FS doesn't support security... return success */ 00167 Status = STATUS_SUCCESS; 00168 goto Cleanup; 00169 } 00170 00171 /* allocate enough memory for the security descriptor */ 00172 RelSD = RtlpAllocateMemory(DescriptorSize, 00173 'dSeS'); 00174 if (RelSD == NULL) 00175 { 00176 Status = STATUS_NO_MEMORY; 00177 goto Cleanup; 00178 } 00179 00180 /* query the self-relative security descriptor */ 00181 Status = ZwQuerySecurityObject(DirectoryHandle, 00182 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 00183 RelSD, 00184 DescriptorSize, 00185 &DescriptorSize); 00186 if (!NT_SUCCESS(Status)) 00187 { 00188 /* FIXME - handle the case where someone else modified the owner and/or 00189 DACL while we allocated memory. But that should be *very* 00190 unlikely.... */ 00191 goto Cleanup; 00192 } 00193 00194 /* query the owner and DACL from the descriptor */ 00195 Status = RtlGetOwnerSecurityDescriptor(RelSD, 00196 &OwnerSid, 00197 &OwnerDefaulted); 00198 if (!NT_SUCCESS(Status)) 00199 { 00200 goto Cleanup; 00201 } 00202 00203 Status = RtlGetDaclSecurityDescriptor(RelSD, 00204 &DaclPresent, 00205 &Dacl, 00206 &DaclDefaulted); 00207 if (!NT_SUCCESS(Status)) 00208 { 00209 goto Cleanup; 00210 } 00211 00212 /* create the Administrators SID */ 00213 Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority, 00214 2, 00215 SECURITY_BUILTIN_DOMAIN_RID, 00216 DOMAIN_ALIAS_RID_ADMINS, 00217 0, 00218 0, 00219 0, 00220 0, 00221 0, 00222 0, 00223 &AdminSid); 00224 if (!NT_SUCCESS(Status)) 00225 { 00226 goto Cleanup; 00227 } 00228 00229 /* create the local SYSTEM SID */ 00230 Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority, 00231 1, 00232 SECURITY_LOCAL_SYSTEM_RID, 00233 0, 00234 0, 00235 0, 00236 0, 00237 0, 00238 0, 00239 0, 00240 &LocalSystemSid); 00241 if (!NT_SUCCESS(Status)) 00242 { 00243 goto Cleanup; 00244 } 00245 00246 /* check if the Administrators are the owner and at least a not-NULL DACL 00247 is present */ 00248 if (OwnerSid != NULL && 00249 RtlEqualSid(OwnerSid, 00250 AdminSid) && 00251 DaclPresent && Dacl != NULL) 00252 { 00253 /* check the DACL for an Allowed ACE for the SYSTEM account */ 00254 AceIndex = 0; 00255 do 00256 { 00257 Status = RtlGetAce(Dacl, 00258 AceIndex++, 00259 (PVOID*)&Ace); 00260 if (!NT_SUCCESS(Status)) 00261 { 00262 Ace = NULL; 00263 } 00264 else if (Ace != NULL && Ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE) 00265 { 00266 /* check if the the ACE is a set of allowed permissions for the 00267 local SYSTEM account */ 00268 if (RtlEqualSid((PSID)(Ace + 1), 00269 LocalSystemSid)) 00270 { 00271 /* check if the ACE is inherited by noncontainer and 00272 container objects, if not attempt to change that */ 00273 if (!(Ace->Header.AceFlags & OBJECT_INHERIT_ACE) || 00274 !(Ace->Header.AceFlags & CONTAINER_INHERIT_ACE)) 00275 { 00276 Ace->Header.AceFlags |= OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE; 00277 Status = ZwSetSecurityObject(DirectoryHandle, 00278 DACL_SECURITY_INFORMATION, 00279 RelSD); 00280 } 00281 else 00282 { 00283 /* all done, we have access */ 00284 Status = STATUS_SUCCESS; 00285 } 00286 00287 goto Cleanup; 00288 } 00289 } 00290 } while (Ace != NULL); 00291 } 00292 00293 AbsSDSize = DescriptorSize; 00294 00295 /* because we need to change any existing data we need to convert it to 00296 an absolute security descriptor first */ 00297 Status = RtlSelfRelativeToAbsoluteSD2(RelSD, 00298 &AbsSDSize); 00299 #ifdef _WIN64 00300 if (Status == STATUS_BUFFER_TOO_SMALL) 00301 { 00302 /* this error code can only be returned on 64 bit builds because 00303 the size of an absolute security descriptor is greater than the 00304 size of a self-relative security descriptor */ 00305 ASSERT(AbsSDSize > DescriptorSize); 00306 00307 AbsSD = RtlpAllocateMemory(DescriptorSize, 00308 'dSeS'); 00309 if (AbsSD == NULL) 00310 { 00311 Status = STATUS_NO_MEMORY; 00312 goto Cleanup; 00313 } 00314 00315 AbsSDAllocated = TRUE; 00316 00317 /* make a raw copy of the self-relative descriptor */ 00318 RtlCopyMemory(AbsSD, 00319 RelSD, 00320 DescriptorSize); 00321 00322 /* finally convert it */ 00323 Status = RtlSelfRelativeToAbsoluteSD2(AbsSD, 00324 &AbsSDSize); 00325 } 00326 else 00327 #endif 00328 { 00329 AbsSD = RelSD; 00330 } 00331 00332 if (!NT_SUCCESS(Status)) 00333 { 00334 goto Cleanup; 00335 } 00336 00337 /* set the owner SID */ 00338 Status = RtlSetOwnerSecurityDescriptor(AbsSD, 00339 AdminSid, 00340 FALSE); 00341 if (!NT_SUCCESS(Status)) 00342 { 00343 goto Cleanup; 00344 } 00345 00346 /* set the DACL in the security descriptor */ 00347 Status = RtlSetDaclSecurityDescriptor(AbsSD, 00348 TRUE, 00349 SecurityDescriptor->Dacl, 00350 FALSE); 00351 if (!NT_SUCCESS(Status)) 00352 { 00353 goto Cleanup; 00354 } 00355 00356 /* convert it back to a self-relative descriptor, find out how much 00357 memory we need */ 00358 Status = RtlAbsoluteToSelfRelativeSD(AbsSD, 00359 NULL, 00360 &RelSDSize); 00361 if (Status != STATUS_BUFFER_TOO_SMALL) 00362 { 00363 goto Cleanup; 00364 } 00365 00366 /* allocate enough memory for the new self-relative descriptor */ 00367 NewRelSD = RtlpAllocateMemory(RelSDSize, 00368 'dSeS'); 00369 if (NewRelSD == NULL) 00370 { 00371 Status = STATUS_NO_MEMORY; 00372 goto Cleanup; 00373 } 00374 00375 /* convert the security descriptor to self-relative format */ 00376 Status = RtlAbsoluteToSelfRelativeSD(AbsSD, 00377 NewRelSD, 00378 &RelSDSize); 00379 if (Status == STATUS_BUFFER_TOO_SMALL) 00380 { 00381 goto Cleanup; 00382 } 00383 00384 /* finally attempt to change the security information */ 00385 Status = ZwSetSecurityObject(DirectoryHandle, 00386 OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, 00387 NewRelSD); 00388 00389 Cleanup: 00390 if (AdminSid != NULL) 00391 { 00392 RtlFreeSid(AdminSid); 00393 } 00394 00395 if (LocalSystemSid != NULL) 00396 { 00397 RtlFreeSid(LocalSystemSid); 00398 } 00399 00400 if (RelSD != NULL) 00401 { 00402 RtlpFreeMemory(RelSD, 00403 'dSeS'); 00404 } 00405 00406 if (NewRelSD != NULL) 00407 { 00408 RtlpFreeMemory(NewRelSD, 00409 'dSeS'); 00410 } 00411 00412 #ifdef _WIN64 00413 if (AbsSDAllocated) 00414 { 00415 RtlpFreeMemory(AbsSD, 00416 'dSeS'); 00417 } 00418 #endif 00419 00420 return Status; 00421 } 00422 00423 static NTSTATUS 00424 RtlpSysVolTakeOwnership(IN PUNICODE_STRING DirectoryPath, 00425 IN PSECURITY_DESCRIPTOR SecurityDescriptor) 00426 { 00427 TOKEN_PRIVILEGES TokenPrivileges; 00428 OBJECT_ATTRIBUTES ObjectAttributes; 00429 SECURITY_DESCRIPTOR AbsSD; 00430 PSID AdminSid = NULL; 00431 IO_STATUS_BLOCK IoStatusBlock; 00432 BOOLEAN TokenEnabled = FALSE; 00433 HANDLE hToken = NULL; 00434 HANDLE hDirectory = NULL; 00435 NTSTATUS Status; 00436 00437 Status = ZwOpenProcessToken(NtCurrentProcess(), 00438 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, 00439 &hToken); 00440 if (!NT_SUCCESS(Status)) 00441 { 00442 goto Cleanup; 00443 } 00444 00445 /* attempt to enable the SE_TAKE_OWNERSHIP_PRIVILEGE privilege */ 00446 TokenPrivileges.PrivilegeCount = 1; 00447 TokenPrivileges.Privileges[0].Luid.LowPart = SE_TAKE_OWNERSHIP_PRIVILEGE; 00448 TokenPrivileges.Privileges[0].Luid.HighPart = 0; 00449 TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 00450 Status = ZwAdjustPrivilegesToken(hToken, 00451 FALSE, 00452 &TokenPrivileges, 00453 sizeof(TokenPrivileges), 00454 &TokenPrivileges, 00455 NULL); 00456 if (!NT_SUCCESS(Status)) 00457 { 00458 goto Cleanup; 00459 } 00460 TokenEnabled = (TokenPrivileges.PrivilegeCount != 0); 00461 00462 /* open the directory */ 00463 InitializeObjectAttributes(&ObjectAttributes, 00464 DirectoryPath, 00465 0, 00466 NULL, 00467 SecurityDescriptor); 00468 00469 Status = ZwOpenFile(&hDirectory, 00470 SYNCHRONIZE | WRITE_OWNER, 00471 &ObjectAttributes, 00472 &IoStatusBlock, 00473 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 00474 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT); 00475 if (!NT_SUCCESS(Status)) 00476 { 00477 goto Cleanup; 00478 } 00479 00480 /* create the Administrators SID */ 00481 Status = RtlAllocateAndInitializeSid(&LocalSystemAuthority, 00482 2, 00483 SECURITY_BUILTIN_DOMAIN_RID, 00484 DOMAIN_ALIAS_RID_ADMINS, 00485 0, 00486 0, 00487 0, 00488 0, 00489 0, 00490 0, 00491 &AdminSid); 00492 if (!NT_SUCCESS(Status)) 00493 { 00494 goto Cleanup; 00495 } 00496 00497 /* create the security descriptor */ 00498 Status = RtlCreateSecurityDescriptor(&AbsSD, 00499 SECURITY_DESCRIPTOR_REVISION); 00500 if (!NT_SUCCESS(Status)) 00501 { 00502 goto Cleanup; 00503 } 00504 00505 Status = RtlSetOwnerSecurityDescriptor(&AbsSD, 00506 AdminSid, 00507 FALSE); 00508 if (!NT_SUCCESS(Status)) 00509 { 00510 goto Cleanup; 00511 } 00512 00513 /* attempt to take ownership */ 00514 Status = ZwSetSecurityObject(hDirectory, 00515 OWNER_SECURITY_INFORMATION, 00516 &AbsSD); 00517 00518 Cleanup: 00519 if (TokenEnabled) 00520 { 00521 ZwAdjustPrivilegesToken(hToken, 00522 FALSE, 00523 &TokenPrivileges, 00524 0, 00525 NULL, 00526 NULL); 00527 } 00528 00529 if (AdminSid != NULL) 00530 { 00531 RtlFreeSid(AdminSid); 00532 } 00533 00534 if (hDirectory != NULL) 00535 { 00536 ZwClose(hDirectory); 00537 } 00538 00539 if (hToken != NULL) 00540 { 00541 ZwClose(hToken); 00542 } 00543 00544 return Status; 00545 } 00546 00547 /* 00548 * @implemented 00549 */ 00550 NTSTATUS 00551 NTAPI 00552 RtlCreateSystemVolumeInformationFolder(IN PUNICODE_STRING VolumeRootPath) 00553 { 00554 OBJECT_ATTRIBUTES ObjectAttributes; 00555 IO_STATUS_BLOCK IoStatusBlock; 00556 HANDLE hDirectory; 00557 UNICODE_STRING DirectoryName, NewPath; 00558 ULONG PathLen; 00559 PISECURITY_DESCRIPTOR SecurityDescriptor = NULL; 00560 PSID SystemSid = NULL; 00561 BOOLEAN AddSep = FALSE; 00562 NTSTATUS Status; 00563 00564 PAGED_CODE_RTL(); 00565 00566 RtlInitUnicodeString(&DirectoryName, 00567 L"System Volume Information"); 00568 00569 PathLen = VolumeRootPath->Length + DirectoryName.Length; 00570 00571 /* make sure we don't overflow while appending the strings */ 00572 if (PathLen > 0xFFFC) 00573 { 00574 return STATUS_INVALID_PARAMETER; 00575 } 00576 00577 if (VolumeRootPath->Buffer[(VolumeRootPath->Length / sizeof(WCHAR)) - 1] != L'\\') 00578 { 00579 AddSep = TRUE; 00580 PathLen += sizeof(WCHAR); 00581 } 00582 00583 /* allocate the new string */ 00584 NewPath.MaximumLength = (USHORT)PathLen + sizeof(WCHAR); 00585 NewPath.Buffer = RtlpAllocateStringMemory(NewPath.MaximumLength, 00586 TAG_USTR); 00587 if (NewPath.Buffer == NULL) 00588 { 00589 return STATUS_INSUFFICIENT_RESOURCES; 00590 } 00591 00592 /* create the new path string */ 00593 NewPath.Length = VolumeRootPath->Length; 00594 RtlCopyMemory(NewPath.Buffer, 00595 VolumeRootPath->Buffer, 00596 NewPath.Length); 00597 if (AddSep) 00598 { 00599 NewPath.Buffer[NewPath.Length / sizeof(WCHAR)] = L'\\'; 00600 NewPath.Length += sizeof(WCHAR); 00601 } 00602 RtlCopyMemory(NewPath.Buffer + (NewPath.Length / sizeof(WCHAR)), 00603 DirectoryName.Buffer, 00604 DirectoryName.Length); 00605 NewPath.Length += DirectoryName.Length; 00606 NewPath.Buffer[NewPath.Length / sizeof(WCHAR)] = L'\0'; 00607 00608 ASSERT(NewPath.Length == PathLen); 00609 ASSERT(NewPath.Length == NewPath.MaximumLength - sizeof(WCHAR)); 00610 00611 /* create the security descriptor for the new directory */ 00612 Status = RtlpSysVolCreateSecurityDescriptor(&SecurityDescriptor, 00613 &SystemSid); 00614 if (NT_SUCCESS(Status)) 00615 { 00616 /* create or open the directory */ 00617 InitializeObjectAttributes(&ObjectAttributes, 00618 &NewPath, 00619 0, 00620 NULL, 00621 SecurityDescriptor); 00622 00623 Status = ZwCreateFile(&hDirectory, 00624 SYNCHRONIZE | WRITE_OWNER | WRITE_DAC | READ_CONTROL, 00625 &ObjectAttributes, 00626 &IoStatusBlock, 00627 NULL, 00628 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, 00629 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 00630 FILE_OPEN_IF, 00631 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 00632 NULL, 00633 0); 00634 if (!NT_SUCCESS(Status)) 00635 { 00636 Status = RtlpSysVolTakeOwnership(&NewPath, 00637 SecurityDescriptor); 00638 00639 if (NT_SUCCESS(Status)) 00640 { 00641 /* successfully took ownership, attempt to open it */ 00642 Status = ZwCreateFile(&hDirectory, 00643 SYNCHRONIZE | WRITE_OWNER | WRITE_DAC | READ_CONTROL, 00644 &ObjectAttributes, 00645 &IoStatusBlock, 00646 NULL, 00647 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN, 00648 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 00649 FILE_OPEN_IF, 00650 FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, 00651 NULL, 00652 0); 00653 } 00654 } 00655 00656 if (NT_SUCCESS(Status)) 00657 { 00658 /* check security now and adjust it if neccessary */ 00659 Status = RtlpSysVolCheckOwnerAndSecurity(hDirectory, 00660 SecurityDescriptor); 00661 ZwClose(hDirectory); 00662 } 00663 00664 /* free allocated memory */ 00665 ASSERT(SecurityDescriptor != NULL); 00666 ASSERT(SecurityDescriptor->Dacl != NULL); 00667 00668 RtlpFreeMemory(SecurityDescriptor->Dacl, 00669 'cAeS'); 00670 RtlpFreeMemory(SecurityDescriptor, 00671 'dSeS'); 00672 00673 RtlFreeSid(SystemSid); 00674 } 00675 00676 RtlpFreeStringMemory(NewPath.Buffer, 00677 TAG_USTR); 00678 return Status; 00679 } 00680 00681 /* 00682 * @implemented 00683 */ 00684 NTSTATUS 00685 NTAPI 00686 RtlCreateBootStatusDataFile(VOID) 00687 { 00688 OBJECT_ATTRIBUTES ObjectAttributes; 00689 IO_STATUS_BLOCK IoStatusBlock; 00690 LARGE_INTEGER AllocationSize; 00691 LARGE_INTEGER ByteOffset; 00692 UNICODE_STRING FileName; 00693 HANDLE FileHandle; 00694 NTSTATUS Status; 00695 00696 /* Initialize the file name */ 00697 RtlInitUnicodeString(&FileName, 00698 L"\\SystemRoot\\bootstat.dat"); 00699 00700 /* Initialize the object attributes */ 00701 InitializeObjectAttributes(&ObjectAttributes, 00702 &FileName, 00703 OBJ_CASE_INSENSITIVE, 00704 NULL, 00705 NULL); 00706 00707 AllocationSize.QuadPart = 0x800; 00708 00709 /* Create the boot status data file */ 00710 Status = ZwCreateFile(&FileHandle, 00711 FILE_GENERIC_READ | FILE_GENERIC_WRITE, 00712 &ObjectAttributes, 00713 &IoStatusBlock, 00714 NULL, //&AllocationSize, 00715 FILE_ATTRIBUTE_SYSTEM, 00716 0, 00717 FILE_CREATE, 00718 FILE_SYNCHRONOUS_IO_NONALERT, 00719 NULL, 00720 0); 00721 if (NT_SUCCESS(Status)) 00722 { 00723 // FIXME: Initialize the buffer in a better way. 00724 UCHAR Buffer[12] = {0xC,0,0,0, 1,0,0,0, 1, 0x1e, 1, 0}; 00725 00726 ByteOffset.QuadPart = 0; 00727 Status = ZwWriteFile(FileHandle, 00728 NULL, 00729 NULL, 00730 NULL, 00731 &IoStatusBlock, 00732 &Buffer, 00733 12, //BufferSize, 00734 &ByteOffset, 00735 NULL); 00736 } 00737 00738 /* Close the file */ 00739 ZwClose(FileHandle); 00740 00741 return Status; 00742 } 00743 00744 /* 00745 * @implemented 00746 */ 00747 NTSTATUS 00748 NTAPI 00749 RtlGetSetBootStatusData(IN HANDLE FileHandle, 00750 IN BOOLEAN WriteMode, 00751 IN RTL_BSD_ITEM_TYPE DataClass, 00752 IN PVOID Buffer, 00753 IN ULONG BufferSize, 00754 OUT PULONG ReturnLength) 00755 { 00756 IO_STATUS_BLOCK IoStatusBlock; 00757 LARGE_INTEGER ByteOffset; 00758 NTSTATUS Status; 00759 00760 DPRINT("RtlGetSetBootStatusData (%p %u %u %p %lu %p)\n", 00761 FileHandle, WriteMode, DataClass, Buffer, BufferSize, ReturnLength); 00762 00763 if (DataClass >= RtlBsdItemMax) 00764 return STATUS_INVALID_PARAMETER; 00765 00766 if (BufferSize > BsdItemTable[DataClass].Size) 00767 return STATUS_BUFFER_TOO_SMALL; 00768 00769 ByteOffset.HighPart = 0; 00770 ByteOffset.LowPart = BsdItemTable[DataClass].Offset; 00771 00772 if (WriteMode) 00773 { 00774 Status = ZwReadFile(FileHandle, 00775 NULL, 00776 NULL, 00777 NULL, 00778 &IoStatusBlock, 00779 Buffer, 00780 BufferSize, 00781 &ByteOffset, 00782 NULL); 00783 } 00784 else 00785 { 00786 Status = ZwWriteFile(FileHandle, 00787 NULL, 00788 NULL, 00789 NULL, 00790 &IoStatusBlock, 00791 Buffer, 00792 BufferSize, 00793 &ByteOffset, 00794 NULL); 00795 } 00796 00797 if (NT_SUCCESS(Status)) 00798 { 00799 if (ReturnLength) 00800 *ReturnLength = BsdItemTable[DataClass].Size; 00801 } 00802 00803 return Status; 00804 } 00805 00806 /* 00807 * @implemented 00808 */ 00809 NTSTATUS 00810 NTAPI 00811 RtlLockBootStatusData(OUT PHANDLE FileHandle) 00812 { 00813 OBJECT_ATTRIBUTES ObjectAttributes; 00814 IO_STATUS_BLOCK IoStatusBlock; 00815 UNICODE_STRING FileName; 00816 HANDLE LocalFileHandle; 00817 NTSTATUS Status; 00818 00819 /* Intialize the file handle */ 00820 *FileHandle = NULL; 00821 00822 /* Initialize the file name */ 00823 RtlInitUnicodeString(&FileName, 00824 L"\\SystemRoot\\bootstat.dat"); 00825 00826 /* Initialize the object attributes */ 00827 InitializeObjectAttributes(&ObjectAttributes, 00828 &FileName, 00829 0, 00830 NULL, 00831 NULL); 00832 00833 /* Open the boot status data file */ 00834 Status = ZwOpenFile(&LocalFileHandle, 00835 FILE_ALL_ACCESS, 00836 &ObjectAttributes, 00837 &IoStatusBlock, 00838 0, 00839 FILE_SYNCHRONOUS_IO_NONALERT); 00840 if (NT_SUCCESS(Status)) 00841 { 00842 /* Return the file handle */ 00843 *FileHandle = LocalFileHandle; 00844 } 00845 00846 return Status; 00847 } 00848 00849 /* 00850 * @implemented 00851 */ 00852 NTSTATUS 00853 NTAPI 00854 RtlUnlockBootStatusData(IN HANDLE FileHandle) 00855 { 00856 IO_STATUS_BLOCK IoStatusBlock; 00857 00858 /* Flush the file and close it */ 00859 ZwFlushBuffersFile(FileHandle, 00860 &IoStatusBlock); 00861 00862 return ZwClose(FileHandle); 00863 } 00864 00865 /* EOF */ Generated on Sun May 27 2012 04:27:12 for ReactOS by
1.7.6.1
|