Changed the super I/O fan control: Fan controls are now always displayed, even if the value is null (as for example for ITE 87XX chips in automatic mode.
     1 //-----------------------------------------------------------------------------
 
     3 //       Mail : hiyohiyo@crystalmark.info
 
     4 //        Web : http://openlibsys.org/
 
     5 //    License : The modified BSD license
 
     7 //                     Copyright 2007-2008 OpenLibSys.org. All rights reserved.
 
     8 //-----------------------------------------------------------------------------
 
    12 #include "OpenLibSys.h"
 
    14 //-----------------------------------------------------------------------------
 
    18 //-----------------------------------------------------------------------------
 
    20 static ULONG refCount;
 
    22 //-----------------------------------------------------------------------------
 
    25 // DriverEntry / OlsDispatch / Unload
 
    27 //-----------------------------------------------------------------------------
 
    31 	IN PDRIVER_OBJECT  DriverObject,
 
    32 	IN PUNICODE_STRING RegistryPath
 
    39 	STATUS_SUCCESS if the driver initialized correctly, otherwise an erroror
 
    40 	indicating the reason for failure.
 
    45 	UNICODE_STRING  ntDeviceName;
 
    46 	UNICODE_STRING  win32DeviceName;
 
    47 	PDEVICE_OBJECT  deviceObject = NULL;
 
    49 	RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
 
    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
 
    60 	if(!NT_SUCCESS(status))
 
    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;
 
    76 	// Initialize a Unicode String containing the Win32 name for our device.
 
    77 	RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);
 
    79 	// Create a symbolic link between our device name  and the Win32 name
 
    80 	status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);
 
    82 	if (!NT_SUCCESS(status))
 
    84 		// Delete everything that this routine has allocated.
 
    85 		IoDeleteDevice( deviceObject );
 
    93 	IN	PDEVICE_OBJECT pDO,
 
   100 	This routine is the dispatch handler for the driver.  It is responsible
 
   101 	for processing the IRPs.
 
   105 	pDO - Pointer to device object.
 
   107 	pIrp - Pointer to the current IRP.
 
   111 	STATUS_SUCCESS if the IRP was processed successfully, otherwise an erroror
 
   112 	indicating the reason for failure.
 
   117 	PIO_STACK_LOCATION pIrpStack;
 
   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);
 
   126 	//  Set default return status
 
   127 	status = STATUS_NOT_IMPLEMENTED;
 
   129 	// Dispatch based on major fcn code.
 
   130 	switch(pIrpStack->MajorFunction)
 
   133 			if(refCount != (ULONG)-1){refCount++;}
 
   134 			status = STATUS_SUCCESS;
 
   137 			if(refCount != (ULONG)-1){refCount--;}
 
   138 			status = STATUS_SUCCESS;
 
   141 		case IRP_MJ_DEVICE_CONTROL:
 
   143 			switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode)
 
   145 			case IOCTL_OLS_GET_DRIVER_VERSION:
 
   146 				*(PULONG)pIrp->AssociatedIrp.SystemBuffer = OLS_DRIVER_VERSION;
 
   147 				pIrp->IoStatus.Information = 4;
 
   148 				status = STATUS_SUCCESS;
 
   151 			case IOCTL_OLS_GET_REFCOUNT:
 
   152 				*(PULONG)pIrp->AssociatedIrp.SystemBuffer = refCount;
 
   153 				pIrp->IoStatus.Information = sizeof(refCount);
 
   154 				status = STATUS_SUCCESS;
 
   157 			case IOCTL_OLS_READ_MSR:
 
   159 					pIrp->AssociatedIrp.SystemBuffer,
 
   160 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
 
   161 					pIrp->AssociatedIrp.SystemBuffer,
 
   162 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
 
   163 					(ULONG*)&pIrp->IoStatus.Information
 
   166 			case IOCTL_OLS_WRITE_MSR:
 
   168 					pIrp->AssociatedIrp.SystemBuffer,
 
   169 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
 
   170 					pIrp->AssociatedIrp.SystemBuffer,
 
   171 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
 
   172 					(ULONG*)&pIrp->IoStatus.Information
 
   175 			case IOCTL_OLS_READ_PMC:
 
   177 					pIrp->AssociatedIrp.SystemBuffer,
 
   178 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
 
   179 					pIrp->AssociatedIrp.SystemBuffer,
 
   180 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
 
   181 					(ULONG*)&pIrp->IoStatus.Information
 
   186 				status = STATUS_SUCCESS;
 
   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:
 
   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
 
   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
 
   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
 
   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
 
   235 			case IOCTL_OLS_READ_MEMORY:
 
   237 					pIrp->AssociatedIrp.SystemBuffer,
 
   238 					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
 
   239 					pIrp->AssociatedIrp.SystemBuffer,
 
   240 					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
 
   241 					(ULONG*)&pIrp->IoStatus.Information
 
   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
 
   259 	// We're done with I/O request.  Record the status of the I/O action.
 
   260 	pIrp->IoStatus.Status = status;
 
   262 	// Don't boost priority when returning since this took little time.
 
   263 	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
 
   270 	PDRIVER_OBJECT DriverObject
 
   276 	This routine is called by the I/O system to unload the driver.
 
   278 	Any resources previously allocated must be freed.
 
   282 	DriverObject - a pointer to the object that represents our driver.
 
   290 	PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
 
   291 	UNICODE_STRING win32NameString;
 
   295 	// Create counted string version of our Win32 device name.
 
   296 	RtlInitUnicodeString(&win32NameString, DOS_DEVICE_NAME);
 
   298 	// Delete the link from our device name to a name in the Win32 namespace.
 
   299 	IoDeleteSymbolicLink(&win32NameString);
 
   301 	if(deviceObject != NULL)
 
   303 		IoDeleteDevice(deviceObject);
 
   307 //-----------------------------------------------------------------------------
 
   311 //-----------------------------------------------------------------------------
 
   314 ReadMsr(	void	*lpInBuffer, 
 
   317 			ULONG	nOutBufferSize, 
 
   318 			ULONG	*lpBytesReturned)
 
   322 		ULONGLONG data = __readmsr(*(ULONG*)lpInBuffer);
 
   323 		memcpy((PULONG)lpOutBuffer, &data, 8);
 
   324 		*lpBytesReturned = 8;
 
   325 		return STATUS_SUCCESS;
 
   327 	__except(EXCEPTION_EXECUTE_HANDLER)
 
   329 		*lpBytesReturned = 0;
 
   330 		return STATUS_UNSUCCESSFUL;
 
   335 WriteMsr(	void	*lpInBuffer, 
 
   338 			ULONG	nOutBufferSize, 
 
   339 			ULONG	*lpBytesReturned)
 
   343 		OLS_WRITE_MSR_INPUT* param;
 
   344 		param = (OLS_WRITE_MSR_INPUT*)lpInBuffer;
 
   346 		__writemsr(param->Register, param->Value.QuadPart);
 
   347 		*lpBytesReturned = 0;
 
   348 		return STATUS_SUCCESS;
 
   350 	__except(EXCEPTION_EXECUTE_HANDLER)
 
   352 		*lpBytesReturned = 0;
 
   353 		return STATUS_UNSUCCESSFUL;
 
   358 ReadPmc(	void	*lpInBuffer, 
 
   361 			ULONG	nOutBufferSize, 
 
   362 			ULONG	*lpBytesReturned)
 
   366 		ULONGLONG data = __readpmc(*(ULONG*)lpInBuffer);
 
   367 		memcpy((PULONG)lpOutBuffer, &data, 8);
 
   368 		*lpBytesReturned = 8;
 
   369 		return STATUS_SUCCESS;
 
   371 	__except(EXCEPTION_EXECUTE_HANDLER)
 
   373 		*lpBytesReturned = 0;
 
   374 		return STATUS_UNSUCCESSFUL;
 
   378 //-----------------------------------------------------------------------------
 
   382 //-----------------------------------------------------------------------------
 
   385 ReadIoPort( ULONG	ioControlCode,
 
   389 			ULONG	nOutBufferSize, 
 
   390 			ULONG	*lpBytesReturned)
 
   392 	ULONG nPort = *(ULONG*)lpInBuffer;
 
   394 	switch(ioControlCode)
 
   396 		case IOCTL_OLS_READ_IO_PORT_BYTE:
 
   397 			*(PUCHAR)lpOutBuffer = READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort);
 
   399 		case IOCTL_OLS_READ_IO_PORT_WORD:
 
   400 			*(PUSHORT)lpOutBuffer = READ_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort);
 
   402 		case IOCTL_OLS_READ_IO_PORT_DWORD:
 
   403 			*(PULONG)lpOutBuffer = READ_PORT_ULONG((PULONG)(ULONG_PTR)nPort);
 
   406 			*lpBytesReturned = 0;
 
   407 			return STATUS_INVALID_PARAMETER;
 
   411 	*lpBytesReturned = nInBufferSize;
 
   412 	return STATUS_SUCCESS;
 
   416 WriteIoPort(ULONG	ioControlCode,
 
   420 			ULONG	nOutBufferSize, 
 
   421 			ULONG	*lpBytesReturned)
 
   424 	OLS_WRITE_IO_PORT_INPUT* param;
 
   426 	param = (OLS_WRITE_IO_PORT_INPUT*)lpInBuffer;
 
   427 	nPort = param->PortNumber;
 
   429 	switch(ioControlCode)
 
   432 		case IOCTL_OLS_WRITE_IO_PORT_BYTE:
 
   433 			WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort, param->CharData);
 
   435 		case IOCTL_OLS_WRITE_IO_PORT_WORD:
 
   436 			WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort, param->ShortData);
 
   438 		case IOCTL_OLS_WRITE_IO_PORT_DWORD:
 
   439 			WRITE_PORT_ULONG((PULONG)(ULONG_PTR)nPort, param->LongData);
 
   442 			return STATUS_INVALID_PARAMETER;
 
   446 	return STATUS_SUCCESS;
 
   449 //-----------------------------------------------------------------------------
 
   453 //-----------------------------------------------------------------------------
 
   456 ReadPciConfig(	void	*lpInBuffer, 
 
   459 				ULONG	nOutBufferSize, 
 
   460 				ULONG	*lpBytesReturned)
 
   462 	OLS_READ_PCI_CONFIG_INPUT *param;
 
   465 	if(nInBufferSize != sizeof(OLS_READ_PCI_CONFIG_INPUT))
 
   467 		return STATUS_INVALID_PARAMETER;
 
   469 	param = (OLS_READ_PCI_CONFIG_INPUT *)lpInBuffer;
 
   471 	status = pciConfigRead(param->PciAddress, param->PciOffset,
 
   472 						lpOutBuffer, nOutBufferSize);
 
   474 	if(status == STATUS_SUCCESS)
 
   476 		*lpBytesReturned = nOutBufferSize;
 
   480 		*lpBytesReturned = 0;
 
   487 WritePciConfig(	void *lpInBuffer, 
 
   490 				ULONG nOutBufferSize, 
 
   491 				ULONG *lpBytesReturned)
 
   494 	OLS_WRITE_PCI_CONFIG_INPUT *param;
 
   498 	if(nInBufferSize < offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data))
 
   500 		return STATUS_INVALID_PARAMETER;
 
   503 	param = (OLS_WRITE_PCI_CONFIG_INPUT *)lpInBuffer;
 
   504 	writeSize = nInBufferSize - offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data);
 
   506 	*lpBytesReturned = 0;
 
   508 	return pciConfigWrite(param->PciAddress, param->PciOffset,
 
   509 							¶m->Data, writeSize);
 
   513 //-----------------------------------------------------------------------------
 
   517 //-----------------------------------------------------------------------------
 
   519 NTSTATUS pciConfigRead(ULONG pciAddress, ULONG offset, void *data, int length)
 
   521 	PCI_SLOT_NUMBER slot;
 
   525 	busNumber = PciGetBus(pciAddress);
 
   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);
 
   534 		return OLS_ERROR_PCI_BUS_NOT_EXIST;
 
   536 	else if(length != 2 && error == 2)
 
   538 		return OLS_ERROR_PCI_NO_DEVICE;
 
   540 	else if(length != error)
 
   542 		return OLS_ERROR_PCI_READ_CONFIG;
 
   545 	return STATUS_SUCCESS;
 
   548 NTSTATUS pciConfigWrite(ULONG pciAddress, ULONG offset, void *data, int length)
 
   550 	PCI_SLOT_NUMBER slot;
 
   554 	busNumber = PciGetBus(pciAddress);
 
   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);
 
   564 		return OLS_ERROR_PCI_WRITE_CONFIG;
 
   567 	return STATUS_SUCCESS;
 
   571 //-----------------------------------------------------------------------------
 
   575 //-----------------------------------------------------------------------------
 
   578 ReadMemory(	void	*lpInBuffer, 
 
   581 			ULONG	nOutBufferSize, 
 
   582 			ULONG	*lpBytesReturned)
 
   584 	OLS_READ_MEMORY_INPUT *param;
 
   586 	PHYSICAL_ADDRESS address;
 
   590 	if(nInBufferSize != sizeof(OLS_READ_MEMORY_INPUT))
 
   592 		return STATUS_INVALID_PARAMETER;
 
   595 	param = (OLS_READ_MEMORY_INPUT *)lpInBuffer;
 
   596 	size = param->UnitSize * param->Count;
 
   598 	if(nOutBufferSize < size)
 
   600 		return STATUS_INVALID_PARAMETER;
 
   603 	address.QuadPart = param->Address.QuadPart;
 
   605 #ifndef _PHYSICAL_MEMORY_SUPPORT
 
   607 	if(0x000C0000 > address.QuadPart 
 
   608 	|| (address.QuadPart + size - 1) > 0x000FFFFF)
 
   610 		return STATUS_INVALID_PARAMETER;
 
   615 	maped = MmMapIoSpace(address, size, FALSE);
 
   618 	switch(param->UnitSize){
 
   620 			READ_REGISTER_BUFFER_UCHAR(maped, lpOutBuffer, param->Count);
 
   623 			READ_REGISTER_BUFFER_USHORT(maped, lpOutBuffer, param->Count);
 
   626 			READ_REGISTER_BUFFER_ULONG(maped, lpOutBuffer, param->Count);
 
   633 	MmUnmapIoSpace(maped, size);
 
   637 		return STATUS_INVALID_PARAMETER;
 
   640 	*lpBytesReturned = nOutBufferSize;
 
   642 	return STATUS_SUCCESS;
 
   646 WriteMemory(void	*lpInBuffer, 
 
   649 			ULONG	nOutBufferSize, 
 
   650 			ULONG	*lpBytesReturned)
 
   652 #ifdef _PHYSICAL_MEMORY_SUPPORT
 
   654 	OLS_WRITE_MEMORY_INPUT *param;
 
   656 	PHYSICAL_ADDRESS address;
 
   660 	if(nInBufferSize < offsetof(OLS_WRITE_MEMORY_INPUT, Data))
 
   662 		return STATUS_INVALID_PARAMETER;
 
   665 	param = (OLS_WRITE_MEMORY_INPUT *)lpInBuffer;
 
   667 	size = param->UnitSize * param->Count;
 
   668 	if (nInBufferSize < size + offsetof(OLS_WRITE_MEMORY_INPUT, Data))
 
   670 		return STATUS_INVALID_PARAMETER;
 
   673 	address.QuadPart = param->Address.QuadPart;
 
   675 	maped = MmMapIoSpace(address, size, FALSE);
 
   678 	switch(param->UnitSize){
 
   680 			WRITE_REGISTER_BUFFER_UCHAR(maped, 
 
   681 										(UCHAR*)¶m->Data, param->Count);
 
   684 			WRITE_REGISTER_BUFFER_USHORT(maped,
 
   685 										(USHORT*)¶m->Data, param->Count);
 
   688 			WRITE_REGISTER_BUFFER_ULONG(maped,
 
   689 										(ULONG*)¶m->Data, param->Count);
 
   696 	MmUnmapIoSpace(maped, size);
 
   700 		return STATUS_INVALID_PARAMETER;
 
   703 	*lpBytesReturned = 0;
 
   705 	return STATUS_SUCCESS;
 
   709 	*lpBytesReturned = 0;
 
   711 	return STATUS_INVALID_PARAMETER;