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 |
¶m->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*)¶m->Data, param->Count);
|
moel@347
|
682 |
break;
|
moel@347
|
683 |
case 2:
|
moel@347
|
684 |
WRITE_REGISTER_BUFFER_USHORT(maped,
|
moel@347
|
685 |
(USHORT*)¶m->Data, param->Count);
|
moel@347
|
686 |
break;
|
moel@347
|
687 |
case 4:
|
moel@347
|
688 |
WRITE_REGISTER_BUFFER_ULONG(maped,
|
moel@347
|
689 |
(ULONG*)¶m->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 |
}
|