NTSTATUS
FatPnpRemove (
PIRP_CONTEXT IrpContext,
PIRP Irp,
PVCB Vcb
)
/*++
Routine Description:
This routine handles the PnP remove operation. This is our notification
that the underlying storage device for the volume we have is gone, and
an excellent indication that the volume will never reappear. The filesystem
is responsible for initiation or completion of the dismount.
Arguments:
Irp - Supplies the Irp to process
Vcb - Supplies the volume being removed.
Return Value:
NTSTATUS - The return status for the operation
--*/
{
NTSTATUS Status;
KEVENT Event;
BOOLEAN VcbDeleted;
//
// REMOVE - a storage device is now gone. We either got
// QUERY'd and said yes OR got a SURPRISE OR a storage
// stack failed to spin back up from a sleep/stop state
// (the only case in which this will be the first warning).
//
// Note that it is entirely unlikely that we will be around
// for a REMOVE in the first two cases, as we try to intiate
// dismount.
//
//
// Acquire the global resource so that we can try to vaporize
// the volume, and the vcb resource itself.
//
#if __NDAS_FAT_SECONDARY__
if (FlagOn(IrpContext->NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT))
FatAcquireExclusiveSecondaryVcb( IrpContext, Vcb );
else
FatAcquireExclusiveVcb( IrpContext, Vcb );
#else
FatAcquireExclusiveVcb( &IrpContext, Vcb );
#endif
//
// The device will be going away. Remove our lock (benign
// if we never had it).
//
(VOID) FatUnlockVolumeInternal( IrpContext, Vcb, NULL );
//
// We need to pass this down before starting the dismount, which
// could disconnect us immediately from the stack.
//
//
// Get the next stack location, and copy over the stack location
//
IoCopyCurrentIrpStackLocationToNext( Irp );
//
// Set up the completion routine
//
KeInitializeEvent( &Event, NotificationEvent, FALSE );
IoSetCompletionRoutine( Irp,
FatPnpCompletionRoutine,
&Event,
TRUE,
TRUE,
TRUE );
//
// Send the request and wait.
//
Status = IoCallDriver(Vcb->TargetDeviceObject, Irp);
if (Status == STATUS_PENDING) {
KeWaitForSingleObject( &Event,
Executive,
KernelMode,
FALSE,
//.........这里部分代码省略.........
//.........这里部分代码省略.........
if (NT_SUCCESS(Status))
{
/* Return the handle */
*PortHandle = Handle;
LPCTRACE(LPC_CONNECT_DEBUG,
"Handle: %p. Length: %lx\n",
Handle,
PortMessageLength);
/* Check if maximum length was requested */
if (MaxMessageLength) *MaxMessageLength = PortMessageLength;
/* Check if we had a client view */
if (ClientView)
{
/* Copy it back */
RtlCopyMemory(ClientView,
&ConnectMessage->ClientView,
sizeof(PORT_VIEW));
}
/* Check if we had a server view */
if (ServerView)
{
/* Copy it back */
RtlCopyMemory(ServerView,
&ConnectMessage->ServerView,
sizeof(REMOTE_PORT_VIEW));
}
}
}
else
{
/* No connection port, we failed */
if (SectionToMap) ObDereferenceObject(SectionToMap);
/* Acquire the lock */
KeAcquireGuardedMutex(&LpcpLock);
/* Check if it's because the name got deleted */
if (!(ClientPort->ConnectionPort) ||
(Port->Flags & LPCP_NAME_DELETED))
{
/* Set the correct status */
Status = STATUS_OBJECT_NAME_NOT_FOUND;
}
else
{
/* Otherwise, the caller refused us */
Status = STATUS_PORT_CONNECTION_REFUSED;
}
/* Release the lock */
KeReleaseGuardedMutex(&LpcpLock);
/* Kill the port */
ObDereferenceObject(ClientPort);
}
/* Free the message */
LpcpFreeToPortZone(Message, 0);
}
else
{
/* No reply message, fail */
if (SectionToMap) ObDereferenceObject(SectionToMap);
ObDereferenceObject(ClientPort);
Status = STATUS_PORT_CONNECTION_REFUSED;
}
/* Return status */
ObDereferenceObject(Port);
return Status;
Cleanup:
/* We failed, free the message */
SectionToMap = LpcpFreeConMsg(&Message, &ConnectMessage, Thread);
/* Check if the semaphore got signaled */
if (KeReadStateSemaphore(&Thread->LpcReplySemaphore))
{
/* Wait on it */
KeWaitForSingleObject(&Thread->LpcReplySemaphore,
WrExecutive,
KernelMode,
FALSE,
NULL);
}
/* Check if we had a message and free it */
if (Message) LpcpFreeToPortZone(Message, 0);
/* Dereference other objects */
if (SectionToMap) ObDereferenceObject(SectionToMap);
ObDereferenceObject(ClientPort);
/* Return status */
ObDereferenceObject(Port);
return Status;
}
开发者ID:GYGit,项目名称:reactos,代码行数:101,代码来源:connect.c
示例6: TdiSendMessage
NTSTATUS
TdiSendMessage(
ULONG Ip,
USHORT Port,
PCHAR Message,
ULONG Length
)
{
PFILE_OBJECT ConnectionFileObject, AddressFileObject;
HANDLE AddressHandle, ConnectionHandle;
CHAR Buffer[80], Data[] = "Hello from Gary";
NTSTATUS Status;
KEVENT Done;
KeInitializeEvent(&Done, NotificationEvent, FALSE);
Status = TdiCreateConnection(&ConnectionHandle, &ConnectionFileObject);
if (!NT_SUCCESS(Status)) return Status;
Status = TdiCreateAddress(&AddressHandle, &AddressFileObject, SOCK_STREAM, 0, 0);
if (!NT_SUCCESS(Status)) return Status;
do
{
IO_STATUS_BLOCK IoStatus;
KEVENT Event;
Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_DISCONNECT, TdiEventDisconnect, &Done);
if (!NT_SUCCESS(Status)) break;
Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_ERROR, TdiEventError, 0);
if (!NT_SUCCESS(Status)) break;
Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_RECEIVE, TdiEventReceive, 0);
if (!NT_SUCCESS(Status)) break;
Status = TdiBind(ConnectionFileObject, AddressHandle);
if (!NT_SUCCESS(Status)) break;
Status = TdiConnect(ConnectionFileObject, Ip, Port, NULL);
if (!NT_SUCCESS(Status)) break;
Status = TdiSend(ConnectionFileObject, Message, Length);
if (!NT_SUCCESS(Status)) break;
Status = TdiDisconnect(ConnectionFileObject);
if (!NT_SUCCESS(Status)) break;
KeWaitForSingleObject(&Done, UserRequest, KernelMode, FALSE, 0);
} while (0);
ObDereferenceObject(ConnectionFileObject);
ObDereferenceObject(AddressFileObject);
ZwClose(ConnectionHandle);
ZwClose(AddressHandle);
return Status;
}
开发者ID:0x00dec0de,项目名称:Rovnix,代码行数:64,代码来源:tdi.c
示例7: XenUsb_Connect
NTSTATUS
XenUsb_Connect(PVOID context, BOOLEAN suspend) {
NTSTATUS status;
PXENUSB_DEVICE_DATA xudd = context;
PFN_NUMBER pfn;
ULONG i;
if (!suspend) {
xudd->handle = XnOpenDevice(xudd->pdo, XenUsb_DeviceCallback, xudd);
}
if (!xudd->handle) {
FUNCTION_MSG("Cannot open Xen device\n");
return STATUS_UNSUCCESSFUL;
}
if (xudd->device_state != DEVICE_STATE_INACTIVE) {
for (i = 0; i <= 5 && xudd->backend_state != XenbusStateInitialising && xudd->backend_state != XenbusStateInitWait && xudd->backend_state != XenbusStateInitialised; i++) {
FUNCTION_MSG("Waiting for XenbusStateInitXxx\n");
if (xudd->backend_state == XenbusStateClosed) {
status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "state", XenbusStateInitialising);
}
KeWaitForSingleObject(&xudd->backend_event, Executive, KernelMode, FALSE, NULL);
}
if (xudd->backend_state != XenbusStateInitialising && xudd->backend_state != XenbusStateInitWait && xudd->backend_state != XenbusStateInitialised) {
FUNCTION_MSG("Backend state timeout\n");
return STATUS_UNSUCCESSFUL;
}
if (!NT_SUCCESS(status = XnBindEvent(xudd->handle, &xudd->event_channel, XenUsb_HandleEvent_DIRQL, xudd))) {
FUNCTION_MSG("Cannot allocate event channel\n");
return STATUS_UNSUCCESSFUL;
}
FUNCTION_MSG("event_channel = %d\n", xudd->event_channel);
status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "event-channel", xudd->event_channel);
xudd->urb_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENUSB_POOL_TAG);
if (!xudd->urb_sring) {
FUNCTION_MSG("Cannot allocate urb_sring\n");
return STATUS_UNSUCCESSFUL;
}
SHARED_RING_INIT(xudd->urb_sring);
FRONT_RING_INIT(&xudd->urb_ring, xudd->urb_sring, PAGE_SIZE);
pfn = (PFN_NUMBER)(MmGetPhysicalAddress(xudd->urb_sring).QuadPart >> PAGE_SHIFT);
FUNCTION_MSG("usb sring pfn = %d\n", (ULONG)pfn);
xudd->urb_sring_gref = XnGrantAccess(xudd->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENUSB_POOL_TAG);
FUNCTION_MSG("usb sring_gref = %d\n", xudd->urb_sring_gref);
status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "urb-ring-ref", xudd->urb_sring_gref);
xudd->conn_sring = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, XENUSB_POOL_TAG);
if (!xudd->conn_sring) {
FUNCTION_MSG("Cannot allocate conn_sring\n");
return STATUS_UNSUCCESSFUL;
}
SHARED_RING_INIT(xudd->conn_sring);
FRONT_RING_INIT(&xudd->conn_ring, xudd->conn_sring, PAGE_SIZE);
pfn = (PFN_NUMBER)(MmGetPhysicalAddress(xudd->conn_sring).QuadPart >> PAGE_SHIFT);
FUNCTION_MSG("conn sring pfn = %d\n", (ULONG)pfn);
xudd->conn_sring_gref = XnGrantAccess(xudd->handle, (ULONG)pfn, FALSE, INVALID_GRANT_REF, XENUSB_POOL_TAG);
FUNCTION_MSG("conn sring_gref = %d\n", xudd->conn_sring_gref);
status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "conn-ring-ref", xudd->conn_sring_gref);
/* fill conn ring with requests */
for (i = 0; i < USB_CONN_RING_SIZE; i++) {
usbif_conn_request_t *req = RING_GET_REQUEST(&xudd->conn_ring, i);
req->id = (uint16_t)i;
}
xudd->conn_ring.req_prod_pvt = i;
status = XnWriteInt32(xudd->handle, XN_BASE_FRONTEND, "state", XenbusStateConnected);
for (i = 0; i <= 5 && xudd->backend_state != XenbusStateConnected; i++) {
FUNCTION_MSG("Waiting for XenbusStateConnected\n");
KeWaitForSingleObject(&xudd->backend_event, Executive, KernelMode, FALSE, NULL);
}
if (xudd->backend_state != XenbusStateConnected) {
FUNCTION_MSG("Backend state timeout\n");
return STATUS_UNSUCCESSFUL;
}
xudd->device_state = DEVICE_STATE_ACTIVE;
}
return STATUS_SUCCESS;
}
VOID
LspPollingThread(
IN PVOID Context
)
/*++
Routine Description:
This is the main thread that removes IRP from the queue
and peforms I/O on it.
Arguments:
Context -- pointer to the device object
--*/
{
PDEVICE_OBJECT DeviceObject = Context;
PDEVICE_EXTENSION DevExtension = DeviceObject->DeviceExtension;
PIRP Irp;
NTSTATUS Status;
KeSetPriorityThread(KeGetCurrentThread(), LOW_REALTIME_PRIORITY );
//
// Now enter the main IRP-processing loop
//
while( TRUE )
{
//
// Wait indefinitely for an IRP to appear in the work queue or for
// the Unload routine to stop the thread. Every successful return
// from the wait decrements the semaphore count by 1.
//
KeWaitForSingleObject(
&DevExtension->IrpQueueSemaphore,
Executive,
KernelMode,
FALSE,
NULL );
//
// See if thread was awakened because driver is unloading itself...
//
if( DevExtension->ThreadShouldStop )
{
PsTerminateSystemThread( STATUS_SUCCESS );
}
//
// Remove a pending IRP from the queue.
//
Irp = IoCsqRemoveNextIrp(&DevExtension->CancelSafeQueue, NULL);
if(!Irp)
{
LSP_KDPRINT(("Oops, a queued irp got cancelled\n"));
continue; // go back to waiting
}
while(TRUE)
{
//
// Perform I/O
//
Status = LspPollDevice(DeviceObject, Irp);
if(Status == STATUS_PENDING)
{
//
// Device is not ready, so sleep for a while and try again.
//
KeDelayExecutionThread(
KernelMode,
FALSE,
&DevExtension->PollingInterval);
}
else
{
//
// I/O is successful, so complete the Irp.
//
Irp->IoStatus.Status = Status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
break;
}
}
//
// Go back to the top of the loop to see if there's another request waiting.
//
} // end of while-loop
}
//.........这里部分代码省略.........
if (CurrentProcess->ExitStatus == STATUS_PENDING)
{
/* Use the last exit status */
CurrentProcess->ExitStatus = CurrentProcess->
LastThreadExitStatus;
}
}
else
{
/* Just a normal exit, write the code */
CurrentProcess->ExitStatus = ExitStatus;
}
/* Loop all the current threads */
FirstEntry = &CurrentProcess->ThreadListHead;
CurrentEntry = FirstEntry->Flink;
while (FirstEntry != CurrentEntry)
{
/* Get the thread on the list */
OtherThread = CONTAINING_RECORD(CurrentEntry,
ETHREAD,
ThreadListEntry);
/* Check if it's a thread that's still alive */
if ((OtherThread != Thread) &&
!(KeReadStateThread(&OtherThread->Tcb)) &&
(ObReferenceObjectSafe(OtherThread)))
{
/* It's a live thread and we referenced it, unlock process */
ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
KeLeaveCriticalRegion();
/* Wait on the thread */
KeWaitForSingleObject(OtherThread,
Executive,
KernelMode,
FALSE,
NULL);
/* Check if we had a previous thread to dereference */
if (PreviousThread) ObDereferenceObject(PreviousThread);
/* Remember the thread and re-lock the process */
PreviousThread = OtherThread;
KeEnterCriticalRegion();
ExAcquirePushLockExclusive(&CurrentProcess->ProcessLock);
}
/* Go to the next thread */
CurrentEntry = CurrentEntry->Flink;
}
}
else if (ExitStatus != STATUS_THREAD_IS_TERMINATING)
{
/* Write down the exit status of the last thread to get killed */
CurrentProcess->LastThreadExitStatus = ExitStatus;
}
/* Unlock the Process */
ExReleasePushLockExclusive(&CurrentProcess->ProcessLock);
KeLeaveCriticalRegion();
/* Check if we had a previous thread to dereference */
if (PreviousThread) ObDereferenceObject(PreviousThread);
/* Check if the process has a debug port and if this is a user thread */
请发表评论