merge Art's tcpip changes to the branch Added: branches/ros-branch-0_2_9/reactos/drivers/lib/chew/ Added: branches/ros-branch-0_2_9/reactos/drivers/lib/chew/chew.xml Added: branches/ros-branch-0_2_9/reactos/drivers/lib/chew/workqueue.c Modified: branches/ros-branch-0_2_9/reactos/drivers/lib/directory.xml Modified: branches/ros-branch-0_2_9/reactos/drivers/lib/ip/transport/tcp/tcp.c Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/datalink/lan.c Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/include/precomp.h Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/include/tcp.h Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip/dispatch.c Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip/main.c Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip.xml Added: branches/ros-branch-0_2_9/reactos/include/chew/ Added: branches/ros-branch-0_2_9/reactos/include/chew/chew.h _____
Added: branches/ros-branch-0_2_9/reactos/drivers/lib/chew/chew.xml --- branches/ros-branch-0_2_9/reactos/drivers/lib/chew/chew.xml 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/drivers/lib/chew/chew.xml 2005-12-14 10:28:30 UTC (rev 20162) @@ -0,0 +1,7 @@
+<module name="chew" type="staticlibrary"> + <define name="__USE_W32API" /> + <define name="_NTOSKRNL_" /> + <include base="chew">include</include> + <include base="reactos">w32api/include/ddk</include> + <file>workqueue.c</file> +</module> \ No newline at end of file _____
Added: branches/ros-branch-0_2_9/reactos/drivers/lib/chew/workqueue.c --- branches/ros-branch-0_2_9/reactos/drivers/lib/chew/workqueue.c 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/drivers/lib/chew/workqueue.c 2005-12-14 10:28:30 UTC (rev 20162) @@ -0,0 +1,106 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: drivers/lib/chew/workqueue.c + * PURPOSE: Common Highlevel Executive Worker + * + * PROGRAMMERS: arty (ayerkes@speakeasy.net) + */ +#include <ntddk.h> +#include <chew/chew.h> + +#define NDEBUG + +#define FOURCC(w,x,y,z) (((w) << 24) | ((x) << 16) | ((y) << 8) | (z)) + +PDEVICE_OBJECT WorkQueueDevice; +LIST_ENTRY WorkQueue; +KSPIN_LOCK WorkQueueLock; + +typedef struct _WORK_ITEM { + LIST_ENTRY Entry; + PIO_WORKITEM WorkItem; + VOID (*Worker)( PVOID Data ); + CHAR UserSpace[1]; +} WORK_ITEM, *PWORK_ITEM; + +VOID ChewInit( PDEVICE_OBJECT DeviceObject ) { + WorkQueueDevice = DeviceObject; + InitializeListHead( &WorkQueue ); + KeInitializeSpinLock( &WorkQueueLock ); +} + +VOID ChewShutdown() { + KIRQL OldIrql; + PLIST_ENTRY Entry; + PWORK_ITEM WorkItem; + + KeAcquireSpinLock( &WorkQueueLock, &OldIrql ); + + while( !IsListEmpty( &WorkQueue ) ) { + Entry = RemoveHeadList( &WorkQueue ); + WorkItem = CONTAINING_RECORD( Entry, WORK_ITEM, Entry ); + IoFreeWorkItem( WorkItem->WorkItem ); + ExFreePool( WorkItem ); + } + + KeReleaseSpinLock( &WorkQueueLock, OldIrql ); +} + +VOID STDCALL ChewWorkItem( PDEVICE_OBJECT DeviceObject, PVOID ChewItem ) { + PWORK_ITEM WorkItem = ChewItem; + + RemoveEntryList( &WorkItem->Entry ); + + if( WorkItem->Worker ) + WorkItem->Worker( WorkItem->UserSpace ); + + IoFreeWorkItem( WorkItem->WorkItem ); + ExFreePool( WorkItem ); +} + +BOOLEAN ChewCreate +( PVOID *ItemPtr, UINT Bytes, VOID (*Worker)( PVOID ), PVOID UserSpace ) { + PWORK_ITEM Item; + + if( KeGetCurrentIrql() == PASSIVE_LEVEL ) { + if( ItemPtr ) + *ItemPtr = NULL; + Worker(UserSpace); + return TRUE; + } else { + Item = ExAllocatePoolWithTag + ( NonPagedPool, + sizeof( WORK_ITEM ) + Bytes - 1, + FOURCC('C','H','E','W') ); + + if( Item ) { + Item->WorkItem = IoAllocateWorkItem( WorkQueueDevice ); + if( !Item->WorkItem ) { + ExFreePool( Item ); + return FALSE; + } + Item->Worker = Worker; + if( Bytes && UserSpace ) + RtlCopyMemory( Item->UserSpace, UserSpace, Bytes ); + + ExInterlockedInsertTailList + ( &WorkQueue, &Item->Entry, &WorkQueueLock ); + IoQueueWorkItem + ( Item->WorkItem, ChewWorkItem, CriticalWorkQueue, Item ); + + if( ItemPtr ) + *ItemPtr = Item; + + return TRUE; + } else { + return FALSE; + } + } +} + +VOID ChewRemove( PVOID Item ) { + PWORK_ITEM WorkItem = Item; + IoFreeWorkItem( WorkItem->WorkItem ); + ExFreePool( WorkItem ); +} _____
Modified: branches/ros-branch-0_2_9/reactos/drivers/lib/directory.xml --- branches/ros-branch-0_2_9/reactos/drivers/lib/directory.xml 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/drivers/lib/directory.xml 2005-12-14 10:28:30 UTC (rev 20162) @@ -10,3 +10,6 @@
<directory name="oskittcp"> <xi:include href="oskittcp/oskittcp.xml" /> </directory> +<directory name="chew"> + <xi:include href="chew/chew.xml" /> +</directory> \ No newline at end of file _____
Modified: branches/ros-branch-0_2_9/reactos/drivers/lib/ip/transport/tcp/tcp.c --- branches/ros-branch-0_2_9/reactos/drivers/lib/ip/transport/tcp/tcp.c 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/drivers/lib/ip/transport/tcp/tcp.c 2005-12-14 10:28:30 UTC (rev 20162) @@ -647,4 +647,34 @@
return STATUS_SUCCESS; }
+VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { + PLIST_ENTRY Entry; + PLIST_ENTRY ListHead[4]; + KIRQL OldIrql; + PTDI_BUCKET Bucket; + UINT i = 0; + + ListHead[0] = &Endpoint->ReceiveRequest; + ListHead[1] = &Endpoint->ConnectRequest; + ListHead[2] = &Endpoint->ListenRequest; + ListHead[3] = 0; + + TcpipAcquireSpinLock( &Endpoint->Lock, &OldIrql ); + + for( i = 0; ListHead[i]; i++ ) { + for( Entry = ListHead[i]->Flink; + Entry != ListHead[i]; + Entry = Entry->Flink ) { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + + if( Bucket->Request.RequestContext == Irp ) { + RemoveEntryList( &Bucket->Entry ); + break; + } + } + } + + TcpipReleaseSpinLock( &Endpoint->Lock, OldIrql ); +} + /* EOF */ _____
Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/datalink/lan.c --- branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/datalink/lan.c 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/datalink/lan.c 2005-12-14 10:28:30 UTC (rev 20162) @@ -51,11 +51,6 @@
LIST_ENTRY AdapterListHead; KSPIN_LOCK AdapterListLock;
-/* Work around being called back into afd at Dpc level */ -KSPIN_LOCK LanWorkLock; -LIST_ENTRY LanWorkList; -WORK_QUEUE_ITEM LanWorkItem; - /* Double complete protection */ KSPIN_LOCK LanSendCompleteLock; LIST_ENTRY LanSendCompleteList; @@ -289,10 +284,9 @@ } }
-VOID STDCALL LanReceiveWorker( PVOID Context ) { +VOID LanReceiveWorker( PVOID Context ) { UINT PacketType; - PLIST_ENTRY ListEntry; - PLAN_WQ_ITEM WorkItem; + PLAN_WQ_ITEM WorkItem = (PLAN_WQ_ITEM)Context; PNDIS_PACKET Packet; PLAN_ADAPTER Adapter; UINT BytesTransferred; @@ -301,60 +295,49 @@
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
- while( (ListEntry = - ExInterlockedRemoveHeadList( &LanWorkList, &LanWorkLock )) ) { - WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); - - TI_DbgPrint(DEBUG_DATALINK, ("WorkItem: %x\n", WorkItem)); - - Packet = WorkItem->Packet; - Adapter = WorkItem->Adapter; - BytesTransferred = WorkItem->BytesTransferred; - - ExFreePool( WorkItem ); - - IPPacket.NdisPacket = Packet; - - NdisGetFirstBufferFromPacket(Packet, - &NdisBuffer, - &IPPacket.Header, - &IPPacket.ContigSize, - &IPPacket.TotalSize); - - IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred; - /* Determine which upper layer protocol that should receive - this packet and pass it to the correct receive handler */ - - TI_DbgPrint(MID_TRACE, - ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", - IPPacket.ContigSize, IPPacket.TotalSize, - BytesTransferred)); - - PacketType = PC(IPPacket.NdisPacket)->PacketType; - IPPacket.Position = 0; - - TI_DbgPrint - (DEBUG_DATALINK, - ("Ether Type = %x ContigSize = %d Total = %d\n", - PacketType, IPPacket.ContigSize, IPPacket.TotalSize)); - - switch (PacketType) { - case ETYPE_IPv4: - case ETYPE_IPv6: - TI_DbgPrint(MID_TRACE,("Received IP Packet\n")); - IPReceive(Adapter->Context, &IPPacket); - break; - case ETYPE_ARP: - TI_DbgPrint(MID_TRACE,("Received ARP Packet\n")); - ARPReceive(Adapter->Context, &IPPacket); - default: - break; - } - - FreeNdisPacket( Packet ); + Packet = WorkItem->Packet; + Adapter = WorkItem->Adapter; + BytesTransferred = WorkItem->BytesTransferred; + + IPPacket.NdisPacket = Packet; + + NdisGetFirstBufferFromPacket(Packet, + &NdisBuffer, + &IPPacket.Header, + &IPPacket.ContigSize, + &IPPacket.TotalSize); + + IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred; + /* Determine which upper layer protocol that should receive + this packet and pass it to the correct receive handler */ + + TI_DbgPrint(MID_TRACE, + ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n", + IPPacket.ContigSize, IPPacket.TotalSize, + BytesTransferred)); + + PacketType = PC(IPPacket.NdisPacket)->PacketType; + IPPacket.Position = 0; + + TI_DbgPrint + (DEBUG_DATALINK, + ("Ether Type = %x ContigSize = %d Total = %d\n", + PacketType, IPPacket.ContigSize, IPPacket.TotalSize)); + + switch (PacketType) { + case ETYPE_IPv4: + case ETYPE_IPv6: + TI_DbgPrint(MID_TRACE,("Received IP Packet\n")); + IPReceive(Adapter->Context, &IPPacket); + break; + case ETYPE_ARP: + TI_DbgPrint(MID_TRACE,("Received ARP Packet\n")); + ARPReceive(Adapter->Context, &IPPacket); + default: + break; } - TI_DbgPrint(DEBUG_DATALINK, ("Leaving\n")); - LanReceiveWorkerBusy = FALSE; + + FreeNdisPacket( Packet ); }
VOID LanSubmitReceiveWork( @@ -362,34 +345,19 @@ PNDIS_PACKET Packet, NDIS_STATUS Status, UINT BytesTransferred) { - PLAN_WQ_ITEM WQItem; + LAN_WQ_ITEM WQItem; PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; - KIRQL OldIrql; + PVOID LanWorkItem;
TI_DbgPrint(DEBUG_DATALINK,("called\n"));
- TcpipAcquireSpinLock( &LanWorkLock, &OldIrql ); + WQItem.Packet = Packet; + WQItem.Adapter = Adapter; + WQItem.BytesTransferred = BytesTransferred;
- WQItem = ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) ); - if( !WQItem ) { - TcpipReleaseSpinLock( &LanWorkLock, OldIrql ); - return; - } - - WQItem->Packet = Packet; - WQItem->Adapter = Adapter; - WQItem->BytesTransferred = BytesTransferred; - InsertTailList( &LanWorkList, &WQItem->ListEntry ); - if( !LanReceiveWorkerBusy ) { - LanReceiveWorkerBusy = TRUE; - ExQueueWorkItem( &LanWorkItem, CriticalWorkQueue ); - TI_DbgPrint(DEBUG_DATALINK, - ("Work item inserted %x %x\n", &LanWorkItem, WQItem)); - } else { - TI_DbgPrint(DEBUG_DATALINK, - ("LAN WORKER BUSY %x %x\n", &LanWorkItem, WQItem)); - } - TcpipReleaseSpinLock( &LanWorkLock, OldIrql ); + if( !ChewCreate + ( &LanWorkItem, sizeof(LAN_WQ_ITEM), LanReceiveWorker, &WQItem ) ) + ASSERT(0); }
VOID STDCALL ProtocolTransferDataComplete( @@ -452,7 +420,6 @@ PNDIS_PACKET NdisPacket; PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; PETH_HEADER EHeader = (PETH_HEADER)HeaderBuffer; - KIRQL OldIrql;
TI_DbgPrint(DEBUG_DATALINK, ("Called. (packetsize %d)\n",PacketSize));
@@ -490,12 +457,9 @@ TI_DbgPrint(DEBUG_DATALINK, ("Adapter: %x (MTU %d)\n", Adapter, Adapter->MTU));
- TcpipAcquireSpinLock( &LanWorkLock, &OldIrql ); - NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL, PacketSize + HeaderBufferSize ); if( NdisStatus != NDIS_STATUS_SUCCESS ) { - TcpipReleaseSpinLock( &LanWorkLock, OldIrql ); return NDIS_STATUS_NOT_ACCEPTED; }
@@ -534,7 +498,6 @@ BytesTransferred = 0; } } - TcpipReleaseSpinLock( &LanWorkLock, OldIrql ); TI_DbgPrint(DEBUG_DATALINK, ("Calling complete\n"));
if (NdisStatus != NDIS_STATUS_PENDING) @@ -1369,10 +1332,8 @@ }
VOID LANStartup() { - InitializeListHead( &LanWorkList ); InitializeListHead( &LanSendCompleteList ); KeInitializeSpinLock( &LanSendCompleteLock ); - ExInitializeWorkItem( &LanWorkItem, LanReceiveWorker, NULL ); }
VOID LANShutdown() { @@ -1380,15 +1341,6 @@ PLAN_WQ_ITEM WorkItem; PLIST_ENTRY ListEntry;
- TcpipAcquireSpinLock( &LanWorkLock, &OldIrql ); - while( !IsListEmpty( &LanWorkList ) ) { - ListEntry = RemoveHeadList( &LanWorkList ); - WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry); - FreeNdisPacket( WorkItem->Packet ); - ExFreePool( WorkItem ); - } - TcpipReleaseSpinLock( &LanWorkLock, OldIrql ); - KeAcquireSpinLock( &LanSendCompleteLock, &OldIrql ); while( !IsListEmpty( &LanSendCompleteList ) ) { ListEntry = RemoveHeadList( &LanSendCompleteList ); _____
Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/include/precomp.h --- branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/include/precomp.h 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/include/precomp.h 2005-12-14 10:28:30 UTC (rev 20162) @@ -36,4 +36,4 @@
#include <ports.h> #include <ipifcons.h> #include <ndk/ntndk.h> - +#include <chew/chew.h> _____
Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/include/tcp.h --- branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/include/tcp.h 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/include/tcp.h 2005-12-14 10:28:30 UTC (rev 20162) @@ -176,4 +176,6 @@
NTSTATUS TCPShutdown( VOID);
+VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp ); + #endif /* __TCP_H */ _____
Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip/dispatch.c --- branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip/dispatch.c 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip/dispatch.c 2005-12-14 10:28:30 UTC (rev 20162) @@ -135,7 +135,31 @@
TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n")); }
+typedef struct _DISCONNECT_TYPE { + UINT Type; + PVOID Context; + PIRP Irp; + PFILE_OBJECT FileObject; +} DISCONNECT_TYPE, *PDISCONNECT_TYPE;
+VOID DispDoDisconnect( PVOID Data ) { + PDISCONNECT_TYPE DisType = (PDISCONNECT_TYPE)Data; + + TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect\n")); + TCPDisconnect + ( DisType->Context, + DisType->Type, + NULL, + NULL, + DispDataRequestComplete, + DisType->Irp ); + TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n")); + + DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0); + + DispCancelComplete(DisType->FileObject); +} + VOID DDKAPI DispCancelRequest( PDEVICE_OBJECT Device, PIRP Irp) @@ -150,6 +174,8 @@ PTRANSPORT_CONTEXT TranContext; PFILE_OBJECT FileObject; UCHAR MinorFunction; + DISCONNECT_TYPE DisType; + PVOID WorkItem; /*NTSTATUS Status = STATUS_SUCCESS;*/
TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -161,6 +187,8 @@
TI_DbgPrint(DEBUG_IRP, ("IRP at (0x%X) MinorFunction (0x%X) IrpSp (0x%X).\n", Irp, MinorFunction, IrpSp));
+ Irp->IoStatus.Status = STATUS_PENDING; + #ifdef DBG if (!Irp->Cancel) TI_DbgPrint(MIN_TRACE, ("Irp->Cancel is FALSE, should be TRUE.\n")); @@ -169,26 +197,22 @@ /* Try canceling the request */ switch(MinorFunction) { case TDI_SEND: - TCPDisconnect - ( TranContext->Handle.ConnectionContext, - TDI_DISCONNECT_RELEASE, - NULL, - NULL, - DispDataRequestComplete, - Irp ); - break; + case TDI_RECEIVE: + DisType.Type = TDI_DISCONNECT_RELEASE | + ((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0); + DisType.Context = TranContext->Handle.ConnectionContext; + DisType.Irp = Irp; + DisType.FileObject = FileObject; + + TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
- case TDI_RECEIVE: - TCPDisconnect - ( TranContext->Handle.ConnectionContext, - TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE, - NULL, - NULL, - DispDataRequestComplete, - Irp ); + if( !ChewCreate( &WorkItem, sizeof(DISCONNECT_TYPE), + DispDoDisconnect, &DisType ) ) + ASSERT(0); break;
case TDI_SEND_DATAGRAM: + Irp->IoStatus.Status = STATUS_CANCELLED; if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { TI_DbgPrint(MIN_TRACE, ("TDI_SEND_DATAGRAM, but no address file.\n")); break; @@ -198,6 +222,7 @@ break;
case TDI_RECEIVE_DATAGRAM: + Irp->IoStatus.Status = STATUS_CANCELLED; if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { TI_DbgPrint(MIN_TRACE, ("TDI_RECEIVE_DATAGRAM, but no address file.\n")); break; @@ -211,10 +236,11 @@ break; }
+ if( Irp->IoStatus.Status == STATUS_PENDING ) + IoMarkIrpPending(Irp); + IoReleaseCancelSpinLock(Irp->CancelIrql);
- DispCancelComplete(FileObject); - TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); }
_____
Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip/main.c --- branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip/main.c 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip/main.c 2005-12-14 10:28:30 UTC (rev 20162) @@ -619,6 +619,8 @@
} TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); #endif + ChewShutdown(); + /* Cancel timer */ KeCancelTimer(&IPTimer);
@@ -734,6 +736,8 @@ return Status; }
+ ChewInit( IPDeviceObject ); + /* Create RawIP device object */ Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject); _____
Modified: branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip.xml --- branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip.xml 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/drivers/net/tcpip/tcpip.xml 2005-12-14 10:28:30 UTC (rev 20162) @@ -9,6 +9,7 @@
<library>oskittcp</library> <library>ndis</library> <library>pseh</library> + <library>chew</library> <library>ntoskrnl</library> <library>hal</library> <directory name="include"> _____
Added: branches/ros-branch-0_2_9/reactos/include/chew/chew.h --- branches/ros-branch-0_2_9/reactos/include/chew/chew.h 2005-12-14 09:26:52 UTC (rev 20161) +++ branches/ros-branch-0_2_9/reactos/include/chew/chew.h 2005-12-14 10:28:30 UTC (rev 20162) @@ -0,0 +1,40 @@
+/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: include/chew/chew.h + * PURPOSE: Common Highlevel Executive Worker + * + * PROGRAMMERS: arty (ayerkes@speakeasy.net) + */ + +#ifndef _REACTOS_CHEW_H +#define _REACTOS_CHEW_H + +/** + * Initialize CHEW, given a device object (since IoAllocateWorkItem relies on + * it). + */ +VOID ChewInit( PDEVICE_OBJECT DeviceObject ); +/** + * Shutdown CHEW, including removing remaining work items. + */ +VOID ChewShutdown(); +/** + * Create a work item, or perform the work, based on IRQL. + * At passive level, Worker is called directly on UserSpace. + * At greater than passive level, a work item is created with Bytes + * context area and data copied from UserSpace. + * If a work item is created, Item contains the address and the function + * returns true. + * If the work is performed immediately, Item contains NULL and the + * function returns true. + * Else, the function returns false and Item is undefined. + */ +BOOLEAN ChewCreate +( PVOID *Item, UINT Bytes, VOID (*Worker)(PVOID), PVOID UserSpace ); +/** + * Remove a work item, given the pointer returned to Item in ChewCreate. + */ +VOID ChewRemove( PVOID Item ); + +#endif/*_REACTOS_CHEW_H*/