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