⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 create.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
	else
	{
		NewPipe = TRUE;
		Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
		if (Fcb == NULL)
		{
			KeUnlockMutex(&DeviceExt->PipeListLock);
			ExFreePool(Ccb);
			Irp->IoStatus.Status = STATUS_NO_MEMORY;
			Irp->IoStatus.Information = 0;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			return STATUS_NO_MEMORY;
		}

		Fcb->PipeName.Length = FileObject->FileName.Length;
		Fcb->PipeName.MaximumLength = Fcb->PipeName.Length + sizeof(UNICODE_NULL);
		Fcb->PipeName.Buffer = ExAllocatePool(NonPagedPool, Fcb->PipeName.MaximumLength);
		if (Fcb->PipeName.Buffer == NULL)
		{
			KeUnlockMutex(&DeviceExt->PipeListLock);
			ExFreePool(Fcb);
			ExFreePool(Ccb);
			Irp->IoStatus.Status = STATUS_NO_MEMORY;
			Irp->IoStatus.Information = 0;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			return STATUS_NO_MEMORY;
		}

		RtlCopyUnicodeString(&Fcb->PipeName, &FileObject->FileName);

		InitializeListHead(&Fcb->ServerCcbListHead);
		InitializeListHead(&Fcb->ClientCcbListHead);
		InitializeListHead(&Fcb->WaiterListHead);
		KeInitializeMutex(&Fcb->CcbListLock, 0);

		Fcb->PipeType = Buffer->NamedPipeType;
		Fcb->WriteMode = Buffer->ReadMode;
		Fcb->ReadMode = Buffer->ReadMode;
		Fcb->CompletionMode = Buffer->CompletionMode;
		switch (IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE))
		{
		case FILE_SHARE_READ:
			Fcb->PipeConfiguration = FILE_PIPE_OUTBOUND;
			break;
		case FILE_SHARE_WRITE:
			Fcb->PipeConfiguration = FILE_PIPE_INBOUND;
			break;
		case FILE_SHARE_READ|FILE_SHARE_WRITE:
			Fcb->PipeConfiguration = FILE_PIPE_FULL_DUPLEX;
			break;
		}
		Fcb->MaximumInstances = Buffer->MaximumInstances;
		Fcb->CurrentInstances = 0;
		Fcb->TimeOut = Buffer->DefaultTimeout;
		if (!(Fcb->PipeConfiguration & FILE_PIPE_OUTBOUND) ||
			Fcb->PipeConfiguration & FILE_PIPE_FULL_DUPLEX)
		{
			if (Buffer->InboundQuota == 0)
			{
				Fcb->InboundQuota = DeviceExt->DefaultQuota;
			}
			else
			{
				Fcb->InboundQuota = PAGE_ROUND_UP(Buffer->InboundQuota);
				if (Fcb->InboundQuota < DeviceExt->MinQuota)
				{
					Fcb->InboundQuota = DeviceExt->MinQuota;
				}
				else if (Fcb->InboundQuota > DeviceExt->MaxQuota)
				{
					Fcb->InboundQuota = DeviceExt->MaxQuota;
				}
			}
		}
		else
		{
			Fcb->InboundQuota = 0;
		}

		if (Fcb->PipeConfiguration & (FILE_PIPE_FULL_DUPLEX|FILE_PIPE_OUTBOUND))
		{
			if (Buffer->OutboundQuota == 0)
			{
				Fcb->OutboundQuota = DeviceExt->DefaultQuota;
			}
			else
			{
				Fcb->OutboundQuota = PAGE_ROUND_UP(Buffer->OutboundQuota);
				if (Fcb->OutboundQuota < DeviceExt->MinQuota)
				{
					Fcb->OutboundQuota = DeviceExt->MinQuota;
				}
				else if (Fcb->OutboundQuota > DeviceExt->MaxQuota)
				{
					Fcb->OutboundQuota = DeviceExt->MaxQuota;
				}
			}
		}
		else
		{
			Fcb->OutboundQuota = 0;
		}

		InsertTailList(&DeviceExt->PipeListHead, &Fcb->PipeListEntry);
		KeUnlockMutex(&DeviceExt->PipeListLock);
	}

	if (Fcb->InboundQuota)
	{
		Ccb->Data = ExAllocatePool(PagedPool, Fcb->InboundQuota);
		if (Ccb->Data == NULL)
		{
			ExFreePool(Ccb);

			if (NewPipe)
			{
				KeLockMutex(&DeviceExt->PipeListLock);
				RemoveEntryList(&Fcb->PipeListEntry);
				KeUnlockMutex(&DeviceExt->PipeListLock);
				RtlFreeUnicodeString(&Fcb->PipeName);
				ExFreePool(Fcb);
			}

			Irp->IoStatus.Status = STATUS_NO_MEMORY;
			IoCompleteRequest(Irp, IO_NO_INCREMENT);
			return STATUS_NO_MEMORY;
		}
	}
	else
	{
		Ccb->Data = NULL;
	}

	Ccb->ReadPtr = Ccb->Data;
	Ccb->WritePtr = Ccb->Data;
	Ccb->ReadDataAvailable = 0;
	Ccb->WriteQuotaAvailable = Fcb->InboundQuota;
	Ccb->MaxDataLength = Fcb->InboundQuota;
	InitializeListHead(&Ccb->ReadRequestListHead);
	ExInitializeFastMutex(&Ccb->DataListLock);

	Fcb->CurrentInstances++;

	Ccb->Fcb = Fcb;
	Ccb->PipeEnd = FILE_PIPE_SERVER_END;
	Ccb->PipeState = FILE_PIPE_LISTENING_STATE;
	Ccb->OtherSide = NULL;

	DPRINT("CCB: %x\n", Ccb);

	KeInitializeEvent(&Ccb->ConnectEvent, SynchronizationEvent, FALSE);
	KeInitializeEvent(&Ccb->ReadEvent, SynchronizationEvent, FALSE);
	KeInitializeEvent(&Ccb->WriteEvent, SynchronizationEvent, FALSE);

	KeLockMutex(&Fcb->CcbListLock);
	InsertTailList(&Fcb->ServerCcbListHead, &Ccb->CcbListEntry);
	KeUnlockMutex(&Fcb->CcbListLock);

	FileObject->FsContext = Fcb;
	FileObject->FsContext2 = Ccb;
	FileObject->Flags |= FO_NAMED_PIPE;

	Irp->IoStatus.Status = STATUS_SUCCESS;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	DPRINT("Success!\n");

	return STATUS_SUCCESS;
}


