2005-03-14 02:08:17 +00:00
|
|
|
/*
|
2006-09-13 00:20:46 +00:00
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2006-09-13 03:02:40 +00:00
|
|
|
* FILE: ntoskrnl/ke/devqueue.c
|
2005-01-26 13:58:37 +00:00
|
|
|
* PURPOSE: Implement device queues
|
2006-09-13 00:20:46 +00:00
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
1998-08-25 04:27:26 +00:00
|
|
|
*/
|
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* INCLUDES ******************************************************************/
|
1998-08-25 04:27:26 +00:00
|
|
|
|
2004-08-15 16:39:12 +00:00
|
|
|
#include <ntoskrnl.h>
|
2000-01-06 00:26:16 +00:00
|
|
|
#define NDEBUG
|
2008-08-30 16:31:06 +00:00
|
|
|
#include <debug.h>
|
1998-08-25 04:27:26 +00:00
|
|
|
|
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2005-03-14 02:08:17 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
2006-09-13 00:20:46 +00:00
|
|
|
NTAPI
|
2005-03-14 02:08:17 +00:00
|
|
|
KeInitializeDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
|
|
|
|
{
|
|
|
|
/* Initialize the Header */
|
|
|
|
DeviceQueue->Type = DeviceQueueObject;
|
|
|
|
DeviceQueue->Size = sizeof(KDEVICE_QUEUE);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Initialize the Listhead and Spinlock */
|
|
|
|
InitializeListHead(&DeviceQueue->DeviceListHead);
|
|
|
|
KeInitializeSpinLock(&DeviceQueue->Lock);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Set it as busy */
|
|
|
|
DeviceQueue->Busy=FALSE;
|
|
|
|
}
|
2003-11-03 20:27:01 +00:00
|
|
|
|
2003-07-10 17:44:06 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-03-14 02:08:17 +00:00
|
|
|
BOOLEAN
|
2006-09-13 00:20:46 +00:00
|
|
|
NTAPI
|
2005-03-14 02:08:17 +00:00
|
|
|
KeInsertDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
|
|
|
|
IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
|
1998-08-25 04:27:26 +00:00
|
|
|
{
|
2006-09-13 00:20:46 +00:00
|
|
|
KLOCK_QUEUE_HANDLE DeviceLock;
|
2005-03-14 02:08:17 +00:00
|
|
|
BOOLEAN Inserted;
|
2006-09-13 00:20:46 +00:00
|
|
|
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2007-03-25 13:23:30 +00:00
|
|
|
DPRINT("KeInsertDeviceQueue() DevQueue %p, Entry %p\n", DeviceQueue, DeviceQueueEntry);
|
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Lock the queue */
|
|
|
|
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Check if it's not busy */
|
|
|
|
if (!DeviceQueue->Busy)
|
|
|
|
{
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Set it as busy */
|
|
|
|
Inserted = FALSE;
|
|
|
|
DeviceQueue->Busy = TRUE;
|
2006-09-13 00:20:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Insert it into the list */
|
2005-05-09 01:38:29 +00:00
|
|
|
Inserted = TRUE;
|
|
|
|
InsertTailList(&DeviceQueue->DeviceListHead,
|
2005-03-14 02:08:17 +00:00
|
|
|
&DeviceQueueEntry->DeviceListEntry);
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Sert the Insert state into the entry */
|
|
|
|
DeviceQueueEntry->Inserted = Inserted;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Release the lock */
|
|
|
|
KiReleaseDeviceQueueLock(&DeviceLock);
|
|
|
|
|
|
|
|
/* Return the state */
|
2005-03-14 02:08:17 +00:00
|
|
|
return Inserted;
|
1998-08-25 04:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 17:44:06 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-05-09 01:38:29 +00:00
|
|
|
BOOLEAN
|
2006-09-13 00:20:46 +00:00
|
|
|
NTAPI
|
2005-03-14 02:08:17 +00:00
|
|
|
KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
|
|
|
|
IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
|
|
|
|
IN ULONG SortKey)
|
1998-08-25 04:27:26 +00:00
|
|
|
{
|
2006-09-13 00:20:46 +00:00
|
|
|
KLOCK_QUEUE_HANDLE DeviceLock;
|
2005-03-14 02:08:17 +00:00
|
|
|
BOOLEAN Inserted;
|
2008-05-22 11:46:46 +00:00
|
|
|
PLIST_ENTRY NextEntry;
|
|
|
|
PKDEVICE_QUEUE_ENTRY LastEntry;
|
2006-09-13 00:20:46 +00:00
|
|
|
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2007-03-25 13:23:30 +00:00
|
|
|
DPRINT("KeInsertByKeyDeviceQueue() DevQueue %p, Entry %p, SortKey 0x%x\n", DeviceQueue, DeviceQueueEntry, SortKey);
|
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Lock the queue */
|
|
|
|
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Set the Sort Key */
|
2006-09-13 00:20:46 +00:00
|
|
|
DeviceQueueEntry->SortKey = SortKey;
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Check if it's not busy */
|
|
|
|
if (!DeviceQueue->Busy)
|
|
|
|
{
|
|
|
|
/* Set it as busy */
|
2005-03-14 02:08:17 +00:00
|
|
|
Inserted = FALSE;
|
2006-09-13 00:20:46 +00:00
|
|
|
DeviceQueue->Busy = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-05-22 11:46:46 +00:00
|
|
|
/* Make sure the list isn't empty */
|
|
|
|
NextEntry = &DeviceQueue->DeviceListHead;
|
|
|
|
if (!IsListEmpty(NextEntry))
|
|
|
|
{
|
|
|
|
/* Get the last entry */
|
|
|
|
LastEntry = CONTAINING_RECORD(NextEntry->Blink,
|
|
|
|
KDEVICE_QUEUE_ENTRY,
|
|
|
|
DeviceListEntry);
|
|
|
|
|
|
|
|
/* Check if our sort key is lower */
|
|
|
|
if (SortKey < LastEntry->SortKey)
|
|
|
|
{
|
|
|
|
/* Loop each sort key */
|
|
|
|
do
|
|
|
|
{
|
|
|
|
/* Get the next entry */
|
|
|
|
NextEntry = NextEntry->Flink;
|
|
|
|
LastEntry = CONTAINING_RECORD(NextEntry,
|
|
|
|
KDEVICE_QUEUE_ENTRY,
|
|
|
|
DeviceListEntry);
|
|
|
|
|
|
|
|
/* Keep looping until we find a place to insert */
|
|
|
|
} while (SortKey >= LastEntry->SortKey);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Now insert us */
|
|
|
|
InsertTailList(NextEntry, &DeviceQueueEntry->DeviceListEntry);
|
2005-03-14 02:08:17 +00:00
|
|
|
Inserted = TRUE;
|
2003-10-31 00:14:09 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Release the lock */
|
|
|
|
KiReleaseDeviceQueueLock(&DeviceLock);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Return the state */
|
2005-03-14 02:08:17 +00:00
|
|
|
return Inserted;
|
1998-08-25 04:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 17:44:06 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
1998-08-25 04:27:26 +00:00
|
|
|
*/
|
2005-03-14 02:08:17 +00:00
|
|
|
PKDEVICE_QUEUE_ENTRY
|
2006-09-13 00:20:46 +00:00
|
|
|
NTAPI
|
2005-03-14 02:08:17 +00:00
|
|
|
KeRemoveDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue)
|
1998-08-25 04:27:26 +00:00
|
|
|
{
|
2005-03-14 02:08:17 +00:00
|
|
|
PLIST_ENTRY ListEntry;
|
|
|
|
PKDEVICE_QUEUE_ENTRY ReturnEntry;
|
2006-09-13 00:20:46 +00:00
|
|
|
KLOCK_QUEUE_HANDLE DeviceLock;
|
|
|
|
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2007-03-25 13:23:30 +00:00
|
|
|
DPRINT("KeRemoveDeviceQueue() DevQueue %p\n", DeviceQueue);
|
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Lock the queue */
|
|
|
|
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
2005-03-14 02:08:17 +00:00
|
|
|
ASSERT(DeviceQueue->Busy);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Check if this is an empty queue */
|
|
|
|
if (IsListEmpty(&DeviceQueue->DeviceListHead))
|
|
|
|
{
|
|
|
|
/* Set it to idle and return nothing*/
|
2005-03-14 02:08:17 +00:00
|
|
|
DeviceQueue->Busy = FALSE;
|
|
|
|
ReturnEntry = NULL;
|
2006-09-13 00:20:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Remove the Entry from the List */
|
|
|
|
ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
|
2005-05-09 01:38:29 +00:00
|
|
|
ReturnEntry = CONTAINING_RECORD(ListEntry,
|
2005-03-14 02:08:17 +00:00
|
|
|
KDEVICE_QUEUE_ENTRY,
|
|
|
|
DeviceListEntry);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Set it as non-inserted */
|
|
|
|
ReturnEntry->Inserted = FALSE;
|
|
|
|
}
|
1998-08-25 04:27:26 +00:00
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Release the lock */
|
|
|
|
KiReleaseDeviceQueueLock(&DeviceLock);
|
|
|
|
|
|
|
|
/* Return the entry */
|
2005-03-14 02:08:17 +00:00
|
|
|
return ReturnEntry;
|
1998-08-25 04:27:26 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 17:44:06 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2005-03-14 02:08:17 +00:00
|
|
|
PKDEVICE_QUEUE_ENTRY
|
2006-09-13 00:20:46 +00:00
|
|
|
NTAPI
|
|
|
|
KeRemoveByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
|
|
|
|
IN ULONG SortKey)
|
1998-08-25 04:27:26 +00:00
|
|
|
{
|
2008-08-22 21:24:31 +00:00
|
|
|
PLIST_ENTRY NextEntry;
|
2005-03-14 02:08:17 +00:00
|
|
|
PKDEVICE_QUEUE_ENTRY ReturnEntry;
|
2006-09-13 00:20:46 +00:00
|
|
|
KLOCK_QUEUE_HANDLE DeviceLock;
|
|
|
|
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
2005-03-14 02:08:17 +00:00
|
|
|
|
2007-03-25 13:23:30 +00:00
|
|
|
DPRINT("KeRemoveByKeyDeviceQueue() DevQueue %p, SortKey 0x%x\n", DeviceQueue, SortKey);
|
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Lock the queue */
|
|
|
|
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
2005-03-14 02:08:17 +00:00
|
|
|
ASSERT(DeviceQueue->Busy);
|
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Check if this is an empty queue */
|
|
|
|
if (IsListEmpty(&DeviceQueue->DeviceListHead))
|
|
|
|
{
|
|
|
|
/* Set it to idle and return nothing*/
|
2005-03-14 02:08:17 +00:00
|
|
|
DeviceQueue->Busy = FALSE;
|
|
|
|
ReturnEntry = NULL;
|
2006-09-13 00:20:46 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-03-25 13:23:30 +00:00
|
|
|
/* If SortKey is greater than the last key, then return the first entry right away */
|
2008-08-22 21:24:31 +00:00
|
|
|
NextEntry = &DeviceQueue->DeviceListHead;
|
|
|
|
ReturnEntry = CONTAINING_RECORD(NextEntry->Blink,
|
2007-03-25 13:23:30 +00:00
|
|
|
KDEVICE_QUEUE_ENTRY,
|
|
|
|
DeviceListEntry);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2008-05-22 11:46:46 +00:00
|
|
|
/* Check if we can just get the first entry */
|
|
|
|
if (ReturnEntry->SortKey <= SortKey)
|
2006-09-13 00:20:46 +00:00
|
|
|
{
|
2008-05-22 11:46:46 +00:00
|
|
|
/* Get the first entry */
|
2008-08-22 21:24:31 +00:00
|
|
|
ReturnEntry = CONTAINING_RECORD(NextEntry->Flink,
|
2005-03-14 02:08:17 +00:00
|
|
|
KDEVICE_QUEUE_ENTRY,
|
|
|
|
DeviceListEntry);
|
2007-03-25 13:23:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-05-22 11:46:46 +00:00
|
|
|
/* Loop the list */
|
2008-08-22 21:24:31 +00:00
|
|
|
NextEntry = DeviceQueue->DeviceListHead.Flink;
|
2008-05-22 11:46:46 +00:00
|
|
|
while (TRUE)
|
2007-03-25 13:23:30 +00:00
|
|
|
{
|
2008-08-22 21:24:31 +00:00
|
|
|
/* Make sure we don't go beyond the end of the queue */
|
|
|
|
ASSERT(NextEntry != &DeviceQueue->DeviceListHead);
|
|
|
|
|
2008-05-22 11:46:46 +00:00
|
|
|
/* Get the next entry and check if the key is low enough */
|
2008-08-22 21:24:31 +00:00
|
|
|
ReturnEntry = CONTAINING_RECORD(NextEntry,
|
2007-03-25 13:23:30 +00:00
|
|
|
KDEVICE_QUEUE_ENTRY,
|
|
|
|
DeviceListEntry);
|
2008-05-22 11:46:46 +00:00
|
|
|
if (SortKey <= ReturnEntry->SortKey) break;
|
|
|
|
|
|
|
|
/* Try the next one */
|
2008-08-22 21:24:31 +00:00
|
|
|
NextEntry = NextEntry->Flink;
|
2007-03-25 13:23:30 +00:00
|
|
|
}
|
2006-09-13 00:20:46 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2008-05-22 11:46:46 +00:00
|
|
|
/* We have an entry, remove it now */
|
|
|
|
RemoveEntryList(&ReturnEntry->DeviceListEntry);
|
|
|
|
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Set it as non-inserted */
|
|
|
|
ReturnEntry->Inserted = FALSE;
|
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Release the lock */
|
|
|
|
KiReleaseDeviceQueueLock(&DeviceLock);
|
|
|
|
|
|
|
|
/* Return the entry */
|
2005-03-14 02:08:17 +00:00
|
|
|
return ReturnEntry;
|
1998-08-25 04:27:26 +00:00
|
|
|
}
|
2002-01-04 13:09:37 +00:00
|
|
|
|
IO Manager Cleanup continues:
- Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of
one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some
objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third
system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile,
IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an
example).
- Cleaned up some IRP code and fixed a couple of bugs, mainly:
- Write I/O Type in IRP
- Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code)
- Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect
behaviour. Code should never depend on a buffer being zeroed!
- Remove a lot of duplicated code and helper/alternate functions that weren't really useful.
- Free MDL and IRP on some failures where we didn't
- Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted
in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the
old revision and copy/pasting the new code directly above it. The functions which we touched are:
- IoAllocateIrp
- IoBuild[A]SyncronousFsdRequest
- IoBuildDeviceIoControlRequest
- IoInitializeIrp
- IoPageRead, IoSynchronousPageWrite
svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
|
|
|
/*
|
2006-09-13 00:20:46 +00:00
|
|
|
* @implemented
|
IO Manager Cleanup continues:
- Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of
one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some
objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third
system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile,
IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an
example).
- Cleaned up some IRP code and fixed a couple of bugs, mainly:
- Write I/O Type in IRP
- Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code)
- Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect
behaviour. Code should never depend on a buffer being zeroed!
- Remove a lot of duplicated code and helper/alternate functions that weren't really useful.
- Free MDL and IRP on some failures where we didn't
- Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted
in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the
old revision and copy/pasting the new code directly above it. The functions which we touched are:
- IoAllocateIrp
- IoBuild[A]SyncronousFsdRequest
- IoBuildDeviceIoControlRequest
- IoInitializeIrp
- IoPageRead, IoSynchronousPageWrite
svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
|
|
|
*/
|
|
|
|
PKDEVICE_QUEUE_ENTRY
|
2006-09-13 00:20:46 +00:00
|
|
|
NTAPI
|
IO Manager Cleanup continues:
- Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of
one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some
objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third
system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile,
IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an
example).
- Cleaned up some IRP code and fixed a couple of bugs, mainly:
- Write I/O Type in IRP
- Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code)
- Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect
behaviour. Code should never depend on a buffer being zeroed!
- Remove a lot of duplicated code and helper/alternate functions that weren't really useful.
- Free MDL and IRP on some failures where we didn't
- Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted
in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the
old revision and copy/pasting the new code directly above it. The functions which we touched are:
- IoAllocateIrp
- IoBuild[A]SyncronousFsdRequest
- IoBuildDeviceIoControlRequest
- IoInitializeIrp
- IoPageRead, IoSynchronousPageWrite
svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
|
|
|
KeRemoveByKeyDeviceQueueIfBusy(IN PKDEVICE_QUEUE DeviceQueue,
|
|
|
|
IN ULONG SortKey)
|
|
|
|
{
|
2008-08-22 21:24:31 +00:00
|
|
|
PLIST_ENTRY NextEntry;
|
2006-09-13 00:20:46 +00:00
|
|
|
PKDEVICE_QUEUE_ENTRY ReturnEntry;
|
|
|
|
KLOCK_QUEUE_HANDLE DeviceLock;
|
|
|
|
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
|
|
|
|
2007-03-25 13:23:30 +00:00
|
|
|
DPRINT("KeRemoveByKeyDeviceQueueIfBusy() DevQueue %p, SortKey 0x%x\n", DeviceQueue, SortKey);
|
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Lock the queue */
|
|
|
|
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
|
|
|
|
|
|
|
/* Check if this is an empty or idle queue */
|
|
|
|
if (!(DeviceQueue->Busy) || (IsListEmpty(&DeviceQueue->DeviceListHead)))
|
|
|
|
{
|
|
|
|
/* Set it to idle and return nothing*/
|
|
|
|
DeviceQueue->Busy = FALSE;
|
|
|
|
ReturnEntry = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2008-08-22 21:24:31 +00:00
|
|
|
/* If SortKey is greater than the last key, then return the first entry right away */
|
|
|
|
NextEntry = &DeviceQueue->DeviceListHead;
|
|
|
|
ReturnEntry = CONTAINING_RECORD(NextEntry->Blink,
|
|
|
|
KDEVICE_QUEUE_ENTRY,
|
|
|
|
DeviceListEntry);
|
2006-09-13 00:20:46 +00:00
|
|
|
|
2008-08-22 21:24:31 +00:00
|
|
|
/* Check if we can just get the first entry */
|
|
|
|
if (ReturnEntry->SortKey <= SortKey)
|
2006-09-13 00:20:46 +00:00
|
|
|
{
|
2008-08-22 21:24:31 +00:00
|
|
|
/* Get the first entry */
|
|
|
|
ReturnEntry = CONTAINING_RECORD(NextEntry->Flink,
|
2006-09-13 00:20:46 +00:00
|
|
|
KDEVICE_QUEUE_ENTRY,
|
|
|
|
DeviceListEntry);
|
|
|
|
}
|
2008-08-22 21:24:31 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Loop the list */
|
|
|
|
NextEntry = DeviceQueue->DeviceListHead.Flink;
|
|
|
|
while (TRUE)
|
|
|
|
{
|
|
|
|
/* Make sure we don't go beyond the end of the queue */
|
|
|
|
ASSERT(NextEntry != &DeviceQueue->DeviceListHead);
|
|
|
|
|
|
|
|
/* Get the next entry and check if the key is low enough */
|
|
|
|
ReturnEntry = CONTAINING_RECORD(NextEntry,
|
|
|
|
KDEVICE_QUEUE_ENTRY,
|
|
|
|
DeviceListEntry);
|
|
|
|
if (SortKey <= ReturnEntry->SortKey) break;
|
|
|
|
|
|
|
|
/* Try the next one */
|
|
|
|
NextEntry = NextEntry->Flink;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We have an entry, remove it now */
|
|
|
|
RemoveEntryList(&ReturnEntry->DeviceListEntry);
|
2006-09-13 00:20:46 +00:00
|
|
|
|
|
|
|
/* Set it as non-inserted */
|
|
|
|
ReturnEntry->Inserted = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Release the lock */
|
|
|
|
KiReleaseDeviceQueueLock(&DeviceLock);
|
|
|
|
|
|
|
|
/* Return the entry */
|
|
|
|
return ReturnEntry;
|
IO Manager Cleanup continues:
- Removed many extra files that expanded the I/O Manager too much. We usually stick with the standard of
one object/class per file, like io/device.c or io/controller.c, so it was very confusing to have some
objects split up in 5 or 6 different files, some containing only one api. Additionally, even a third
system was used, were objects were bunched up together by class. This mess was so bad that NtCreateFile,
IopCreateFile, IoCreateFile, IopDeleteFile, NtDeleteFile and NtWriteFile were in 5 different files (as an
example).
- Cleaned up some IRP code and fixed a couple of bugs, mainly:
- Write I/O Type in IRP
- Write proper IRP Flags where they shoudl be used (Will help for completing requests when i clean up that code)
- Do *NOT* zero out buffers or data that shouldn't be zeroed. Scsiport actually dependen on this incorrect
behaviour. Code should never depend on a buffer being zeroed!
- Remove a lot of duplicated code and helper/alternate functions that weren't really useful.
- Free MDL and IRP on some failures where we didn't
- Alphabetized some of the large io files for easier lookup of functions. This and the deletions have resulted
in a completely bloated diff file. I will provide a cleaned up diff on request by manually downloading the
old revision and copy/pasting the new code directly above it. The functions which we touched are:
- IoAllocateIrp
- IoBuild[A]SyncronousFsdRequest
- IoBuildDeviceIoControlRequest
- IoInitializeIrp
- IoPageRead, IoSynchronousPageWrite
svn path=/trunk/; revision=14837
2005-04-28 00:54:59 +00:00
|
|
|
}
|
|
|
|
|
2003-07-10 17:44:06 +00:00
|
|
|
/*
|
2003-10-31 00:14:09 +00:00
|
|
|
* @implemented
|
2003-07-10 17:44:06 +00:00
|
|
|
*/
|
2006-09-13 00:20:46 +00:00
|
|
|
BOOLEAN
|
|
|
|
NTAPI
|
2005-03-14 02:08:17 +00:00
|
|
|
KeRemoveEntryDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
|
|
|
|
IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
|
2002-01-04 13:09:37 +00:00
|
|
|
{
|
2005-03-14 02:08:17 +00:00
|
|
|
BOOLEAN OldState;
|
2006-09-13 00:20:46 +00:00
|
|
|
KLOCK_QUEUE_HANDLE DeviceLock;
|
|
|
|
ASSERT_DEVICE_QUEUE(DeviceQueue);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2007-03-25 13:23:30 +00:00
|
|
|
DPRINT("KeRemoveEntryDeviceQueue() DevQueue %p, Entry %p\n", DeviceQueue, DeviceQueueEntry);
|
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Lock the queue */
|
|
|
|
KiAcquireDeviceQueueLock(DeviceQueue, &DeviceLock);
|
|
|
|
ASSERT(DeviceQueue->Busy);
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2006-09-13 00:20:46 +00:00
|
|
|
/* Check the insertion state */
|
|
|
|
OldState = DeviceQueueEntry->Inserted;
|
|
|
|
if (OldState)
|
|
|
|
{
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Remove it */
|
|
|
|
DeviceQueueEntry->Inserted = FALSE;
|
|
|
|
RemoveEntryList(&DeviceQueueEntry->DeviceListEntry);
|
2003-10-31 00:14:09 +00:00
|
|
|
}
|
2005-05-09 01:38:29 +00:00
|
|
|
|
2005-03-14 02:08:17 +00:00
|
|
|
/* Unlock and return old state */
|
2006-09-13 00:20:46 +00:00
|
|
|
KiReleaseDeviceQueueLock(&DeviceLock);
|
2005-03-14 02:08:17 +00:00
|
|
|
return OldState;
|
2002-01-04 13:09:37 +00:00
|
|
|
}
|