External/WinRing0/OpenLibSys.c
author StephaneLenclud
Sun, 03 Feb 2013 18:01:50 +0100
branchMiniDisplay
changeset 433 090259cfd699
permissions -rw-r--r--
Adding SoundGraphDisplay and SensorFrontView classes.
They were respectively based on SystemTray and SensorNotifyIcon.
SoundGraphDisplay is now able to load iMONDisplay.dll providing it lives on your PATH.
Adding option to sensor context menu for adding it into FrontView.
     1 //-----------------------------------------------------------------------------
     2 //     Author : hiyohiyo
     3 //       Mail : hiyohiyo@crystalmark.info
     4 //        Web : http://openlibsys.org/
     5 //    License : The modified BSD license
     6 //
     7 //                     Copyright 2007-2008 OpenLibSys.org. All rights reserved.
     8 //-----------------------------------------------------------------------------
     9 
    10 #include <ntddk.h>
    11 #include <stddef.h>
    12 #include "OpenLibSys.h"
    13 
    14 //-----------------------------------------------------------------------------
    15 //
    16 // Global
    17 //
    18 //-----------------------------------------------------------------------------
    19 
    20 static ULONG refCount;
    21 
    22 //-----------------------------------------------------------------------------
    23 //
    24 // Classic NT driver
    25 // DriverEntry / OlsDispatch / Unload
    26 //
    27 //-----------------------------------------------------------------------------
    28 
    29 NTSTATUS
    30 DriverEntry(
    31 	IN PDRIVER_OBJECT  DriverObject,
    32 	IN PUNICODE_STRING RegistryPath
    33 	)
    34 
    35 /*
    36 
    37 Return Value:
    38 
    39 	STATUS_SUCCESS if the driver initialized correctly, otherwise an erroror
    40 	indicating the reason for failure.
    41 */
    42 
    43 {
    44 	NTSTATUS		status;
    45 	UNICODE_STRING  ntDeviceName;
    46 	UNICODE_STRING  win32DeviceName;
    47 	PDEVICE_OBJECT  deviceObject = NULL;
    48 
    49 	RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
    50 
    51 	status = IoCreateDevice(
    52 		DriverObject,					// Our Driver Object
    53 		0,								// We don't use a device extension
    54 		&ntDeviceName,					// Device name 
    55 		OLS_TYPE,						// Device type
    56 		FILE_DEVICE_SECURE_OPEN,		// Device characteristics
    57 		FALSE,							// Not an exclusive device
    58 		&deviceObject );				// Returned ptr to Device Object
    59 
    60 	if(!NT_SUCCESS(status))
    61 	{
    62 		refCount = (ULONG)-1;
    63 		return status;
    64 	}
    65 	else
    66 	{
    67 		refCount = 0;
    68 	}
    69 
    70 	// Initialize the driver object with this driver's entry points.
    71 	DriverObject->MajorFunction[IRP_MJ_CREATE] = OlsDispatch;
    72 	DriverObject->MajorFunction[IRP_MJ_CLOSE] = OlsDispatch;
    73 	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OlsDispatch;
    74 	DriverObject->DriverUnload = Unload;
    75 
    76 	// Initialize a Unicode String containing the Win32 name for our device.
    77 	RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
    78 
    79 	// Create a symbolic link between our device name  and the Win32 name
    80 	status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);
    81 
    82 	if (!NT_SUCCESS(status))
    83 	{
    84 		// Delete everything that this routine has allocated.
    85 		IoDeleteDevice( deviceObject );
    86 	}
    87 
    88 	return status;
    89 }
    90 
    91 NTSTATUS
    92 OlsDispatch(
    93 	IN	PDEVICE_OBJECT pDO,
    94 	IN	PIRP pIrp
    95 	)
    96 
    97 /*++
    98 
    99 Routine Description:
   100 	This routine is the dispatch handler for the driver.  It is responsible
   101 	for processing the IRPs.
   102 
   103 Arguments:
   104 	
   105 	pDO - Pointer to device object.
   106 
   107 	pIrp - Pointer to the current IRP.
   108 
   109 Return Value:
   110 
   111 	STATUS_SUCCESS if the IRP was processed successfully, otherwise an erroror
   112 	indicating the reason for failure.
   113 
   114 --*/
   115 
   116 {
   117 	PIO_STACK_LOCATION pIrpStack;
   118 	NTSTATUS status;
   119 	int index;
   120 
   121 	//  Initialize the irp info field.
   122 	//	  This is used to return the number of bytes transfered.
   123 	pIrp->IoStatus.Information = 0;
   124 	pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
   125 
   126 	//  Set default return status
   127 	status = STATUS_NOT_IMPLEMENTED;
   128 
   129 	// Dispatch based on major fcn code.
   130 	switch(pIrpStack->MajorFunction)
   131 	{
   132 		case IRP_MJ_CREATE:
   133 			if(refCount != (ULONG)-1){refCount++;}
   134 			status = STATUS_SUCCESS;
   135 			break;
   136 		case IRP_MJ_CLOSE:
   137 			if(refCount != (ULONG)-1){refCount--;}
   138 			status = STATUS_SUCCESS;
   139 			break;
   140 
   141 		case IRP_MJ_DEVICE_CONTROL:
   142 			//  Dispatch on IOCTL
   143 			switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode)
   144 			{
   145 			case IOCTL_OLS_GET_DRIVER_VERSION:
   146 				*(PULONG)pIrp->AssociatedIrp.SystemBuffer = OLS_DRIVER_VERSION;
   147 				pIrp->IoStatus.Information = 4;
   148 				status = STATUS_SUCCESS;
   149 				break;
   150 
   151 			case IOCTL_OLS_GET_REFCOUNT:
   152 				*(PULONG)pIrp->AssociatedIrp.SystemBuffer = refCount;
   153 				pIrp->IoStatus.Information = sizeof(refCount);
   154 				status = STATUS_SUCCESS;
   155 				break;
   156 
   157 			case IOCTL_OLS_READ_MSR:
   158 				status = ReadMsr(
   159 					pIrp->AssociatedIrp.SystemBuffer,
   160 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
   161 					pIrp->AssociatedIrp.SystemBuffer,
   162 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
   163 					(ULONG*)&pIrp->IoStatus.Information
   164 					);
   165 				break;
   166 			case IOCTL_OLS_WRITE_MSR:
   167 				status = WriteMsr(
   168 					pIrp->AssociatedIrp.SystemBuffer,
   169 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
   170 					pIrp->AssociatedIrp.SystemBuffer,
   171 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
   172 					(ULONG*)&pIrp->IoStatus.Information
   173 					);
   174 				break;
   175 			case IOCTL_OLS_READ_PMC:
   176 				status = ReadPmc(
   177 					pIrp->AssociatedIrp.SystemBuffer,
   178 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
   179 					pIrp->AssociatedIrp.SystemBuffer,
   180 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
   181 					(ULONG*)&pIrp->IoStatus.Information
   182 					);
   183 				break;
   184 			case IOCTL_OLS_HALT:
   185 				__halt();
   186 				status = STATUS_SUCCESS;
   187 				break;
   188 
   189 			case IOCTL_OLS_READ_IO_PORT:
   190 			case IOCTL_OLS_READ_IO_PORT_BYTE:
   191 			case IOCTL_OLS_READ_IO_PORT_WORD:
   192 			case IOCTL_OLS_READ_IO_PORT_DWORD:
   193 				status = ReadIoPort(
   194 					pIrpStack->Parameters.DeviceIoControl.IoControlCode,
   195 					pIrp->AssociatedIrp.SystemBuffer,
   196 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
   197 					pIrp->AssociatedIrp.SystemBuffer,
   198 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
   199 					(ULONG*)&pIrp->IoStatus.Information
   200 					);
   201 				break;
   202 			case IOCTL_OLS_WRITE_IO_PORT:
   203 			case IOCTL_OLS_WRITE_IO_PORT_BYTE:
   204 			case IOCTL_OLS_WRITE_IO_PORT_WORD:
   205 			case IOCTL_OLS_WRITE_IO_PORT_DWORD:
   206 				status = WriteIoPort(
   207 					pIrpStack->Parameters.DeviceIoControl.IoControlCode,
   208 					pIrp->AssociatedIrp.SystemBuffer,
   209 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
   210 					pIrp->AssociatedIrp.SystemBuffer,
   211 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
   212 					(ULONG*)&pIrp->IoStatus.Information
   213 					);
   214 				break;
   215 
   216 			case IOCTL_OLS_READ_PCI_CONFIG:
   217 				status = ReadPciConfig(
   218 					pIrp->AssociatedIrp.SystemBuffer,
   219 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
   220 					pIrp->AssociatedIrp.SystemBuffer,
   221 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
   222 					(ULONG*)&pIrp->IoStatus.Information
   223 					);
   224 				break;
   225 			case IOCTL_OLS_WRITE_PCI_CONFIG:
   226 				status = WritePciConfig(
   227 					pIrp->AssociatedIrp.SystemBuffer,
   228 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
   229 					pIrp->AssociatedIrp.SystemBuffer,
   230 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
   231 					(ULONG*)&pIrp->IoStatus.Information
   232 					);
   233 				break;
   234 
   235 			case IOCTL_OLS_READ_MEMORY:
   236 				status = ReadMemory(
   237 					pIrp->AssociatedIrp.SystemBuffer,
   238 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
   239 					pIrp->AssociatedIrp.SystemBuffer,
   240 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
   241 					(ULONG*)&pIrp->IoStatus.Information
   242 					);
   243 				break;
   244 			case IOCTL_OLS_WRITE_MEMORY:
   245 				status = WriteMemory(
   246 					pIrp->AssociatedIrp.SystemBuffer,
   247 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
   248 					pIrp->AssociatedIrp.SystemBuffer,
   249 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
   250 					(ULONG*)&pIrp->IoStatus.Information
   251 					);
   252 				break;
   253 
   254 
   255 			}
   256 			break;
   257 	}
   258 
   259 	// We're done with I/O request.  Record the status of the I/O action.
   260 	pIrp->IoStatus.Status = status;
   261 
   262 	// Don't boost priority when returning since this took little time.
   263 	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
   264 
   265 	return status;
   266 }
   267 
   268 VOID
   269 Unload(
   270 	PDRIVER_OBJECT DriverObject
   271 	)
   272 /*++
   273 
   274 Routine Description:
   275 
   276 	This routine is called by the I/O system to unload the driver.
   277 
   278 	Any resources previously allocated must be freed.
   279 
   280 Arguments:
   281 
   282 	DriverObject - a pointer to the object that represents our driver.
   283 
   284 Return Value:
   285 
   286 	None
   287 --*/
   288 
   289 {
   290 	PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
   291 	UNICODE_STRING win32NameString;
   292 
   293 	PAGED_CODE();
   294 
   295 	// Create counted string version of our Win32 device name.
   296 	RtlInitUnicodeString(&win32NameString, DOS_DEVICE_NAME);
   297 
   298 	// Delete the link from our device name to a name in the Win32 namespace.
   299 	IoDeleteSymbolicLink(&win32NameString);
   300 
   301 	if(deviceObject != NULL)
   302 	{
   303 		IoDeleteDevice(deviceObject);
   304 	}
   305 }
   306 
   307 //-----------------------------------------------------------------------------
   308 //
   309 // CPU
   310 //
   311 //-----------------------------------------------------------------------------
   312 
   313 NTSTATUS
   314 ReadMsr(	void	*lpInBuffer, 
   315 			ULONG	nInBufferSize, 
   316 			void	*lpOutBuffer, 
   317 			ULONG	nOutBufferSize, 
   318 			ULONG	*lpBytesReturned)
   319 {
   320 	__try
   321 	{
   322 		ULONGLONG data = __readmsr(*(ULONG*)lpInBuffer);
   323 		memcpy((PULONG)lpOutBuffer, &data, 8);
   324 		*lpBytesReturned = 8;
   325 		return STATUS_SUCCESS;
   326 	}
   327 	__except(EXCEPTION_EXECUTE_HANDLER)
   328 	{
   329 		*lpBytesReturned = 0;
   330 		return STATUS_UNSUCCESSFUL;
   331 	}
   332 }
   333 
   334 NTSTATUS
   335 WriteMsr(	void	*lpInBuffer, 
   336 			ULONG	nInBufferSize, 
   337 			void	*lpOutBuffer, 
   338 			ULONG	nOutBufferSize, 
   339 			ULONG	*lpBytesReturned)
   340 {
   341 	__try
   342 	{
   343 		OLS_WRITE_MSR_INPUT* param;
   344 		param = (OLS_WRITE_MSR_INPUT*)lpInBuffer;
   345 
   346 		__writemsr(param->Register, param->Value.QuadPart);
   347 		*lpBytesReturned = 0;
   348 		return STATUS_SUCCESS;
   349 	}
   350 	__except(EXCEPTION_EXECUTE_HANDLER)
   351 	{
   352 		*lpBytesReturned = 0;
   353 		return STATUS_UNSUCCESSFUL;
   354 	}
   355 }
   356 
   357 NTSTATUS
   358 ReadPmc(	void	*lpInBuffer, 
   359 			ULONG	nInBufferSize, 
   360 			void	*lpOutBuffer, 
   361 			ULONG	nOutBufferSize, 
   362 			ULONG	*lpBytesReturned)
   363 {
   364 	__try
   365 	{
   366 		ULONGLONG data = __readpmc(*(ULONG*)lpInBuffer);
   367 		memcpy((PULONG)lpOutBuffer, &data, 8);
   368 		*lpBytesReturned = 8;
   369 		return STATUS_SUCCESS;
   370 	}
   371 	__except(EXCEPTION_EXECUTE_HANDLER)
   372 	{
   373 		*lpBytesReturned = 0;
   374 		return STATUS_UNSUCCESSFUL;
   375 	}
   376 }
   377 
   378 //-----------------------------------------------------------------------------
   379 //
   380 // IO Port
   381 //
   382 //-----------------------------------------------------------------------------
   383 
   384 NTSTATUS
   385 ReadIoPort( ULONG	ioControlCode,
   386 			void	*lpInBuffer, 
   387 			ULONG	nInBufferSize, 
   388 			void	*lpOutBuffer, 
   389 			ULONG	nOutBufferSize, 
   390 			ULONG	*lpBytesReturned)
   391 {
   392 	ULONG nPort = *(ULONG*)lpInBuffer;
   393 
   394 	switch(ioControlCode)
   395 	{
   396 		case IOCTL_OLS_READ_IO_PORT_BYTE:
   397 			*(PUCHAR)lpOutBuffer = READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort);
   398 			break;
   399 		case IOCTL_OLS_READ_IO_PORT_WORD:
   400 			*(PUSHORT)lpOutBuffer = READ_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort);
   401 			break;
   402 		case IOCTL_OLS_READ_IO_PORT_DWORD:
   403 			*(PULONG)lpOutBuffer = READ_PORT_ULONG((PULONG)(ULONG_PTR)nPort);
   404 			break;
   405 		default:
   406 			*lpBytesReturned = 0;
   407 			return STATUS_INVALID_PARAMETER;
   408 			break;
   409 	}
   410 	
   411 	*lpBytesReturned = nInBufferSize;
   412 	return STATUS_SUCCESS;
   413 }
   414 
   415 NTSTATUS
   416 WriteIoPort(ULONG	ioControlCode,
   417 			void	*lpInBuffer, 
   418 			ULONG	nInBufferSize, 
   419 			void	*lpOutBuffer, 
   420 			ULONG	nOutBufferSize, 
   421 			ULONG	*lpBytesReturned)
   422 {
   423 	ULONG nPort;
   424 	OLS_WRITE_IO_PORT_INPUT* param;
   425 	
   426 	param = (OLS_WRITE_IO_PORT_INPUT*)lpInBuffer;
   427 	nPort = param->PortNumber;
   428 
   429 	switch(ioControlCode)
   430 	{
   431 
   432 		case IOCTL_OLS_WRITE_IO_PORT_BYTE:
   433 			WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort, param->CharData);
   434 			break;
   435 		case IOCTL_OLS_WRITE_IO_PORT_WORD:
   436 			WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort, param->ShortData);
   437 			break;
   438 		case IOCTL_OLS_WRITE_IO_PORT_DWORD:
   439 			WRITE_PORT_ULONG((PULONG)(ULONG_PTR)nPort, param->LongData);
   440 			break;
   441 		default:
   442 			return STATUS_INVALID_PARAMETER;
   443 			break;
   444 	}
   445 
   446 	return STATUS_SUCCESS;
   447 }
   448 
   449 //-----------------------------------------------------------------------------
   450 //
   451 // PCI
   452 //
   453 //-----------------------------------------------------------------------------
   454 
   455 NTSTATUS
   456 ReadPciConfig(	void	*lpInBuffer, 
   457 				ULONG	nInBufferSize, 
   458 				void	*lpOutBuffer, 
   459 				ULONG	nOutBufferSize, 
   460 				ULONG	*lpBytesReturned)
   461 {
   462 	OLS_READ_PCI_CONFIG_INPUT *param;
   463 	NTSTATUS status;
   464 
   465 	if(nInBufferSize != sizeof(OLS_READ_PCI_CONFIG_INPUT))
   466 	{
   467 		return STATUS_INVALID_PARAMETER;
   468 	}
   469 	param = (OLS_READ_PCI_CONFIG_INPUT *)lpInBuffer;
   470 
   471 	status = pciConfigRead(param->PciAddress, param->PciOffset,
   472 						lpOutBuffer, nOutBufferSize);
   473 
   474 	if(status == STATUS_SUCCESS)
   475 	{
   476 		*lpBytesReturned = nOutBufferSize;
   477 	}
   478 	else
   479 	{
   480 		*lpBytesReturned = 0;
   481 	}
   482 
   483 	return status;
   484 }
   485 
   486 NTSTATUS
   487 WritePciConfig(	void *lpInBuffer, 
   488 				ULONG nInBufferSize, 
   489 				void *lpOutBuffer, 
   490 				ULONG nOutBufferSize, 
   491 				ULONG *lpBytesReturned)
   492 
   493 {
   494 	OLS_WRITE_PCI_CONFIG_INPUT *param;
   495 	ULONG writeSize;
   496 	NTSTATUS status;
   497 
   498 	if(nInBufferSize < offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data))
   499 	{
   500 		return STATUS_INVALID_PARAMETER;
   501 	}
   502 
   503 	param = (OLS_WRITE_PCI_CONFIG_INPUT *)lpInBuffer;
   504 	writeSize = nInBufferSize - offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data);
   505 	
   506 	*lpBytesReturned = 0;
   507 
   508 	return pciConfigWrite(param->PciAddress, param->PciOffset,
   509 							&param->Data, writeSize);
   510 
   511 }
   512 
   513 //-----------------------------------------------------------------------------
   514 //
   515 // Support Function
   516 //
   517 //-----------------------------------------------------------------------------
   518 
   519 NTSTATUS pciConfigRead(ULONG pciAddress, ULONG offset, void *data, int length)
   520 {
   521 	PCI_SLOT_NUMBER slot;
   522 	int error;
   523 	ULONG busNumber;
   524 
   525 	busNumber = PciGetBus(pciAddress);
   526 	slot.u.AsULONG = 0;
   527 	slot.u.bits.DeviceNumber = PciGetDev(pciAddress);
   528 	slot.u.bits.FunctionNumber = PciGetFunc(pciAddress);
   529 	error =	HalGetBusDataByOffset(PCIConfiguration, busNumber, slot.u.AsULONG,
   530 									data, offset, length);
   531 
   532 	if(error == 0)
   533 	{
   534 		return OLS_ERROR_PCI_BUS_NOT_EXIST;
   535 	}
   536 	else if(length != 2 && error == 2)
   537 	{
   538 		return OLS_ERROR_PCI_NO_DEVICE;
   539 	}
   540 	else if(length != error)
   541 	{
   542 		return OLS_ERROR_PCI_READ_CONFIG;
   543 	}
   544 
   545 	return STATUS_SUCCESS;
   546 }
   547 
   548 NTSTATUS pciConfigWrite(ULONG pciAddress, ULONG offset, void *data, int length)
   549 {
   550 	PCI_SLOT_NUMBER slot;
   551 	int error;
   552 	ULONG busNumber;
   553 
   554 	busNumber = PciGetBus(pciAddress);
   555 
   556 	slot.u.AsULONG = 0;
   557 	slot.u.bits.DeviceNumber = PciGetDev(pciAddress);
   558 	slot.u.bits.FunctionNumber = PciGetFunc(pciAddress);
   559 	error = HalSetBusDataByOffset(PCIConfiguration, busNumber, slot.u.AsULONG,
   560 									data, offset, length);
   561 
   562 	if(error != length)
   563 	{
   564 		return OLS_ERROR_PCI_WRITE_CONFIG;
   565 	}
   566 
   567 	return STATUS_SUCCESS;
   568 }
   569 
   570 
   571 //-----------------------------------------------------------------------------
   572 //
   573 // Physical Memory
   574 //
   575 //-----------------------------------------------------------------------------
   576 
   577 NTSTATUS
   578 ReadMemory(	void	*lpInBuffer, 
   579 			ULONG	nInBufferSize, 
   580 			void	*lpOutBuffer, 
   581 			ULONG	nOutBufferSize, 
   582 			ULONG	*lpBytesReturned)
   583 {
   584 	OLS_READ_MEMORY_INPUT *param;
   585 	ULONG	size;
   586 	PHYSICAL_ADDRESS address;
   587 	PVOID	maped;
   588 	BOOLEAN	error;
   589 
   590 	if(nInBufferSize != sizeof(OLS_READ_MEMORY_INPUT))
   591 	{
   592 		return STATUS_INVALID_PARAMETER;
   593 	}
   594 
   595 	param = (OLS_READ_MEMORY_INPUT *)lpInBuffer;
   596 	size = param->UnitSize * param->Count;
   597 
   598 	if(nOutBufferSize < size)
   599 	{
   600 		return STATUS_INVALID_PARAMETER;
   601 	}
   602 
   603 	address.QuadPart = param->Address.QuadPart;
   604 
   605 #ifndef _PHYSICAL_MEMORY_SUPPORT
   606 
   607 	if(0x000C0000 > address.QuadPart 
   608 	|| (address.QuadPart + size - 1) > 0x000FFFFF)
   609 	{
   610 		return STATUS_INVALID_PARAMETER;
   611 	}
   612 
   613 #endif
   614 
   615 	maped = MmMapIoSpace(address, size, FALSE);
   616 
   617 	error = FALSE;
   618 	switch(param->UnitSize){
   619 		case 1:
   620 			READ_REGISTER_BUFFER_UCHAR(maped, lpOutBuffer, param->Count);
   621 			break;
   622 		case 2:
   623 			READ_REGISTER_BUFFER_USHORT(maped, lpOutBuffer, param->Count);
   624 			break;
   625 		case 4:
   626 			READ_REGISTER_BUFFER_ULONG(maped, lpOutBuffer, param->Count);
   627 			break;
   628 		default:
   629 			error = TRUE;
   630 			break;
   631 	}
   632 
   633 	MmUnmapIoSpace(maped, size);
   634 
   635 	if(error)
   636 	{
   637 		return STATUS_INVALID_PARAMETER;
   638 	}
   639 
   640 	*lpBytesReturned = nOutBufferSize;
   641 
   642 	return STATUS_SUCCESS;
   643 }
   644 
   645 NTSTATUS
   646 WriteMemory(void	*lpInBuffer, 
   647 			ULONG	nInBufferSize, 
   648 			void	*lpOutBuffer, 
   649 			ULONG	nOutBufferSize, 
   650 			ULONG	*lpBytesReturned)
   651 {
   652 #ifdef _PHYSICAL_MEMORY_SUPPORT
   653 
   654 	OLS_WRITE_MEMORY_INPUT *param;
   655 	ULONG size;
   656 	PHYSICAL_ADDRESS address;
   657 	PVOID	maped;
   658 	BOOLEAN	error;
   659 
   660 	if(nInBufferSize < offsetof(OLS_WRITE_MEMORY_INPUT, Data))
   661 	{
   662 		return STATUS_INVALID_PARAMETER;
   663 	}
   664 
   665 	param = (OLS_WRITE_MEMORY_INPUT *)lpInBuffer;
   666 
   667 	size = param->UnitSize * param->Count;
   668 	if (nInBufferSize < size + offsetof(OLS_WRITE_MEMORY_INPUT, Data))
   669 	{
   670 		return STATUS_INVALID_PARAMETER;
   671 	}
   672 
   673 	address.QuadPart = param->Address.QuadPart;
   674 
   675 	maped = MmMapIoSpace(address, size, FALSE);
   676 
   677 	error = FALSE;
   678 	switch(param->UnitSize){
   679 		case 1:
   680 			WRITE_REGISTER_BUFFER_UCHAR(maped, 
   681 										(UCHAR*)&param->Data, param->Count);
   682 			break;
   683 		case 2:
   684 			WRITE_REGISTER_BUFFER_USHORT(maped,
   685 										(USHORT*)&param->Data, param->Count);
   686 			break;
   687 		case 4:
   688 			WRITE_REGISTER_BUFFER_ULONG(maped,
   689 										(ULONG*)&param->Data, param->Count);
   690 			break;
   691 		default:
   692 			error = TRUE;
   693 			break;
   694 	}
   695 
   696 	MmUnmapIoSpace(maped, size);
   697 
   698 	if(error)
   699 	{
   700 		return STATUS_INVALID_PARAMETER;
   701 	}
   702 
   703 	*lpBytesReturned = 0;
   704 
   705 	return STATUS_SUCCESS;
   706 
   707 #else
   708 
   709 	*lpBytesReturned = 0;
   710 	
   711 	return STATUS_INVALID_PARAMETER;
   712 
   713 #endif
   714 }