NTSTATUS STDCALL
NpfsCleanup(PDEVICE_OBJECT DeviceObject,
			PIRP Irp)
{
	PNPFS_DEVICE_EXTENSION DeviceExt;
	PIO_STACK_LOCATION IoStack;
	PFILE_OBJECT FileObject;
	PNPFS_CCB Ccb, OtherSide;
	PNPFS_FCB Fcb;
	BOOLEAN Server;

	DPRINT("NpfsCleanup(DeviceObject %p Irp %p)\n", DeviceObject, Irp);

	IoStack = IoGetCurrentIrpStackLocation(Irp);
	DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
	FileObject = IoStack->FileObject;
	Ccb = FileObject->FsContext2;

	if (Ccb == NULL)
	{
		DPRINT("Success!\n");
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_SUCCESS;
	}

	DPRINT("CCB %p\n", Ccb);
	Fcb = Ccb->Fcb;

	DPRINT("Cleaning pipe %wZ\n", &Fcb->PipeName);

	KeLockMutex(&Fcb->CcbListLock);

	Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);

	if (Server)
	{
		/* FIXME: Clean up existing connections here ?? */
		DPRINT("Server\n");
	}
	else
	{
		DPRINT("Client\n");
	}
	if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
	{
		OtherSide = Ccb->OtherSide;
		/* Lock the server first */
		if (Server)
		{
			ExAcquireFastMutex(&Ccb->DataListLock);
			ExAcquireFastMutex(&OtherSide->DataListLock);
		}
		else
		{
			ExAcquireFastMutex(&OtherSide->DataListLock);
			ExAcquireFastMutex(&Ccb->DataListLock);
		}
		OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
		OtherSide->OtherSide = NULL;
		/*
		* Signaling the write event. If is possible that an other
		* thread waits for an empty buffer.
		*/
		KeSetEvent(&OtherSide->ReadEvent, IO_NO_INCREMENT, FALSE);
		KeSetEvent(&OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
		if (Server)
		{
			ExReleaseFastMutex(&OtherSide->DataListLock);
			ExReleaseFastMutex(&Ccb->DataListLock);
		}
		else
		{
			ExReleaseFastMutex(&Ccb->DataListLock);
			ExReleaseFastMutex(&OtherSide->DataListLock);
		}
	}
	else if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
	{
		PLIST_ENTRY Entry;
		PNPFS_WAITER_ENTRY WaitEntry = NULL;
		BOOLEAN Complete = FALSE;
		KIRQL oldIrql;
		PIRP tmpIrp;

		Entry = Ccb->Fcb->WaiterListHead.Flink;
		while (Entry != &Ccb->Fcb->WaiterListHead)
		{
			WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
			if (WaitEntry->Ccb == Ccb)
			{
				RemoveEntryList(Entry);
				tmpIrp = CONTAINING_RECORD(WaitEntry, IRP, Tail.Overlay.DriverContext);
				IoAcquireCancelSpinLock(&oldIrql);
				if (!tmpIrp->Cancel)
				{
					(void)IoSetCancelRoutine(tmpIrp, NULL);
					Complete = TRUE;
				}
				IoReleaseCancelSpinLock(oldIrql);
				if (Complete)
				{
					tmpIrp->IoStatus.Status = STATUS_PIPE_BROKEN;
					tmpIrp->IoStatus.Information = 0;
					IoCompleteRequest(tmpIrp, IO_NO_INCREMENT);
				}
				break;
			}
			Entry = Entry->Flink;
		}

	}
	Ccb->PipeState = FILE_PIPE_CLOSING_STATE;

	KeUnlockMutex(&Fcb->CcbListLock);

	ExAcquireFastMutex(&Ccb->DataListLock);
	if (Ccb->Data)
	{
		ExFreePool(Ccb->Data);
		Ccb->Data = NULL;
		Ccb->ReadPtr = NULL;
		Ccb->WritePtr = NULL;
	}
	ExReleaseFastMutex(&Ccb->DataListLock);

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	DPRINT("Success!\n");

	return STATUS_SUCCESS;
}

