diff -r f652ab1e06e2 -r d043dac9f34e External/WinRing0/OpenLibSys.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/External/WinRing0/OpenLibSys.c Sun May 27 16:50:01 2012 +0000 @@ -0,0 +1,714 @@ +//----------------------------------------------------------------------------- +// Author : hiyohiyo +// Mail : hiyohiyo@crystalmark.info +// Web : http://openlibsys.org/ +// License : The modified BSD license +// +// Copyright 2007-2008 OpenLibSys.org. All rights reserved. +//----------------------------------------------------------------------------- + +#include +#include +#include "OpenLibSys.h" + +//----------------------------------------------------------------------------- +// +// Global +// +//----------------------------------------------------------------------------- + +static ULONG refCount; + +//----------------------------------------------------------------------------- +// +// Classic NT driver +// DriverEntry / OlsDispatch / Unload +// +//----------------------------------------------------------------------------- + +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) + +/* + +Return Value: + + STATUS_SUCCESS if the driver initialized correctly, otherwise an erroror + indicating the reason for failure. +*/ + +{ + NTSTATUS status; + UNICODE_STRING ntDeviceName; + UNICODE_STRING win32DeviceName; + PDEVICE_OBJECT deviceObject = NULL; + + RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME); + + status = IoCreateDevice( + DriverObject, // Our Driver Object + 0, // We don't use a device extension + &ntDeviceName, // Device name + OLS_TYPE, // Device type + FILE_DEVICE_SECURE_OPEN, // Device characteristics + FALSE, // Not an exclusive device + &deviceObject ); // Returned ptr to Device Object + + if(!NT_SUCCESS(status)) + { + refCount = (ULONG)-1; + return status; + } + else + { + refCount = 0; + } + + // Initialize the driver object with this driver's entry points. + DriverObject->MajorFunction[IRP_MJ_CREATE] = OlsDispatch; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = OlsDispatch; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OlsDispatch; + DriverObject->DriverUnload = Unload; + + // Initialize a Unicode String containing the Win32 name for our device. + RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME); + + // Create a symbolic link between our device name and the Win32 name + status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName); + + if (!NT_SUCCESS(status)) + { + // Delete everything that this routine has allocated. + IoDeleteDevice( deviceObject ); + } + + return status; +} + +NTSTATUS +OlsDispatch( + IN PDEVICE_OBJECT pDO, + IN PIRP pIrp + ) + +/*++ + +Routine Description: + This routine is the dispatch handler for the driver. It is responsible + for processing the IRPs. + +Arguments: + + pDO - Pointer to device object. + + pIrp - Pointer to the current IRP. + +Return Value: + + STATUS_SUCCESS if the IRP was processed successfully, otherwise an erroror + indicating the reason for failure. + +--*/ + +{ + PIO_STACK_LOCATION pIrpStack; + NTSTATUS status; + int index; + + // Initialize the irp info field. + // This is used to return the number of bytes transfered. + pIrp->IoStatus.Information = 0; + pIrpStack = IoGetCurrentIrpStackLocation(pIrp); + + // Set default return status + status = STATUS_NOT_IMPLEMENTED; + + // Dispatch based on major fcn code. + switch(pIrpStack->MajorFunction) + { + case IRP_MJ_CREATE: + if(refCount != (ULONG)-1){refCount++;} + status = STATUS_SUCCESS; + break; + case IRP_MJ_CLOSE: + if(refCount != (ULONG)-1){refCount--;} + status = STATUS_SUCCESS; + break; + + case IRP_MJ_DEVICE_CONTROL: + // Dispatch on IOCTL + switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode) + { + case IOCTL_OLS_GET_DRIVER_VERSION: + *(PULONG)pIrp->AssociatedIrp.SystemBuffer = OLS_DRIVER_VERSION; + pIrp->IoStatus.Information = 4; + status = STATUS_SUCCESS; + break; + + case IOCTL_OLS_GET_REFCOUNT: + *(PULONG)pIrp->AssociatedIrp.SystemBuffer = refCount; + pIrp->IoStatus.Information = sizeof(refCount); + status = STATUS_SUCCESS; + break; + + case IOCTL_OLS_READ_MSR: + status = ReadMsr( + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.InputBufferLength, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, + (ULONG*)&pIrp->IoStatus.Information + ); + break; + case IOCTL_OLS_WRITE_MSR: + status = WriteMsr( + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.InputBufferLength, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, + (ULONG*)&pIrp->IoStatus.Information + ); + break; + case IOCTL_OLS_READ_PMC: + status = ReadPmc( + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.InputBufferLength, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, + (ULONG*)&pIrp->IoStatus.Information + ); + break; + case IOCTL_OLS_HALT: + __halt(); + status = STATUS_SUCCESS; + break; + + case IOCTL_OLS_READ_IO_PORT: + case IOCTL_OLS_READ_IO_PORT_BYTE: + case IOCTL_OLS_READ_IO_PORT_WORD: + case IOCTL_OLS_READ_IO_PORT_DWORD: + status = ReadIoPort( + pIrpStack->Parameters.DeviceIoControl.IoControlCode, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.InputBufferLength, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, + (ULONG*)&pIrp->IoStatus.Information + ); + break; + case IOCTL_OLS_WRITE_IO_PORT: + case IOCTL_OLS_WRITE_IO_PORT_BYTE: + case IOCTL_OLS_WRITE_IO_PORT_WORD: + case IOCTL_OLS_WRITE_IO_PORT_DWORD: + status = WriteIoPort( + pIrpStack->Parameters.DeviceIoControl.IoControlCode, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.InputBufferLength, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, + (ULONG*)&pIrp->IoStatus.Information + ); + break; + + case IOCTL_OLS_READ_PCI_CONFIG: + status = ReadPciConfig( + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.InputBufferLength, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, + (ULONG*)&pIrp->IoStatus.Information + ); + break; + case IOCTL_OLS_WRITE_PCI_CONFIG: + status = WritePciConfig( + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.InputBufferLength, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, + (ULONG*)&pIrp->IoStatus.Information + ); + break; + + case IOCTL_OLS_READ_MEMORY: + status = ReadMemory( + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.InputBufferLength, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, + (ULONG*)&pIrp->IoStatus.Information + ); + break; + case IOCTL_OLS_WRITE_MEMORY: + status = WriteMemory( + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.InputBufferLength, + pIrp->AssociatedIrp.SystemBuffer, + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength, + (ULONG*)&pIrp->IoStatus.Information + ); + break; + + + } + break; + } + + // We're done with I/O request. Record the status of the I/O action. + pIrp->IoStatus.Status = status; + + // Don't boost priority when returning since this took little time. + IoCompleteRequest(pIrp, IO_NO_INCREMENT); + + return status; +} + +VOID +Unload( + PDRIVER_OBJECT DriverObject + ) +/*++ + +Routine Description: + + This routine is called by the I/O system to unload the driver. + + Any resources previously allocated must be freed. + +Arguments: + + DriverObject - a pointer to the object that represents our driver. + +Return Value: + + None +--*/ + +{ + PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject; + UNICODE_STRING win32NameString; + + PAGED_CODE(); + + // Create counted string version of our Win32 device name. + RtlInitUnicodeString(&win32NameString, DOS_DEVICE_NAME); + + // Delete the link from our device name to a name in the Win32 namespace. + IoDeleteSymbolicLink(&win32NameString); + + if(deviceObject != NULL) + { + IoDeleteDevice(deviceObject); + } +} + +//----------------------------------------------------------------------------- +// +// CPU +// +//----------------------------------------------------------------------------- + +NTSTATUS +ReadMsr( void *lpInBuffer, + ULONG nInBufferSize, + void *lpOutBuffer, + ULONG nOutBufferSize, + ULONG *lpBytesReturned) +{ + __try + { + ULONGLONG data = __readmsr(*(ULONG*)lpInBuffer); + memcpy((PULONG)lpOutBuffer, &data, 8); + *lpBytesReturned = 8; + return STATUS_SUCCESS; + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + *lpBytesReturned = 0; + return STATUS_UNSUCCESSFUL; + } +} + +NTSTATUS +WriteMsr( void *lpInBuffer, + ULONG nInBufferSize, + void *lpOutBuffer, + ULONG nOutBufferSize, + ULONG *lpBytesReturned) +{ + __try + { + OLS_WRITE_MSR_INPUT* param; + param = (OLS_WRITE_MSR_INPUT*)lpInBuffer; + + __writemsr(param->Register, param->Value.QuadPart); + *lpBytesReturned = 0; + return STATUS_SUCCESS; + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + *lpBytesReturned = 0; + return STATUS_UNSUCCESSFUL; + } +} + +NTSTATUS +ReadPmc( void *lpInBuffer, + ULONG nInBufferSize, + void *lpOutBuffer, + ULONG nOutBufferSize, + ULONG *lpBytesReturned) +{ + __try + { + ULONGLONG data = __readpmc(*(ULONG*)lpInBuffer); + memcpy((PULONG)lpOutBuffer, &data, 8); + *lpBytesReturned = 8; + return STATUS_SUCCESS; + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + *lpBytesReturned = 0; + return STATUS_UNSUCCESSFUL; + } +} + +//----------------------------------------------------------------------------- +// +// IO Port +// +//----------------------------------------------------------------------------- + +NTSTATUS +ReadIoPort( ULONG ioControlCode, + void *lpInBuffer, + ULONG nInBufferSize, + void *lpOutBuffer, + ULONG nOutBufferSize, + ULONG *lpBytesReturned) +{ + ULONG nPort = *(ULONG*)lpInBuffer; + + switch(ioControlCode) + { + case IOCTL_OLS_READ_IO_PORT_BYTE: + *(PUCHAR)lpOutBuffer = READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort); + break; + case IOCTL_OLS_READ_IO_PORT_WORD: + *(PUSHORT)lpOutBuffer = READ_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort); + break; + case IOCTL_OLS_READ_IO_PORT_DWORD: + *(PULONG)lpOutBuffer = READ_PORT_ULONG((PULONG)(ULONG_PTR)nPort); + break; + default: + *lpBytesReturned = 0; + return STATUS_INVALID_PARAMETER; + break; + } + + *lpBytesReturned = nInBufferSize; + return STATUS_SUCCESS; +} + +NTSTATUS +WriteIoPort(ULONG ioControlCode, + void *lpInBuffer, + ULONG nInBufferSize, + void *lpOutBuffer, + ULONG nOutBufferSize, + ULONG *lpBytesReturned) +{ + ULONG nPort; + OLS_WRITE_IO_PORT_INPUT* param; + + param = (OLS_WRITE_IO_PORT_INPUT*)lpInBuffer; + nPort = param->PortNumber; + + switch(ioControlCode) + { + + case IOCTL_OLS_WRITE_IO_PORT_BYTE: + WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort, param->CharData); + break; + case IOCTL_OLS_WRITE_IO_PORT_WORD: + WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort, param->ShortData); + break; + case IOCTL_OLS_WRITE_IO_PORT_DWORD: + WRITE_PORT_ULONG((PULONG)(ULONG_PTR)nPort, param->LongData); + break; + default: + return STATUS_INVALID_PARAMETER; + break; + } + + return STATUS_SUCCESS; +} + +//----------------------------------------------------------------------------- +// +// PCI +// +//----------------------------------------------------------------------------- + +NTSTATUS +ReadPciConfig( void *lpInBuffer, + ULONG nInBufferSize, + void *lpOutBuffer, + ULONG nOutBufferSize, + ULONG *lpBytesReturned) +{ + OLS_READ_PCI_CONFIG_INPUT *param; + NTSTATUS status; + + if(nInBufferSize != sizeof(OLS_READ_PCI_CONFIG_INPUT)) + { + return STATUS_INVALID_PARAMETER; + } + param = (OLS_READ_PCI_CONFIG_INPUT *)lpInBuffer; + + status = pciConfigRead(param->PciAddress, param->PciOffset, + lpOutBuffer, nOutBufferSize); + + if(status == STATUS_SUCCESS) + { + *lpBytesReturned = nOutBufferSize; + } + else + { + *lpBytesReturned = 0; + } + + return status; +} + +NTSTATUS +WritePciConfig( void *lpInBuffer, + ULONG nInBufferSize, + void *lpOutBuffer, + ULONG nOutBufferSize, + ULONG *lpBytesReturned) + +{ + OLS_WRITE_PCI_CONFIG_INPUT *param; + ULONG writeSize; + NTSTATUS status; + + if(nInBufferSize < offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data)) + { + return STATUS_INVALID_PARAMETER; + } + + param = (OLS_WRITE_PCI_CONFIG_INPUT *)lpInBuffer; + writeSize = nInBufferSize - offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data); + + *lpBytesReturned = 0; + + return pciConfigWrite(param->PciAddress, param->PciOffset, + ¶m->Data, writeSize); + +} + +//----------------------------------------------------------------------------- +// +// Support Function +// +//----------------------------------------------------------------------------- + +NTSTATUS pciConfigRead(ULONG pciAddress, ULONG offset, void *data, int length) +{ + PCI_SLOT_NUMBER slot; + int error; + ULONG busNumber; + + busNumber = PciGetBus(pciAddress); + slot.u.AsULONG = 0; + slot.u.bits.DeviceNumber = PciGetDev(pciAddress); + slot.u.bits.FunctionNumber = PciGetFunc(pciAddress); + error = HalGetBusDataByOffset(PCIConfiguration, busNumber, slot.u.AsULONG, + data, offset, length); + + if(error == 0) + { + return OLS_ERROR_PCI_BUS_NOT_EXIST; + } + else if(length != 2 && error == 2) + { + return OLS_ERROR_PCI_NO_DEVICE; + } + else if(length != error) + { + return OLS_ERROR_PCI_READ_CONFIG; + } + + return STATUS_SUCCESS; +} + +NTSTATUS pciConfigWrite(ULONG pciAddress, ULONG offset, void *data, int length) +{ + PCI_SLOT_NUMBER slot; + int error; + ULONG busNumber; + + busNumber = PciGetBus(pciAddress); + + slot.u.AsULONG = 0; + slot.u.bits.DeviceNumber = PciGetDev(pciAddress); + slot.u.bits.FunctionNumber = PciGetFunc(pciAddress); + error = HalSetBusDataByOffset(PCIConfiguration, busNumber, slot.u.AsULONG, + data, offset, length); + + if(error != length) + { + return OLS_ERROR_PCI_WRITE_CONFIG; + } + + return STATUS_SUCCESS; +} + + +//----------------------------------------------------------------------------- +// +// Physical Memory +// +//----------------------------------------------------------------------------- + +NTSTATUS +ReadMemory( void *lpInBuffer, + ULONG nInBufferSize, + void *lpOutBuffer, + ULONG nOutBufferSize, + ULONG *lpBytesReturned) +{ + OLS_READ_MEMORY_INPUT *param; + ULONG size; + PHYSICAL_ADDRESS address; + PVOID maped; + BOOLEAN error; + + if(nInBufferSize != sizeof(OLS_READ_MEMORY_INPUT)) + { + return STATUS_INVALID_PARAMETER; + } + + param = (OLS_READ_MEMORY_INPUT *)lpInBuffer; + size = param->UnitSize * param->Count; + + if(nOutBufferSize < size) + { + return STATUS_INVALID_PARAMETER; + } + + address.QuadPart = param->Address.QuadPart; + +#ifndef _PHYSICAL_MEMORY_SUPPORT + + if(0x000C0000 > address.QuadPart + || (address.QuadPart + size - 1) > 0x000FFFFF) + { + return STATUS_INVALID_PARAMETER; + } + +#endif + + maped = MmMapIoSpace(address, size, FALSE); + + error = FALSE; + switch(param->UnitSize){ + case 1: + READ_REGISTER_BUFFER_UCHAR(maped, lpOutBuffer, param->Count); + break; + case 2: + READ_REGISTER_BUFFER_USHORT(maped, lpOutBuffer, param->Count); + break; + case 4: + READ_REGISTER_BUFFER_ULONG(maped, lpOutBuffer, param->Count); + break; + default: + error = TRUE; + break; + } + + MmUnmapIoSpace(maped, size); + + if(error) + { + return STATUS_INVALID_PARAMETER; + } + + *lpBytesReturned = nOutBufferSize; + + return STATUS_SUCCESS; +} + +NTSTATUS +WriteMemory(void *lpInBuffer, + ULONG nInBufferSize, + void *lpOutBuffer, + ULONG nOutBufferSize, + ULONG *lpBytesReturned) +{ +#ifdef _PHYSICAL_MEMORY_SUPPORT + + OLS_WRITE_MEMORY_INPUT *param; + ULONG size; + PHYSICAL_ADDRESS address; + PVOID maped; + BOOLEAN error; + + if(nInBufferSize < offsetof(OLS_WRITE_MEMORY_INPUT, Data)) + { + return STATUS_INVALID_PARAMETER; + } + + param = (OLS_WRITE_MEMORY_INPUT *)lpInBuffer; + + size = param->UnitSize * param->Count; + if (nInBufferSize < size + offsetof(OLS_WRITE_MEMORY_INPUT, Data)) + { + return STATUS_INVALID_PARAMETER; + } + + address.QuadPart = param->Address.QuadPart; + + maped = MmMapIoSpace(address, size, FALSE); + + error = FALSE; + switch(param->UnitSize){ + case 1: + WRITE_REGISTER_BUFFER_UCHAR(maped, + (UCHAR*)¶m->Data, param->Count); + break; + case 2: + WRITE_REGISTER_BUFFER_USHORT(maped, + (USHORT*)¶m->Data, param->Count); + break; + case 4: + WRITE_REGISTER_BUFFER_ULONG(maped, + (ULONG*)¶m->Data, param->Count); + break; + default: + error = TRUE; + break; + } + + MmUnmapIoSpace(maped, size); + + if(error) + { + return STATUS_INVALID_PARAMETER; + } + + *lpBytesReturned = 0; + + return STATUS_SUCCESS; + +#else + + *lpBytesReturned = 0; + + return STATUS_INVALID_PARAMETER; + +#endif +}