Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303/* * PROJECT: ReactOS Drivers * COPYRIGHT: See COPYING in the top level directory * PURPOSE: Kernel Security Support Provider Interface Driver * * PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org) */
/* INCLUDES *******************************************************************/
#include "ksecdd.h"#include <ksecioctl.h>
#define NDEBUG#include <debug.h>
/* FUNCTIONS ******************************************************************/
staticNTSTATUSKsecQueryFileInformation( PVOID InfoBuffer, FILE_INFORMATION_CLASS FileInformationClass, PSIZE_T BufferLength){ PFILE_STANDARD_INFORMATION StandardInformation;
/* Only FileStandardInformation is supported */ if (FileInformationClass != FileStandardInformation) { return STATUS_INVALID_INFO_CLASS; }
/* Validate buffer size */ if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION)) { *BufferLength = sizeof(FILE_STANDARD_INFORMATION); return STATUS_INFO_LENGTH_MISMATCH; }
/* Fill the structure */ StandardInformation = (PFILE_STANDARD_INFORMATION)InfoBuffer; StandardInformation->AllocationSize.QuadPart = 0; StandardInformation->EndOfFile.QuadPart = 0; StandardInformation->NumberOfLinks = 1; StandardInformation->DeletePending = FALSE; StandardInformation->Directory = FALSE; *BufferLength = sizeof(FILE_STANDARD_INFORMATION);
return STATUS_SUCCESS;}
staticNTSTATUSKsecQueryVolumeInformation( PVOID InfoBuffer, FS_INFORMATION_CLASS FsInformationClass, PSIZE_T BufferLength){ PFILE_FS_DEVICE_INFORMATION DeviceInformation;
/* Only FileFsDeviceInformation is supported */ if (FsInformationClass != FileFsDeviceInformation) { return STATUS_INVALID_INFO_CLASS; }
/* Validate buffer size */ if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION)) { *BufferLength = sizeof(FILE_FS_DEVICE_INFORMATION); return STATUS_INFO_LENGTH_MISMATCH; }
/* Fill the structure */ DeviceInformation = (PFILE_FS_DEVICE_INFORMATION)InfoBuffer; DeviceInformation->DeviceType = FILE_DEVICE_NULL; DeviceInformation->Characteristics = 0; *BufferLength = sizeof(FILE_FS_DEVICE_INFORMATION);
return STATUS_SUCCESS;}
staticNTSTATUSKsecDeviceControl( ULONG IoControlCode, PVOID Buffer, SIZE_T InputLength, PSIZE_T OutputLength){ NTSTATUS Status;
if ((IoControlCode == IOCTL_KSEC_RANDOM_FILL_BUFFER) || (IoControlCode == IOCTL_KSEC_ENCRYPT_SAME_PROCESS) || (IoControlCode == IOCTL_KSEC_DECRYPT_SAME_PROCESS) || (IoControlCode == IOCTL_KSEC_ENCRYPT_CROSS_PROCESS) || (IoControlCode == IOCTL_KSEC_DECRYPT_CROSS_PROCESS) || (IoControlCode == IOCTL_KSEC_ENCRYPT_SAME_LOGON) || (IoControlCode == IOCTL_KSEC_DECRYPT_SAME_LOGON)) { /* Make sure we have a valid output buffer */ if ((Buffer == NULL) || (OutputLength == NULL)) { return STATUS_INVALID_PARAMETER; }
/* Check if the input is smaller than the output */ if (InputLength < *OutputLength) { /* We might have uninitialized memory, zero it out */ RtlSecureZeroMemory((PUCHAR)Buffer + InputLength, *OutputLength - InputLength); } }
/* Check ioctl code */ switch (IoControlCode) { case IOCTL_KSEC_REGISTER_LSA_PROCESS:
Status = STATUS_SUCCESS; break;
case IOCTL_KSEC_RANDOM_FILL_BUFFER:
Status = KsecGenRandom(Buffer, *OutputLength); break;
case IOCTL_KSEC_ENCRYPT_SAME_PROCESS:
Status = KsecEncryptMemory(Buffer, *OutputLength, RTL_ENCRYPT_OPTION_SAME_PROCESS); break;
case IOCTL_KSEC_DECRYPT_SAME_PROCESS:
Status = KsecDecryptMemory(Buffer, *OutputLength, RTL_ENCRYPT_OPTION_SAME_PROCESS); break;
case IOCTL_KSEC_ENCRYPT_CROSS_PROCESS:
Status = KsecEncryptMemory(Buffer, *OutputLength, RTL_ENCRYPT_OPTION_CROSS_PROCESS); break;
case IOCTL_KSEC_DECRYPT_CROSS_PROCESS:
Status = KsecDecryptMemory(Buffer, *OutputLength, RTL_ENCRYPT_OPTION_CROSS_PROCESS); break;
case IOCTL_KSEC_ENCRYPT_SAME_LOGON:
Status = KsecEncryptMemory(Buffer, *OutputLength, RTL_ENCRYPT_OPTION_SAME_LOGON); break;
case IOCTL_KSEC_DECRYPT_SAME_LOGON:
Status = KsecDecryptMemory(Buffer, *OutputLength, RTL_ENCRYPT_OPTION_SAME_LOGON); break;
default: DPRINT1("Unhandled control code 0x%lx\n", IoControlCode); __debugbreak(); return STATUS_INVALID_PARAMETER; }
return Status;}
NTSTATUSNTAPIKsecDdDispatch( PDEVICE_OBJECT DeviceObject, PIRP Irp){ PIO_STACK_LOCATION IoStackLocation; ULONG_PTR Information; NTSTATUS Status; PVOID Buffer; SIZE_T InputLength, OutputLength; FILE_INFORMATION_CLASS FileInfoClass; FS_INFORMATION_CLASS FsInfoClass; ULONG IoControlCode;
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
switch (IoStackLocation->MajorFunction) { case IRP_MJ_CREATE: case IRP_MJ_CLOSE:
/* Just return success */ Status = STATUS_SUCCESS; Information = 0; break;
case IRP_MJ_READ:
/* There is nothing to read */ Status = STATUS_END_OF_FILE; Information = 0; break;
case IRP_MJ_WRITE:
/* Pretend to have written everything */ Status = STATUS_SUCCESS; Information = IoStackLocation->Parameters.Write.Length; break;
case IRP_MJ_QUERY_INFORMATION:
/* Extract the parameters */ Buffer = Irp->AssociatedIrp.SystemBuffer; OutputLength = IoStackLocation->Parameters.QueryFile.Length; FileInfoClass = IoStackLocation->Parameters.QueryFile.FileInformationClass;
/* Call the internal function */ Status = KsecQueryFileInformation(Buffer, FileInfoClass, &OutputLength); Information = OutputLength; break;
case IRP_MJ_QUERY_VOLUME_INFORMATION:
/* Extract the parameters */ Buffer = Irp->AssociatedIrp.SystemBuffer; OutputLength = IoStackLocation->Parameters.QueryVolume.Length; FsInfoClass = IoStackLocation->Parameters.QueryVolume.FsInformationClass;
/* Call the internal function */ Status = KsecQueryVolumeInformation(Buffer, FsInfoClass, &OutputLength); Information = OutputLength; break;
case IRP_MJ_DEVICE_CONTROL:
/* Extract the parameters */ InputLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength; OutputLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength; IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
/* Check for METHOD_OUT_DIRECT method */ if ((METHOD_FROM_CTL_CODE(IoControlCode) == METHOD_OUT_DIRECT) && (OutputLength != 0)) { /* Use the provided MDL */ OutputLength = Irp->MdlAddress->ByteCount; Buffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); if (Buffer == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; Information = 0; break; } } else { /* Otherwise this is METHOD_BUFFERED, use the SystemBuffer */ Buffer = Irp->AssociatedIrp.SystemBuffer; }
/* Call the internal function */ Status = KsecDeviceControl(IoControlCode, Buffer, InputLength, &OutputLength); Information = OutputLength; break;
default: DPRINT1("Unhandled major function %lu!\n", IoStackLocation->MajorFunction); ASSERT(FALSE); return STATUS_INVALID_DEVICE_REQUEST; }
/* Return the information */ Irp->IoStatus.Status = Status; Irp->IoStatus.Information = Information;
/* Complete the request */ IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;}