Ejemplo n.º 1
0
// Dispatch table for control
NTSTATUS NeoNdisDispatch(DEVICE_OBJECT *DeviceObject, IRP *Irp)
{
	NTSTATUS status;
	IO_STACK_LOCATION *stack;
	void *buf;
	BOOL ok;
	status = STATUS_SUCCESS;

	if (ctx == NULL)
	{
		return NDIS_STATUS_FAILURE;
	}

	InterlockedIncrement(&ctx->NumCurrentDispatch);

	// Get the IRP stack
	stack = IoGetCurrentIrpStackLocation(Irp);

	// Initialize the number of bytes
	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = STATUS_SUCCESS;

	buf = Irp->UserBuffer;

	if (ctx->Halting != FALSE)
	{
		// Device driver is terminating
		Irp->IoStatus.Information = STATUS_UNSUCCESSFUL;
		InterlockedDecrement(&ctx->NumCurrentDispatch);

		IoCompleteRequest(Irp, IO_NO_INCREMENT);

		return STATUS_SUCCESS;
	}

	// Branch to each operation
	switch (stack->MajorFunction)
	{
	case IRP_MJ_CREATE:
		// Device is opened
		if (NeoNdisOnOpen(Irp, stack) == FALSE)
		{
			Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			status = STATUS_UNSUCCESSFUL;
		}
		break;

	case IRP_MJ_CLOSE:
		// Device is closed
		if (NeoNdisOnClose(Irp, stack) == FALSE)
		{
			Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			status = STATUS_UNSUCCESSFUL;
		}
		break;

	case IRP_MJ_READ:
		// Read (Reading of the received packet)
		ok = false;
		if (buf != NULL)
		{
			if (ctx->Opened && ctx->Inited)
			{
				if (stack->Parameters.Read.Length == NEO_EXCHANGE_BUFFER_SIZE)
				{
					// Address check
					bool check_ok = true;
					__try
					{
						ProbeForWrite(buf, NEO_EXCHANGE_BUFFER_SIZE, 1);
					}
					__except (EXCEPTION_EXECUTE_HANDLER)
					{
						check_ok = false;
					}

					if (check_ok)
					{
						// Address check
						MDL *mdl = IoAllocateMdl(buf, NEO_EXCHANGE_BUFFER_SIZE, false, false, NULL);

						if (mdl != NULL)
						{
							MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess);
						}

						// Read
						NeoRead(buf);
						Irp->IoStatus.Information = NEO_EXCHANGE_BUFFER_SIZE;
						ok = true;

						if (mdl != NULL)
						{
							MmUnlockPages(mdl);
							IoFreeMdl(mdl);
						}
					}
				}
			}
		}
		if (ok == FALSE)
		{
			// An error occurred
			Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			status = STATUS_UNSUCCESSFUL;
		}
		break;

	case IRP_MJ_WRITE:
		// Write (Writing of a transmission packet)
		ok = false;
		if (buf != NULL)
		{
			if (ctx->Opened && ctx->Inited)
			{
				if (stack->Parameters.Write.Length == NEO_EXCHANGE_BUFFER_SIZE)
				{
					// Address check
					bool check_ok = true;
					__try
					{
						ProbeForRead(buf, NEO_EXCHANGE_BUFFER_SIZE, 1);
					}
					__except (EXCEPTION_EXECUTE_HANDLER)
					{
						check_ok = false;
					}

					if (check_ok)
					{
						// Address check
						MDL *mdl = IoAllocateMdl(buf, NEO_EXCHANGE_BUFFER_SIZE, false, false, NULL);

						if (mdl != NULL)
						{
							MmProbeAndLockPages(mdl, KernelMode, IoReadAccess);
						}

						ProbeForRead(buf, NEO_EXCHANGE_BUFFER_SIZE, 1);

						// Write
						NeoWrite(buf);
						Irp->IoStatus.Information = stack->Parameters.Write.Length;
						ok = true;

						if (mdl != NULL)
						{
							MmUnlockPages(mdl);
							IoFreeMdl(mdl);
						}
					}
				}
			}
		}
Ejemplo n.º 2
0
// Dispatch table for control
NTSTATUS NeoNdisDispatch(DEVICE_OBJECT *DeviceObject, IRP *Irp)
{
	NTSTATUS status;
	IO_STACK_LOCATION *stack;
	void *buf;
	BOOL ok;
	status = STATUS_SUCCESS;

	if (ctx == NULL)
	{
		return NDIS_STATUS_FAILURE;
	}

	// Get the IRP stack
	stack = IoGetCurrentIrpStackLocation(Irp);

	// Initialize the number of bytes
	Irp->IoStatus.Information = 0;
	Irp->IoStatus.Status = STATUS_SUCCESS;

	buf = Irp->UserBuffer;

	if (ctx->Halting != FALSE)
	{
		// Device driver is terminating
		Irp->IoStatus.Information = STATUS_UNSUCCESSFUL;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_UNSUCCESSFUL;
	}

	// Branch to each operation
	switch (stack->MajorFunction)
	{
	case IRP_MJ_CREATE:
		// Device is opened
		if (NeoNdisOnOpen(Irp, stack) == FALSE)
		{
			Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			status = STATUS_UNSUCCESSFUL;
		}
		break;

	case IRP_MJ_CLOSE:
		// Device is closed
		if (NeoNdisOnClose(Irp, stack) == FALSE)
		{
			Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			status = STATUS_UNSUCCESSFUL;
		}
		break;

	case IRP_MJ_READ:
#ifndef	WIN9X
		// Read (Reading of the received packet)
		ok = false;
		if (buf != NULL)
		{
			if (ctx->Opened && ctx->Inited)
			{
				if (stack->Parameters.Read.Length == NEO_EXCHANGE_BUFFER_SIZE)
				{
					// Address check
					MDL *mdl = IoAllocateMdl(buf, NEO_EXCHANGE_BUFFER_SIZE, false, false, NULL);

					if (mdl != NULL)
					{
						MmProbeAndLockPages(mdl, KernelMode, IoWriteAccess);
					}

					if (NeoIsKernelAddress(buf) == FALSE)
					{
						// Read
						NeoRead(buf);
						Irp->IoStatus.Information = NEO_EXCHANGE_BUFFER_SIZE;
						ok = true;
					}

					if (mdl != NULL)
					{
						MmUnlockPages(mdl);
						IoFreeMdl(mdl);
					}
				}
			}
		}
		if (ok == FALSE)
		{
			// An error occurred
			Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			status = STATUS_UNSUCCESSFUL;
		}
#endif	// WIN9X
		break;

	case IRP_MJ_WRITE:
#ifndef	WIN9X
		// Write (Writing of a transmission packet)
		ok = false;
		if (buf != NULL)
		{
			if (ctx->Opened && ctx->Inited)
			{
				if (stack->Parameters.Write.Length == NEO_EXCHANGE_BUFFER_SIZE)
				{
					// Address check
					MDL *mdl = IoAllocateMdl(buf, NEO_EXCHANGE_BUFFER_SIZE, false, false, NULL);

					if (mdl != NULL)
					{
						MmProbeAndLockPages(mdl, KernelMode, IoReadAccess);
					}

					if (NeoIsKernelAddress(buf) == FALSE)
					{
						// Write
						NeoWrite(buf);
						Irp->IoStatus.Information = stack->Parameters.Write.Length;
						ok = true;
					}

					if (mdl != NULL)
					{
						MmUnlockPages(mdl);
						IoFreeMdl(mdl);
					}
				}
			}
		}
		if (ok == FALSE)
		{
			// An error occurred
			Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			status = STATUS_UNSUCCESSFUL;
		}
		break;
#endif	// WIN9X
	case IRP_MJ_DEVICE_CONTROL:
#ifdef	WIN9X
		// IO Control
		switch (stack->Parameters.DeviceIoControl.IoControlCode)
		{
		case NEO_IOCTL_SET_EVENT:
			// Specify a event
			if (Irp->AssociatedIrp.SystemBuffer == NULL ||
				stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(DWORD))
			{
				// An error occurred
				Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
			}
			else
			{
				DWORD value = *((DWORD *)Irp->AssociatedIrp.SystemBuffer);
				ctx->Event = NeoCreateWin9xEvent(value);
				Irp->IoStatus.Information = sizeof(DWORD);
			}
			break;

		case NEO_IOCTL_PUT_PACKET:
			// Write a packet
			ok = false;
			buf = Irp->AssociatedIrp.SystemBuffer;
			if (buf != NULL)
			{
				if (stack->Parameters.DeviceIoControl.InputBufferLength == NEO_EXCHANGE_BUFFER_SIZE)
				{
					// Write
					NeoWrite(buf);
					Irp->IoStatus.Information = NEO_EXCHANGE_BUFFER_SIZE;
					ok = true;
				}
			}

			if (ok == false)
			{
				// An error occurred
				Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
				status = STATUS_UNSUCCESSFUL;
			}
			break;

		case NEO_IOCTL_GET_PACKET:
			// Get the packet
			ok = false;
			buf = Irp->AssociatedIrp.SystemBuffer;
			if (buf != NULL)
			{
				if (stack->Parameters.DeviceIoControl.OutputBufferLength == NEO_EXCHANGE_BUFFER_SIZE)
				{
					// Read
					NeoRead(buf);
					Irp->IoStatus.Information = NEO_EXCHANGE_BUFFER_SIZE;
					ok = true;
				}
			}

			if (ok == false)
			{
				// An error occurred
				Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
				status = STATUS_UNSUCCESSFUL;
			}
			break;
		}
#endif	// WIN9X
		break;
	}

	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return STATUS_SUCCESS;
}