NTSTATUS STDCALL
NpfsClose(PDEVICE_OBJECT DeviceObject,
		  PIRP Irp)
{
	PNPFS_DEVICE_EXTENSION DeviceExt;
	PIO_STACK_LOCATION IoStack;
	PFILE_OBJECT FileObject;
	PNPFS_FCB Fcb;
	PNPFS_CCB Ccb;
	BOOLEAN Server;

	DPRINT("NpfsClose(DeviceObject %p Irp %p)\n", DeviceObject, Irp);

	IoStack = IoGetCurrentIrpStackLocation(Irp);
	DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
	FileObject = IoStack->FileObject;
	Ccb = FileObject->FsContext2;

	if (Ccb == NULL)
	{
		DPRINT("Success!\n");
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = 0;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return STATUS_SUCCESS;
	}

	DPRINT("CCB %x\n", Ccb);
	Fcb = Ccb->Fcb;

	DPRINT("Closing pipe %wZ\n", &Fcb->PipeName);

	KeLockMutex(&Fcb->CcbListLock);

	Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);

	if (Server)
	{
		DPRINT("Server\n");
		Fcb->CurrentInstances--;
	}
	else
	{
		DPRINT("Client\n");
	}

	ASSERT(Ccb->PipeState == FILE_PIPE_CLOSING_STATE);

	FileObject->FsContext2 = NULL;

	RemoveEntryList(&Ccb->CcbListEntry);

	ExFreePool(Ccb);

	KeUnlockMutex(&Fcb->CcbListLock);

	if (IsListEmpty(&Fcb->ServerCcbListHead) &&
		IsListEmpty(&Fcb->ClientCcbListHead))
	{
		RtlFreeUnicodeString(&Fcb->PipeName);
		KeLockMutex(&DeviceExt->PipeListLock);
		RemoveEntryList(&Fcb->PipeListEntry);
		KeUnlockMutex(&DeviceExt->PipeListLock);
		ExFreePool(Fcb);
		FileObject->FsContext = NULL;
	}

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	DPRINT("Success!\n");

	return STATUS_SUCCESS;
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -