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.
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
}