1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/External/WinRing0/OpenLibSys.c Sun May 27 16:50:01 2012 +0000
1.3 @@ -0,0 +1,714 @@
1.4 +//-----------------------------------------------------------------------------
1.5 +// Author : hiyohiyo
1.6 +// Mail : hiyohiyo@crystalmark.info
1.7 +// Web : http://openlibsys.org/
1.8 +// License : The modified BSD license
1.9 +//
1.10 +// Copyright 2007-2008 OpenLibSys.org. All rights reserved.
1.11 +//-----------------------------------------------------------------------------
1.12 +
1.13 +#include <ntddk.h>
1.14 +#include <stddef.h>
1.15 +#include "OpenLibSys.h"
1.16 +
1.17 +//-----------------------------------------------------------------------------
1.18 +//
1.19 +// Global
1.20 +//
1.21 +//-----------------------------------------------------------------------------
1.22 +
1.23 +static ULONG refCount;
1.24 +
1.25 +//-----------------------------------------------------------------------------
1.26 +//
1.27 +// Classic NT driver
1.28 +// DriverEntry / OlsDispatch / Unload
1.29 +//
1.30 +//-----------------------------------------------------------------------------
1.31 +
1.32 +NTSTATUS
1.33 +DriverEntry(
1.34 + IN PDRIVER_OBJECT DriverObject,
1.35 + IN PUNICODE_STRING RegistryPath
1.36 + )
1.37 +
1.38 +/*
1.39 +
1.40 +Return Value:
1.41 +
1.42 + STATUS_SUCCESS if the driver initialized correctly, otherwise an erroror
1.43 + indicating the reason for failure.
1.44 +*/
1.45 +
1.46 +{
1.47 + NTSTATUS status;
1.48 + UNICODE_STRING ntDeviceName;
1.49 + UNICODE_STRING win32DeviceName;
1.50 + PDEVICE_OBJECT deviceObject = NULL;
1.51 +
1.52 + RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
1.53 +
1.54 + status = IoCreateDevice(
1.55 + DriverObject, // Our Driver Object
1.56 + 0, // We don't use a device extension
1.57 + &ntDeviceName, // Device name
1.58 + OLS_TYPE, // Device type
1.59 + FILE_DEVICE_SECURE_OPEN, // Device characteristics
1.60 + FALSE, // Not an exclusive device
1.61 + &deviceObject ); // Returned ptr to Device Object
1.62 +
1.63 + if(!NT_SUCCESS(status))
1.64 + {
1.65 + refCount = (ULONG)-1;
1.66 + return status;
1.67 + }
1.68 + else
1.69 + {
1.70 + refCount = 0;
1.71 + }
1.72 +
1.73 + // Initialize the driver object with this driver's entry points.
1.74 + DriverObject->MajorFunction[IRP_MJ_CREATE] = OlsDispatch;
1.75 + DriverObject->MajorFunction[IRP_MJ_CLOSE] = OlsDispatch;
1.76 + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OlsDispatch;
1.77 + DriverObject->DriverUnload = Unload;
1.78 +
1.79 + // Initialize a Unicode String containing the Win32 name for our device.
1.80 + RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
1.81 +
1.82 + // Create a symbolic link between our device name and the Win32 name
1.83 + status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);
1.84 +
1.85 + if (!NT_SUCCESS(status))
1.86 + {
1.87 + // Delete everything that this routine has allocated.
1.88 + IoDeleteDevice( deviceObject );
1.89 + }
1.90 +
1.91 + return status;
1.92 +}
1.93 +
1.94 +NTSTATUS
1.95 +OlsDispatch(
1.96 + IN PDEVICE_OBJECT pDO,
1.97 + IN PIRP pIrp
1.98 + )
1.99 +
1.100 +/*++
1.101 +
1.102 +Routine Description:
1.103 + This routine is the dispatch handler for the driver. It is responsible
1.104 + for processing the IRPs.
1.105 +
1.106 +Arguments:
1.107 +
1.108 + pDO - Pointer to device object.
1.109 +
1.110 + pIrp - Pointer to the current IRP.
1.111 +
1.112 +Return Value:
1.113 +
1.114 + STATUS_SUCCESS if the IRP was processed successfully, otherwise an erroror
1.115 + indicating the reason for failure.
1.116 +
1.117 +--*/
1.118 +
1.119 +{
1.120 + PIO_STACK_LOCATION pIrpStack;
1.121 + NTSTATUS status;
1.122 + int index;
1.123 +
1.124 + // Initialize the irp info field.
1.125 + // This is used to return the number of bytes transfered.
1.126 + pIrp->IoStatus.Information = 0;
1.127 + pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
1.128 +
1.129 + // Set default return status
1.130 + status = STATUS_NOT_IMPLEMENTED;
1.131 +
1.132 + // Dispatch based on major fcn code.
1.133 + switch(pIrpStack->MajorFunction)
1.134 + {
1.135 + case IRP_MJ_CREATE:
1.136 + if(refCount != (ULONG)-1){refCount++;}
1.137 + status = STATUS_SUCCESS;
1.138 + break;
1.139 + case IRP_MJ_CLOSE:
1.140 + if(refCount != (ULONG)-1){refCount--;}
1.141 + status = STATUS_SUCCESS;
1.142 + break;
1.143 +
1.144 + case IRP_MJ_DEVICE_CONTROL:
1.145 + // Dispatch on IOCTL
1.146 + switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode)
1.147 + {
1.148 + case IOCTL_OLS_GET_DRIVER_VERSION:
1.149 + *(PULONG)pIrp->AssociatedIrp.SystemBuffer = OLS_DRIVER_VERSION;
1.150 + pIrp->IoStatus.Information = 4;
1.151 + status = STATUS_SUCCESS;
1.152 + break;
1.153 +
1.154 + case IOCTL_OLS_GET_REFCOUNT:
1.155 + *(PULONG)pIrp->AssociatedIrp.SystemBuffer = refCount;
1.156 + pIrp->IoStatus.Information = sizeof(refCount);
1.157 + status = STATUS_SUCCESS;
1.158 + break;
1.159 +
1.160 + case IOCTL_OLS_READ_MSR:
1.161 + status = ReadMsr(
1.162 + pIrp->AssociatedIrp.SystemBuffer,
1.163 + pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
1.164 + pIrp->AssociatedIrp.SystemBuffer,
1.165 + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
1.166 + (ULONG*)&pIrp->IoStatus.Information
1.167 + );
1.168 + break;
1.169 + case IOCTL_OLS_WRITE_MSR:
1.170 + status = WriteMsr(
1.171 + pIrp->AssociatedIrp.SystemBuffer,
1.172 + pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
1.173 + pIrp->AssociatedIrp.SystemBuffer,
1.174 + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
1.175 + (ULONG*)&pIrp->IoStatus.Information
1.176 + );
1.177 + break;
1.178 + case IOCTL_OLS_READ_PMC:
1.179 + status = ReadPmc(
1.180 + pIrp->AssociatedIrp.SystemBuffer,
1.181 + pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
1.182 + pIrp->AssociatedIrp.SystemBuffer,
1.183 + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
1.184 + (ULONG*)&pIrp->IoStatus.Information
1.185 + );
1.186 + break;
1.187 + case IOCTL_OLS_HALT:
1.188 + __halt();
1.189 + status = STATUS_SUCCESS;
1.190 + break;
1.191 +
1.192 + case IOCTL_OLS_READ_IO_PORT:
1.193 + case IOCTL_OLS_READ_IO_PORT_BYTE:
1.194 + case IOCTL_OLS_READ_IO_PORT_WORD:
1.195 + case IOCTL_OLS_READ_IO_PORT_DWORD:
1.196 + status = ReadIoPort(
1.197 + pIrpStack->Parameters.DeviceIoControl.IoControlCode,
1.198 + pIrp->AssociatedIrp.SystemBuffer,
1.199 + pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
1.200 + pIrp->AssociatedIrp.SystemBuffer,
1.201 + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
1.202 + (ULONG*)&pIrp->IoStatus.Information
1.203 + );
1.204 + break;
1.205 + case IOCTL_OLS_WRITE_IO_PORT:
1.206 + case IOCTL_OLS_WRITE_IO_PORT_BYTE:
1.207 + case IOCTL_OLS_WRITE_IO_PORT_WORD:
1.208 + case IOCTL_OLS_WRITE_IO_PORT_DWORD:
1.209 + status = WriteIoPort(
1.210 + pIrpStack->Parameters.DeviceIoControl.IoControlCode,
1.211 + pIrp->AssociatedIrp.SystemBuffer,
1.212 + pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
1.213 + pIrp->AssociatedIrp.SystemBuffer,
1.214 + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
1.215 + (ULONG*)&pIrp->IoStatus.Information
1.216 + );
1.217 + break;
1.218 +
1.219 + case IOCTL_OLS_READ_PCI_CONFIG:
1.220 + status = ReadPciConfig(
1.221 + pIrp->AssociatedIrp.SystemBuffer,
1.222 + pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
1.223 + pIrp->AssociatedIrp.SystemBuffer,
1.224 + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
1.225 + (ULONG*)&pIrp->IoStatus.Information
1.226 + );
1.227 + break;
1.228 + case IOCTL_OLS_WRITE_PCI_CONFIG:
1.229 + status = WritePciConfig(
1.230 + pIrp->AssociatedIrp.SystemBuffer,
1.231 + pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
1.232 + pIrp->AssociatedIrp.SystemBuffer,
1.233 + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
1.234 + (ULONG*)&pIrp->IoStatus.Information
1.235 + );
1.236 + break;
1.237 +
1.238 + case IOCTL_OLS_READ_MEMORY:
1.239 + status = ReadMemory(
1.240 + pIrp->AssociatedIrp.SystemBuffer,
1.241 + pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
1.242 + pIrp->AssociatedIrp.SystemBuffer,
1.243 + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
1.244 + (ULONG*)&pIrp->IoStatus.Information
1.245 + );
1.246 + break;
1.247 + case IOCTL_OLS_WRITE_MEMORY:
1.248 + status = WriteMemory(
1.249 + pIrp->AssociatedIrp.SystemBuffer,
1.250 + pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
1.251 + pIrp->AssociatedIrp.SystemBuffer,
1.252 + pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
1.253 + (ULONG*)&pIrp->IoStatus.Information
1.254 + );
1.255 + break;
1.256 +
1.257 +
1.258 + }
1.259 + break;
1.260 + }
1.261 +
1.262 + // We're done with I/O request. Record the status of the I/O action.
1.263 + pIrp->IoStatus.Status = status;
1.264 +
1.265 + // Don't boost priority when returning since this took little time.
1.266 + IoCompleteRequest(pIrp, IO_NO_INCREMENT);
1.267 +
1.268 + return status;
1.269 +}
1.270 +
1.271 +VOID
1.272 +Unload(
1.273 + PDRIVER_OBJECT DriverObject
1.274 + )
1.275 +/*++
1.276 +
1.277 +Routine Description:
1.278 +
1.279 + This routine is called by the I/O system to unload the driver.
1.280 +
1.281 + Any resources previously allocated must be freed.
1.282 +
1.283 +Arguments:
1.284 +
1.285 + DriverObject - a pointer to the object that represents our driver.
1.286 +
1.287 +Return Value:
1.288 +
1.289 + None
1.290 +--*/
1.291 +
1.292 +{
1.293 + PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
1.294 + UNICODE_STRING win32NameString;
1.295 +
1.296 + PAGED_CODE();
1.297 +
1.298 + // Create counted string version of our Win32 device name.
1.299 + RtlInitUnicodeString(&win32NameString, DOS_DEVICE_NAME);
1.300 +
1.301 + // Delete the link from our device name to a name in the Win32 namespace.
1.302 + IoDeleteSymbolicLink(&win32NameString);
1.303 +
1.304 + if(deviceObject != NULL)
1.305 + {
1.306 + IoDeleteDevice(deviceObject);
1.307 + }
1.308 +}
1.309 +
1.310 +//-----------------------------------------------------------------------------
1.311 +//
1.312 +// CPU
1.313 +//
1.314 +//-----------------------------------------------------------------------------
1.315 +
1.316 +NTSTATUS
1.317 +ReadMsr( void *lpInBuffer,
1.318 + ULONG nInBufferSize,
1.319 + void *lpOutBuffer,
1.320 + ULONG nOutBufferSize,
1.321 + ULONG *lpBytesReturned)
1.322 +{
1.323 + __try
1.324 + {
1.325 + ULONGLONG data = __readmsr(*(ULONG*)lpInBuffer);
1.326 + memcpy((PULONG)lpOutBuffer, &data, 8);
1.327 + *lpBytesReturned = 8;
1.328 + return STATUS_SUCCESS;
1.329 + }
1.330 + __except(EXCEPTION_EXECUTE_HANDLER)
1.331 + {
1.332 + *lpBytesReturned = 0;
1.333 + return STATUS_UNSUCCESSFUL;
1.334 + }
1.335 +}
1.336 +
1.337 +NTSTATUS
1.338 +WriteMsr( void *lpInBuffer,
1.339 + ULONG nInBufferSize,
1.340 + void *lpOutBuffer,
1.341 + ULONG nOutBufferSize,
1.342 + ULONG *lpBytesReturned)
1.343 +{
1.344 + __try
1.345 + {
1.346 + OLS_WRITE_MSR_INPUT* param;
1.347 + param = (OLS_WRITE_MSR_INPUT*)lpInBuffer;
1.348 +
1.349 + __writemsr(param->Register, param->Value.QuadPart);
1.350 + *lpBytesReturned = 0;
1.351 + return STATUS_SUCCESS;
1.352 + }
1.353 + __except(EXCEPTION_EXECUTE_HANDLER)
1.354 + {
1.355 + *lpBytesReturned = 0;
1.356 + return STATUS_UNSUCCESSFUL;
1.357 + }
1.358 +}
1.359 +
1.360 +NTSTATUS
1.361 +ReadPmc( void *lpInBuffer,
1.362 + ULONG nInBufferSize,
1.363 + void *lpOutBuffer,
1.364 + ULONG nOutBufferSize,
1.365 + ULONG *lpBytesReturned)
1.366 +{
1.367 + __try
1.368 + {
1.369 + ULONGLONG data = __readpmc(*(ULONG*)lpInBuffer);
1.370 + memcpy((PULONG)lpOutBuffer, &data, 8);
1.371 + *lpBytesReturned = 8;
1.372 + return STATUS_SUCCESS;
1.373 + }
1.374 + __except(EXCEPTION_EXECUTE_HANDLER)
1.375 + {
1.376 + *lpBytesReturned = 0;
1.377 + return STATUS_UNSUCCESSFUL;
1.378 + }
1.379 +}
1.380 +
1.381 +//-----------------------------------------------------------------------------
1.382 +//
1.383 +// IO Port
1.384 +//
1.385 +//-----------------------------------------------------------------------------
1.386 +
1.387 +NTSTATUS
1.388 +ReadIoPort( ULONG ioControlCode,
1.389 + void *lpInBuffer,
1.390 + ULONG nInBufferSize,
1.391 + void *lpOutBuffer,
1.392 + ULONG nOutBufferSize,
1.393 + ULONG *lpBytesReturned)
1.394 +{
1.395 + ULONG nPort = *(ULONG*)lpInBuffer;
1.396 +
1.397 + switch(ioControlCode)
1.398 + {
1.399 + case IOCTL_OLS_READ_IO_PORT_BYTE:
1.400 + *(PUCHAR)lpOutBuffer = READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort);
1.401 + break;
1.402 + case IOCTL_OLS_READ_IO_PORT_WORD:
1.403 + *(PUSHORT)lpOutBuffer = READ_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort);
1.404 + break;
1.405 + case IOCTL_OLS_READ_IO_PORT_DWORD:
1.406 + *(PULONG)lpOutBuffer = READ_PORT_ULONG((PULONG)(ULONG_PTR)nPort);
1.407 + break;
1.408 + default:
1.409 + *lpBytesReturned = 0;
1.410 + return STATUS_INVALID_PARAMETER;
1.411 + break;
1.412 + }
1.413 +
1.414 + *lpBytesReturned = nInBufferSize;
1.415 + return STATUS_SUCCESS;
1.416 +}
1.417 +
1.418 +NTSTATUS
1.419 +WriteIoPort(ULONG ioControlCode,
1.420 + void *lpInBuffer,
1.421 + ULONG nInBufferSize,
1.422 + void *lpOutBuffer,
1.423 + ULONG nOutBufferSize,
1.424 + ULONG *lpBytesReturned)
1.425 +{
1.426 + ULONG nPort;
1.427 + OLS_WRITE_IO_PORT_INPUT* param;
1.428 +
1.429 + param = (OLS_WRITE_IO_PORT_INPUT*)lpInBuffer;
1.430 + nPort = param->PortNumber;
1.431 +
1.432 + switch(ioControlCode)
1.433 + {
1.434 +
1.435 + case IOCTL_OLS_WRITE_IO_PORT_BYTE:
1.436 + WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort, param->CharData);
1.437 + break;
1.438 + case IOCTL_OLS_WRITE_IO_PORT_WORD:
1.439 + WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort, param->ShortData);
1.440 + break;
1.441 + case IOCTL_OLS_WRITE_IO_PORT_DWORD:
1.442 + WRITE_PORT_ULONG((PULONG)(ULONG_PTR)nPort, param->LongData);
1.443 + break;
1.444 + default:
1.445 + return STATUS_INVALID_PARAMETER;
1.446 + break;
1.447 + }
1.448 +
1.449 + return STATUS_SUCCESS;
1.450 +}
1.451 +
1.452 +//-----------------------------------------------------------------------------
1.453 +//
1.454 +// PCI
1.455 +//
1.456 +//-----------------------------------------------------------------------------
1.457 +
1.458 +NTSTATUS
1.459 +ReadPciConfig( void *lpInBuffer,
1.460 + ULONG nInBufferSize,
1.461 + void *lpOutBuffer,
1.462 + ULONG nOutBufferSize,
1.463 + ULONG *lpBytesReturned)
1.464 +{
1.465 + OLS_READ_PCI_CONFIG_INPUT *param;
1.466 + NTSTATUS status;
1.467 +
1.468 + if(nInBufferSize != sizeof(OLS_READ_PCI_CONFIG_INPUT))
1.469 + {
1.470 + return STATUS_INVALID_PARAMETER;
1.471 + }
1.472 + param = (OLS_READ_PCI_CONFIG_INPUT *)lpInBuffer;
1.473 +
1.474 + status = pciConfigRead(param->PciAddress, param->PciOffset,
1.475 + lpOutBuffer, nOutBufferSize);
1.476 +
1.477 + if(status == STATUS_SUCCESS)
1.478 + {
1.479 + *lpBytesReturned = nOutBufferSize;
1.480 + }
1.481 + else
1.482 + {
1.483 + *lpBytesReturned = 0;
1.484 + }
1.485 +
1.486 + return status;
1.487 +}
1.488 +
1.489 +NTSTATUS
1.490 +WritePciConfig( void *lpInBuffer,
1.491 + ULONG nInBufferSize,
1.492 + void *lpOutBuffer,
1.493 + ULONG nOutBufferSize,
1.494 + ULONG *lpBytesReturned)
1.495 +
1.496 +{
1.497 + OLS_WRITE_PCI_CONFIG_INPUT *param;
1.498 + ULONG writeSize;
1.499 + NTSTATUS status;
1.500 +
1.501 + if(nInBufferSize < offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data))
1.502 + {
1.503 + return STATUS_INVALID_PARAMETER;
1.504 + }
1.505 +
1.506 + param = (OLS_WRITE_PCI_CONFIG_INPUT *)lpInBuffer;
1.507 + writeSize = nInBufferSize - offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data);
1.508 +
1.509 + *lpBytesReturned = 0;
1.510 +
1.511 + return pciConfigWrite(param->PciAddress, param->PciOffset,
1.512 + ¶m->Data, writeSize);
1.513 +
1.514 +}
1.515 +
1.516 +//-----------------------------------------------------------------------------
1.517 +//
1.518 +// Support Function
1.519 +//
1.520 +//-----------------------------------------------------------------------------
1.521 +
1.522 +NTSTATUS pciConfigRead(ULONG pciAddress, ULONG offset, void *data, int length)
1.523 +{
1.524 + PCI_SLOT_NUMBER slot;
1.525 + int error;
1.526 + ULONG busNumber;
1.527 +
1.528 + busNumber = PciGetBus(pciAddress);
1.529 + slot.u.AsULONG = 0;
1.530 + slot.u.bits.DeviceNumber = PciGetDev(pciAddress);
1.531 + slot.u.bits.FunctionNumber = PciGetFunc(pciAddress);
1.532 + error = HalGetBusDataByOffset(PCIConfiguration, busNumber, slot.u.AsULONG,
1.533 + data, offset, length);
1.534 +
1.535 + if(error == 0)
1.536 + {
1.537 + return OLS_ERROR_PCI_BUS_NOT_EXIST;
1.538 + }
1.539 + else if(length != 2 && error == 2)
1.540 + {
1.541 + return OLS_ERROR_PCI_NO_DEVICE;
1.542 + }
1.543 + else if(length != error)
1.544 + {
1.545 + return OLS_ERROR_PCI_READ_CONFIG;
1.546 + }
1.547 +
1.548 + return STATUS_SUCCESS;
1.549 +}
1.550 +
1.551 +NTSTATUS pciConfigWrite(ULONG pciAddress, ULONG offset, void *data, int length)
1.552 +{
1.553 + PCI_SLOT_NUMBER slot;
1.554 + int error;
1.555 + ULONG busNumber;
1.556 +
1.557 + busNumber = PciGetBus(pciAddress);
1.558 +
1.559 + slot.u.AsULONG = 0;
1.560 + slot.u.bits.DeviceNumber = PciGetDev(pciAddress);
1.561 + slot.u.bits.FunctionNumber = PciGetFunc(pciAddress);
1.562 + error = HalSetBusDataByOffset(PCIConfiguration, busNumber, slot.u.AsULONG,
1.563 + data, offset, length);
1.564 +
1.565 + if(error != length)
1.566 + {
1.567 + return OLS_ERROR_PCI_WRITE_CONFIG;
1.568 + }
1.569 +
1.570 + return STATUS_SUCCESS;
1.571 +}
1.572 +
1.573 +
1.574 +//-----------------------------------------------------------------------------
1.575 +//
1.576 +// Physical Memory
1.577 +//
1.578 +//-----------------------------------------------------------------------------
1.579 +
1.580 +NTSTATUS
1.581 +ReadMemory( void *lpInBuffer,
1.582 + ULONG nInBufferSize,
1.583 + void *lpOutBuffer,
1.584 + ULONG nOutBufferSize,
1.585 + ULONG *lpBytesReturned)
1.586 +{
1.587 + OLS_READ_MEMORY_INPUT *param;
1.588 + ULONG size;
1.589 + PHYSICAL_ADDRESS address;
1.590 + PVOID maped;
1.591 + BOOLEAN error;
1.592 +
1.593 + if(nInBufferSize != sizeof(OLS_READ_MEMORY_INPUT))
1.594 + {
1.595 + return STATUS_INVALID_PARAMETER;
1.596 + }
1.597 +
1.598 + param = (OLS_READ_MEMORY_INPUT *)lpInBuffer;
1.599 + size = param->UnitSize * param->Count;
1.600 +
1.601 + if(nOutBufferSize < size)
1.602 + {
1.603 + return STATUS_INVALID_PARAMETER;
1.604 + }
1.605 +
1.606 + address.QuadPart = param->Address.QuadPart;
1.607 +
1.608 +#ifndef _PHYSICAL_MEMORY_SUPPORT
1.609 +
1.610 + if(0x000C0000 > address.QuadPart
1.611 + || (address.QuadPart + size - 1) > 0x000FFFFF)
1.612 + {
1.613 + return STATUS_INVALID_PARAMETER;
1.614 + }
1.615 +
1.616 +#endif
1.617 +
1.618 + maped = MmMapIoSpace(address, size, FALSE);
1.619 +
1.620 + error = FALSE;
1.621 + switch(param->UnitSize){
1.622 + case 1:
1.623 + READ_REGISTER_BUFFER_UCHAR(maped, lpOutBuffer, param->Count);
1.624 + break;
1.625 + case 2:
1.626 + READ_REGISTER_BUFFER_USHORT(maped, lpOutBuffer, param->Count);
1.627 + break;
1.628 + case 4:
1.629 + READ_REGISTER_BUFFER_ULONG(maped, lpOutBuffer, param->Count);
1.630 + break;
1.631 + default:
1.632 + error = TRUE;
1.633 + break;
1.634 + }
1.635 +
1.636 + MmUnmapIoSpace(maped, size);
1.637 +
1.638 + if(error)
1.639 + {
1.640 + return STATUS_INVALID_PARAMETER;
1.641 + }
1.642 +
1.643 + *lpBytesReturned = nOutBufferSize;
1.644 +
1.645 + return STATUS_SUCCESS;
1.646 +}
1.647 +
1.648 +NTSTATUS
1.649 +WriteMemory(void *lpInBuffer,
1.650 + ULONG nInBufferSize,
1.651 + void *lpOutBuffer,
1.652 + ULONG nOutBufferSize,
1.653 + ULONG *lpBytesReturned)
1.654 +{
1.655 +#ifdef _PHYSICAL_MEMORY_SUPPORT
1.656 +
1.657 + OLS_WRITE_MEMORY_INPUT *param;
1.658 + ULONG size;
1.659 + PHYSICAL_ADDRESS address;
1.660 + PVOID maped;
1.661 + BOOLEAN error;
1.662 +
1.663 + if(nInBufferSize < offsetof(OLS_WRITE_MEMORY_INPUT, Data))
1.664 + {
1.665 + return STATUS_INVALID_PARAMETER;
1.666 + }
1.667 +
1.668 + param = (OLS_WRITE_MEMORY_INPUT *)lpInBuffer;
1.669 +
1.670 + size = param->UnitSize * param->Count;
1.671 + if (nInBufferSize < size + offsetof(OLS_WRITE_MEMORY_INPUT, Data))
1.672 + {
1.673 + return STATUS_INVALID_PARAMETER;
1.674 + }
1.675 +
1.676 + address.QuadPart = param->Address.QuadPart;
1.677 +
1.678 + maped = MmMapIoSpace(address, size, FALSE);
1.679 +
1.680 + error = FALSE;
1.681 + switch(param->UnitSize){
1.682 + case 1:
1.683 + WRITE_REGISTER_BUFFER_UCHAR(maped,
1.684 + (UCHAR*)¶m->Data, param->Count);
1.685 + break;
1.686 + case 2:
1.687 + WRITE_REGISTER_BUFFER_USHORT(maped,
1.688 + (USHORT*)¶m->Data, param->Count);
1.689 + break;
1.690 + case 4:
1.691 + WRITE_REGISTER_BUFFER_ULONG(maped,
1.692 + (ULONG*)¶m->Data, param->Count);
1.693 + break;
1.694 + default:
1.695 + error = TRUE;
1.696 + break;
1.697 + }
1.698 +
1.699 + MmUnmapIoSpace(maped, size);
1.700 +
1.701 + if(error)
1.702 + {
1.703 + return STATUS_INVALID_PARAMETER;
1.704 + }
1.705 +
1.706 + *lpBytesReturned = 0;
1.707 +
1.708 + return STATUS_SUCCESS;
1.709 +
1.710 +#else
1.711 +
1.712 + *lpBytesReturned = 0;
1.713 +
1.714 + return STATUS_INVALID_PARAMETER;
1.715 +
1.716 +#endif
1.717 +}