NTSTATUS
CmpOpenFileWithExtremePrejudice(
OUT PHANDLE Primary,
IN POBJECT_ATTRIBUTES Obja,
IN ULONG IoFlags,
IN ULONG AttributeFlags
)
/*++
Routine Description:
This routine opens a hive file that some person has put a
read-only attribute on. It is used to prevent people from hurting
themselves by making the critical system hive files read-only.
Arguments:
Primary - Returns handle to file
Obja - Supplies Object Attributes of file.
IoFlags - Supplies flags to pass to ZwCreateFile
Return Value:
NTSTATUS
--*/
{
NTSTATUS Status;
HANDLE Handle;
IO_STATUS_BLOCK IoStatusBlock;
FILE_BASIC_INFORMATION FileInfo;
RtlZeroMemory(&FileInfo, sizeof(FileInfo));
//
// Get the current file attributes
//
ASSERT_PASSIVE_LEVEL();
Status = ZwQueryAttributesFile(Obja, &FileInfo);
if (!NT_SUCCESS(Status)) {
CmKdPrintEx((DPFLTR_CONFIG_ID,DPFLTR_ERROR_LEVEL,"ZwQueryAttributesFile failed with IO status %lx\n",Status));
return(Status);
}
//
// Clear the readonly bit.
//
FileInfo.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
//
// Open the file
//
Status = ZwOpenFile(&Handle,
FILE_WRITE_ATTRIBUTES,
Obja,
&IoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS(Status)) {
return(Status);
}
//
// Set the new attributes
//
Status = ZwSetInformationFile(Handle,
&IoStatusBlock,
&FileInfo,
sizeof(FileInfo),
FileBasicInformation);
ZwClose(Handle);
if (NT_SUCCESS(Status)) {
//
// Reopen the file with the access that we really need.
//
Status = ZwCreateFile(Primary,
FILE_READ_DATA | FILE_WRITE_DATA,
Obja,
&IoStatusBlock,
NULL,
AttributeFlags,
0,
FILE_OPEN,
IoFlags,
NULL,
0);
}
#if DBG
else {
CmKdPrintEx((DPFLTR_CONFIG_ID,DPFLTR_ERROR_LEVEL,"ZwSetInformationFile failed with IO status %lx\n",Status));
}
CmKdPrintEx((DPFLTR_CONFIG_ID,DPFLTR_ERROR_LEVEL,"CmpOpenFileWithExtremePrejudice returns with IO status %lx\n",Status));
#endif
return(Status);
}