Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/avrdude/windows/giveio.c')
-rw-r--r--src/avrdude/windows/giveio.c168
1 files changed, 168 insertions, 0 deletions
diff --git a/src/avrdude/windows/giveio.c b/src/avrdude/windows/giveio.c
new file mode 100644
index 000000000..f752a2937
--- /dev/null
+++ b/src/avrdude/windows/giveio.c
@@ -0,0 +1,168 @@
+/*********************************************************************
+
+Author: Dale Roberts
+Date: 8/30/95
+Program: GIVEIO.SYS
+Compile: Use DDK BUILD facility
+
+Purpose: Give direct port I/O access to a user mode process.
+
+*********************************************************************/
+#include <ntddk.h>
+
+/*
+ * The name of our device driver.
+ */
+#define DEVICE_NAME_STRING L"giveio"
+
+/*
+ * This is the "structure" of the IOPM. It is just a simple
+ * character array of length 0x2000.
+ *
+ * This holds 8K * 8 bits -> 64K bits of the IOPM, which maps the
+ * entire 64K I/O space of the x86 processor. Any 0 bits will give
+ * access to the corresponding port for user mode processes. Any 1
+ * bits will disallow I/O access to the corresponding port.
+ */
+#define IOPM_SIZE 0x2000
+typedef UCHAR IOPM[IOPM_SIZE];
+
+/*
+ * This will hold simply an array of 0's which will be copied
+ * into our actual IOPM in the TSS by Ke386SetIoAccessMap().
+ * The memory is allocated at driver load time.
+ */
+IOPM *IOPM_local = 0;
+
+/*
+ * These are the two undocumented calls that we will use to give
+ * the calling process I/O access.
+ *
+ * Ke386IoSetAccessMap() copies the passed map to the TSS.
+ *
+ * Ke386IoSetAccessProcess() adjusts the IOPM offset pointer so that
+ * the newly copied map is actually used. Otherwise, the IOPM offset
+ * points beyond the end of the TSS segment limit, causing any I/O
+ * access by the user mode process to generate an exception.
+ */
+void Ke386SetIoAccessMap(int, IOPM *);
+void Ke386QueryIoAccessMap(int, IOPM *);
+void Ke386IoSetAccessProcess(PEPROCESS, int);
+
+/*********************************************************************
+ Release any allocated objects.
+*********************************************************************/
+VOID GiveioUnload(IN PDRIVER_OBJECT DriverObject)
+{
+ WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING;
+ UNICODE_STRING uniDOSString;
+
+ if(IOPM_local)
+ MmFreeNonCachedMemory(IOPM_local, sizeof(IOPM));
+
+ RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);
+ IoDeleteSymbolicLink (&uniDOSString);
+ IoDeleteDevice(DriverObject->DeviceObject);
+}
+
+/*********************************************************************
+ Set the IOPM (I/O permission map) of the calling process so that it
+is given full I/O access. Our IOPM_local[] array is all zeros, so
+the IOPM will be all zeros. If OnFlag is 1, the process is given I/O
+access. If it is 0, access is removed.
+*********************************************************************/
+VOID SetIOPermissionMap(int OnFlag)
+{
+ Ke386IoSetAccessProcess(PsGetCurrentProcess(), OnFlag);
+ Ke386SetIoAccessMap(1, IOPM_local);
+}
+
+void GiveIO(void)
+{
+ SetIOPermissionMap(1);
+}
+
+/*********************************************************************
+ Service handler for a CreateFile() user mode call.
+
+ This routine is entered in the driver object function call table by
+the DriverEntry() routine. When the user mode application calls
+CreateFile(), this routine gets called while still in the context of
+the user mode application, but with the CPL (the processor's Current
+Privelege Level) set to 0. This allows us to do kernel mode
+operations. GiveIO() is called to give the calling process I/O
+access. All the user mode application needs do to obtain I/O access
+is open this device with CreateFile(). No other operations are
+required.
+*********************************************************************/
+NTSTATUS GiveioCreateDispatch(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ GiveIO(); // give the calling process I/O access
+
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+/*********************************************************************
+ Driver Entry routine.
+
+ This routine is called only once after the driver is initially
+loaded into memory. It allocates everything necessary for the
+driver's operation. In our case, it allocates memory for our IOPM
+array, and creates a device which user mode applications can open.
+It also creates a symbolic link to the device driver. This allows
+a user mode application to access our driver using the \\.\giveio
+notation.
+*********************************************************************/
+NTSTATUS DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+{
+ PDEVICE_OBJECT deviceObject;
+ NTSTATUS status;
+ WCHAR NameBuffer[] = L"\\Device\\" DEVICE_NAME_STRING;
+ WCHAR DOSNameBuffer[] = L"\\DosDevices\\" DEVICE_NAME_STRING;
+ UNICODE_STRING uniNameString, uniDOSString;
+
+ //
+ // Allocate a buffer for the local IOPM and zero it.
+ //
+ IOPM_local = MmAllocateNonCachedMemory(sizeof(IOPM));
+ if(IOPM_local == 0)
+ return STATUS_INSUFFICIENT_RESOURCES;
+ RtlZeroMemory(IOPM_local, sizeof(IOPM));
+
+ //
+ // Set up device driver name and device object.
+ //
+ RtlInitUnicodeString(&uniNameString, NameBuffer);
+ RtlInitUnicodeString(&uniDOSString, DOSNameBuffer);
+
+ status = IoCreateDevice(DriverObject, 0,
+ &uniNameString,
+ FILE_DEVICE_UNKNOWN,
+ 0, FALSE, &deviceObject);
+
+ if(!NT_SUCCESS(status))
+ return status;
+
+ status = IoCreateSymbolicLink (&uniDOSString, &uniNameString);
+
+ if (!NT_SUCCESS(status))
+ return status;
+
+ //
+ // Initialize the Driver Object with driver's entry points.
+ // All we require are the Create and Unload operations.
+ //
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = GiveioCreateDispatch;
+ DriverObject->DriverUnload = GiveioUnload;
+ return STATUS_SUCCESS;
+}
+