master
c 122 lines 3.68 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 #include <ddk/ntddk.h>
4 #include <intrin.h>
5
6 #define MSR_IA32_THERM_STATUS 0x19C
7 #define MSR_DEVICE_NAME L"\\Device\\NDDrv"
8 #define MSR_DOSLINK_NAME L"\\DosDevices\\NDDrv"
9
10 #define IOCTL_MSR_READ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
11
12 typedef struct _MSR_REQUEST {
13 ULONG msr;
14 ULONG cpu;
15 ULONG low;
16 ULONG high;
17 } MSR_REQUEST, *PMSR_REQUEST;
18
19 DRIVER_UNLOAD NetdataMsrUnload;
20 DRIVER_DISPATCH NetdataMsrCreateClose;
21 DRIVER_DISPATCH NetdataMsrDeviceControl;
22
23 static UNICODE_STRING g_DeviceName = RTL_CONSTANT_STRING(MSR_DEVICE_NAME);
24 static UNICODE_STRING g_DosLinkName = RTL_CONSTANT_STRING(MSR_DOSLINK_NAME);
25
26 VOID NetdataMsrUnload(_In_ PDRIVER_OBJECT DriverObject)
27 {
28 IoDeleteSymbolicLink(&g_DosLinkName);
29
30 if (DriverObject->DeviceObject) {
31 IoDeleteDevice(DriverObject->DeviceObject);
32 }
33 }
34
35 NTSTATUS NetdataMsrCreateClose(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
36 {
37 UNREFERENCED_PARAMETER(DeviceObject);
38
39 Irp->IoStatus.Status = STATUS_SUCCESS;
40 Irp->IoStatus.Information = 0;
41 IoCompleteRequest(Irp, IO_NO_INCREMENT);
42 return STATUS_SUCCESS;
43 }
44
45 NTSTATUS NetdataMsrDeviceControl(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp)
46 {
47 UNREFERENCED_PARAMETER(DeviceObject);
48
49 PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
50 NTSTATUS status = STATUS_SUCCESS;
51 ULONG information = 0;
52
53 if (irpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_MSR_READ) {
54 if (irpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(MSR_REQUEST) ||
55 irpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MSR_REQUEST)) {
56 status = STATUS_BUFFER_TOO_SMALL;
57 } else {
58 PMSR_REQUEST req = (PMSR_REQUEST)Irp->AssociatedIrp.SystemBuffer;
59
60 ULONG maxCpus = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS);
61 if (req->cpu >= maxCpus) {
62 status = STATUS_INVALID_PARAMETER;
63 } else {
64 KAFFINITY cpuMask = 1ull << req->cpu;
65 KAFFINITY oldMask = KeSetSystemAffinityThreadEx(cpuMask);
66
67 ULONGLONG value = __readmsr(req->msr);
68 req->low = (ULONG)(value & 0xFFFFFFFF);
69 req->high = (ULONG)(value >> 32);
70 information = sizeof(MSR_REQUEST);
71
72 KeRevertToUserAffinityThreadEx(oldMask);
73 }
74 }
75 } else {
76 status = STATUS_INVALID_DEVICE_REQUEST;
77 }
78
79 Irp->IoStatus.Status = status;
80 Irp->IoStatus.Information = information;
81 IoCompleteRequest(Irp, IO_NO_INCREMENT);
82
83 return status;
84 }
85
86 NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
87 {
88 UNREFERENCED_PARAMETER(RegistryPath);
89 NTSTATUS status;
90 PDEVICE_OBJECT deviceObject = NULL;
91
92 status = IoCreateDevice(
93 DriverObject,
94 0,
95 &g_DeviceName,
96 FILE_DEVICE_UNKNOWN,
97 FILE_DEVICE_SECURE_OPEN,
98 FALSE,
99 &deviceObject
100 );
101
102 if (!NT_SUCCESS(status)) {
103 return status;
104 }
105
106 status = IoCreateSymbolicLink(&g_DosLinkName, &g_DeviceName);
107 if (!NT_SUCCESS(status)) {
108 IoDeleteDevice(deviceObject);
109 return status;
110 }
111
112 deviceObject->Flags |= DO_BUFFERED_IO;
113
114 DriverObject->MajorFunction[IRP_MJ_CREATE] = NetdataMsrCreateClose;
115 DriverObject->MajorFunction[IRP_MJ_CLOSE] = NetdataMsrCreateClose;
116 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = NetdataMsrDeviceControl;
117 DriverObject->DriverUnload = NetdataMsrUnload;
118
119 deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
120
121 return STATUS_SUCCESS;
122 }