mirror of
https://github.com/reactos/reactos.git
synced 2025-04-19 12:08:55 +00:00
Fixed a race condition on unload, other minor clean-up, now loads and runs correctly on win2ksp4 checked w/ full verifier
svn path=/trunk/; revision=6800
This commit is contained in:
parent
d50eee1838
commit
fcfd77241a
2 changed files with 38 additions and 43 deletions
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
|
|
||||||
extern DWORD DebugTraceLevel;
|
extern ULONG DebugTraceLevel;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,10 @@
|
||||||
* FILE: tditest.c
|
* FILE: tditest.c
|
||||||
* PURPOSE: Testing TDI drivers
|
* PURPOSE: Testing TDI drivers
|
||||||
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
|
||||||
|
* Vizzini (vizzini@plasmic.com)
|
||||||
* REVISIONS:
|
* REVISIONS:
|
||||||
* CSH 01/08-2000 Created
|
* CSH 01/08-2000 Created
|
||||||
|
* 26-Nov-2003 Vizzini Updated to run properly on Win2ksp4
|
||||||
*/
|
*/
|
||||||
#include <tditest.h>
|
#include <tditest.h>
|
||||||
|
|
||||||
|
@ -24,12 +26,7 @@ ULONG LocalAddress;
|
||||||
BOOLEAN OpenError;
|
BOOLEAN OpenError;
|
||||||
KEVENT StopEvent;
|
KEVENT StopEvent;
|
||||||
HANDLE SendThread;
|
HANDLE SendThread;
|
||||||
KEVENT SendThreadEvent;
|
|
||||||
HANDLE ReceiveThread;
|
HANDLE ReceiveThread;
|
||||||
KEVENT ReceiveThreadEvent;
|
|
||||||
PVOID ReceiveThreadObject;
|
|
||||||
PVOID SendThreadObject;
|
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS TdiCall(
|
NTSTATUS TdiCall(
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
|
@ -65,7 +62,7 @@ NTSTATUS TdiCall(
|
||||||
{
|
{
|
||||||
if (CanCancel)
|
if (CanCancel)
|
||||||
{
|
{
|
||||||
Status = KeWaitForMultipleObjects(2, (PVOID)&Events, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
|
Status = KeWaitForMultipleObjects(2, (PVOID)Events, WaitAny, Executive, KernelMode, FALSE, NULL, NULL);
|
||||||
|
|
||||||
if (KeReadStateEvent(&StopEvent) != 0)
|
if (KeReadStateEvent(&StopEvent) != 0)
|
||||||
{
|
{
|
||||||
|
@ -112,13 +109,15 @@ NTSTATUS TdiOpenDevice(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
RtlInitUnicodeString(&Name, Protocol);
|
RtlInitUnicodeString(&Name, Protocol);
|
||||||
InitializeObjectAttributes(&Attr, /* Attribute buffer */
|
InitializeObjectAttributes(
|
||||||
|
&Attr, /* Attribute buffer */
|
||||||
&Name, /* Device name */
|
&Name, /* Device name */
|
||||||
OBJ_CASE_INSENSITIVE, /* Attributes */
|
OBJ_CASE_INSENSITIVE, /* Attributes */
|
||||||
NULL, /* Root directory */
|
NULL, /* Root directory */
|
||||||
NULL); /* Security descriptor */
|
NULL); /* Security descriptor */
|
||||||
|
|
||||||
Status = ZwCreateFile(Handle, /* Return file handle */
|
Status = ZwCreateFile(
|
||||||
|
Handle, /* Return file handle */
|
||||||
GENERIC_READ | GENERIC_WRITE, /* Desired access */
|
GENERIC_READ | GENERIC_WRITE, /* Desired access */
|
||||||
&Attr, /* Object attributes */
|
&Attr, /* Object attributes */
|
||||||
&Iosb, /* IO status */
|
&Iosb, /* IO status */
|
||||||
|
@ -132,7 +131,8 @@ NTSTATUS TdiOpenDevice(
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
Status = ObReferenceObjectByHandle(*Handle, /* Handle to open file */
|
Status = ObReferenceObjectByHandle(
|
||||||
|
*Handle, /* Handle to open file */
|
||||||
GENERIC_READ | GENERIC_WRITE, /* Access mode */
|
GENERIC_READ | GENERIC_WRITE, /* Access mode */
|
||||||
NULL, /* Object type */
|
NULL, /* Object type */
|
||||||
KernelMode, /* Access mode */
|
KernelMode, /* Access mode */
|
||||||
|
@ -189,7 +189,7 @@ NTSTATUS TdiOpenTransport(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG EaLength;
|
ULONG EaLength;
|
||||||
|
|
||||||
/* EaName *must* be 0-termed, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
|
/* EaName must be 0-termed, even though TDI_TRANSPORT_ADDRESS_LENGTH does *not* include the 0 */
|
||||||
EaLength = sizeof(FILE_FULL_EA_INFORMATION) + TDI_TRANSPORT_ADDRESS_LENGTH + sizeof(TA_IP_ADDRESS) + 1;
|
EaLength = sizeof(FILE_FULL_EA_INFORMATION) + TDI_TRANSPORT_ADDRESS_LENGTH + sizeof(TA_IP_ADDRESS) + 1;
|
||||||
EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength);
|
EaInfo = (PFILE_FULL_EA_INFORMATION)ExAllocatePool(NonPagedPool, EaLength);
|
||||||
|
|
||||||
|
@ -304,7 +304,8 @@ NTSTATUS TdiQueryInformationEx(
|
||||||
QueryInfo.ID.toi_type = Type;
|
QueryInfo.ID.toi_type = Type;
|
||||||
QueryInfo.ID.toi_id = Id;
|
QueryInfo.ID.toi_id = Id;
|
||||||
|
|
||||||
return TdiQueryDeviceControl(FileObject, /* Transport/connection object */
|
return TdiQueryDeviceControl(
|
||||||
|
FileObject, /* Transport/connection object */
|
||||||
IOCTL_TCP_QUERY_INFORMATION_EX, /* Control code */
|
IOCTL_TCP_QUERY_INFORMATION_EX, /* Control code */
|
||||||
&QueryInfo, /* Input buffer */
|
&QueryInfo, /* Input buffer */
|
||||||
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), /* Input buffer length */
|
sizeof(TCP_REQUEST_QUERY_INFORMATION_EX), /* Input buffer length */
|
||||||
|
@ -347,7 +348,8 @@ NTSTATUS TdiQueryAddress(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Query device for supported entities */
|
/* Query device for supported entities */
|
||||||
Status = TdiQueryInformationEx(FileObject, /* File object */
|
Status = TdiQueryInformationEx(
|
||||||
|
FileObject, /* File object */
|
||||||
GENERIC_ENTITY, /* Entity */
|
GENERIC_ENTITY, /* Entity */
|
||||||
TL_INSTANCE, /* Instance */
|
TL_INSTANCE, /* Instance */
|
||||||
INFO_CLASS_GENERIC, /* Entity class */
|
INFO_CLASS_GENERIC, /* Entity class */
|
||||||
|
@ -374,7 +376,8 @@ NTSTATUS TdiQueryAddress(
|
||||||
{
|
{
|
||||||
/* Query device for entity type */
|
/* Query device for entity type */
|
||||||
BufferSize = sizeof(EntityType);
|
BufferSize = sizeof(EntityType);
|
||||||
Status = TdiQueryInformationEx(FileObject, /* File object */
|
Status = TdiQueryInformationEx(
|
||||||
|
FileObject, /* File object */
|
||||||
CL_NL_ENTITY, /* Entity */
|
CL_NL_ENTITY, /* Entity */
|
||||||
Entities[i].tei_instance, /* Instance */
|
Entities[i].tei_instance, /* Instance */
|
||||||
INFO_CLASS_GENERIC, /* Entity class */
|
INFO_CLASS_GENERIC, /* Entity class */
|
||||||
|
@ -391,7 +394,8 @@ NTSTATUS TdiQueryAddress(
|
||||||
|
|
||||||
/* Query device for SNMP information */
|
/* Query device for SNMP information */
|
||||||
BufferSize = sizeof(SnmpInfo);
|
BufferSize = sizeof(SnmpInfo);
|
||||||
Status = TdiQueryInformationEx(FileObject, /* File object */
|
Status = TdiQueryInformationEx(
|
||||||
|
FileObject, /* File object */
|
||||||
CL_NL_ENTITY, /* Entity */
|
CL_NL_ENTITY, /* Entity */
|
||||||
Entities[i].tei_instance, /* Instance */
|
Entities[i].tei_instance, /* Instance */
|
||||||
INFO_CLASS_PROTOCOL, /* Entity class */
|
INFO_CLASS_PROTOCOL, /* Entity class */
|
||||||
|
@ -417,7 +421,8 @@ NTSTATUS TdiQueryAddress(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = TdiQueryInformationEx(FileObject, /* File object */
|
Status = TdiQueryInformationEx(
|
||||||
|
FileObject, /* File object */
|
||||||
CL_NL_ENTITY, /* Entity */
|
CL_NL_ENTITY, /* Entity */
|
||||||
Entities[i].tei_instance, /* Instance */
|
Entities[i].tei_instance, /* Instance */
|
||||||
INFO_CLASS_PROTOCOL, /* Entity class */
|
INFO_CLASS_PROTOCOL, /* Entity class */
|
||||||
|
@ -746,7 +751,7 @@ VOID TdiSendThread(
|
||||||
while (NT_SUCCESS(Status))
|
while (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Wait until timeout or stop flag is set */
|
/* Wait until timeout or stop flag is set */
|
||||||
KeWaitForMultipleObjects( 2, (PVOID)&Events, WaitAny, Executive, KernelMode, FALSE, &Timeout, NULL);
|
KeWaitForMultipleObjects( 2, (PVOID)Events, WaitAny, Executive, KernelMode, FALSE, &Timeout, NULL);
|
||||||
|
|
||||||
if (KeReadStateEvent(&StopEvent) != 0)
|
if (KeReadStateEvent(&StopEvent) != 0)
|
||||||
{
|
{
|
||||||
|
@ -765,8 +770,6 @@ VOID TdiSendThread(
|
||||||
|
|
||||||
TDI_DbgPrint(MAX_TRACE, ("Terminating send thread...\n"));
|
TDI_DbgPrint(MAX_TRACE, ("Terminating send thread...\n"));
|
||||||
|
|
||||||
KeSetEvent(&SendThreadEvent, 0, FALSE);
|
|
||||||
|
|
||||||
PsTerminateSystemThread(STATUS_SUCCESS);
|
PsTerminateSystemThread(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -813,8 +816,6 @@ VOID TdiReceiveThread(
|
||||||
|
|
||||||
TDI_DbgPrint(MAX_TRACE, ("Terminating receive thread...\n"));
|
TDI_DbgPrint(MAX_TRACE, ("Terminating receive thread...\n"));
|
||||||
|
|
||||||
KeSetEvent(&ReceiveThreadEvent, 0, FALSE);
|
|
||||||
|
|
||||||
PsTerminateSystemThread(STATUS_SUCCESS);
|
PsTerminateSystemThread(STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -868,19 +869,25 @@ VOID TdiUnload(
|
||||||
* DriverObject = Pointer to a driver object for this driver
|
* DriverObject = Pointer to a driver object for this driver
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
PVOID ReceiveThreadObject = 0;
|
||||||
|
PVOID SendThreadObject = 0;
|
||||||
|
|
||||||
TDI_DbgPrint(MAX_TRACE, ("Setting stop flag\n"));
|
TDI_DbgPrint(MAX_TRACE, ("Setting stop flag\n"));
|
||||||
|
|
||||||
|
/* Get pointers to the thread objects */
|
||||||
|
ObReferenceObjectByHandle(SendThread, THREAD_ALL_ACCESS, NULL, KernelMode, &SendThreadObject, NULL);
|
||||||
|
ObReferenceObjectByHandle(ReceiveThread, THREAD_ALL_ACCESS, NULL, KernelMode, &ReceiveThreadObject, NULL);
|
||||||
|
|
||||||
|
ASSERT(ReceiveThreadObject);
|
||||||
|
ASSERT(SendThreadObject);
|
||||||
|
|
||||||
KeSetEvent(&StopEvent, 0, FALSE);
|
KeSetEvent(&StopEvent, 0, FALSE);
|
||||||
|
|
||||||
/* Wait for send thread to stop */
|
/* Wait for send thread to stop */
|
||||||
KeWaitForSingleObject(&SendThreadEvent, Executive, KernelMode, FALSE, NULL);
|
KeWaitForSingleObject(SendThreadObject, Executive, KernelMode, FALSE, NULL);
|
||||||
|
|
||||||
ObDereferenceObject(SendThreadObject);
|
|
||||||
|
|
||||||
/* Wait for receive thread to stop */
|
/* Wait for receive thread to stop */
|
||||||
KeWaitForSingleObject(&ReceiveThreadEvent, Executive, KernelMode, FALSE, NULL);
|
KeWaitForSingleObject(ReceiveThreadObject, Executive, KernelMode, FALSE, NULL);
|
||||||
|
|
||||||
ObDereferenceObject(ReceiveThreadObject);
|
|
||||||
|
|
||||||
/* Close device */
|
/* Close device */
|
||||||
TdiCloseDevice(TdiTransport, TdiTransportObject);
|
TdiCloseDevice(TdiTransport, TdiTransportObject);
|
||||||
|
@ -908,8 +915,6 @@ DriverEntry(
|
||||||
WORK_QUEUE_ITEM WorkItem;
|
WORK_QUEUE_ITEM WorkItem;
|
||||||
|
|
||||||
KeInitializeEvent(&StopEvent, NotificationEvent, FALSE);
|
KeInitializeEvent(&StopEvent, NotificationEvent, FALSE);
|
||||||
KeInitializeEvent(&SendThreadEvent, NotificationEvent, FALSE);
|
|
||||||
KeInitializeEvent(&ReceiveThreadEvent, NotificationEvent, FALSE);
|
|
||||||
|
|
||||||
/* Call TdiOpenThread() */
|
/* Call TdiOpenThread() */
|
||||||
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
|
||||||
|
@ -918,7 +923,8 @@ DriverEntry(
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL);
|
KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, NULL);
|
||||||
|
|
||||||
/* Create a UDP send thread that sends a dgram every 2 seconds */
|
/* Create a UDP send thread that sends a dgram every 2 seconds */
|
||||||
Status = PsCreateSystemThread(&SendThread, /* Thread handle */
|
Status = PsCreateSystemThread(
|
||||||
|
&SendThread, /* Thread handle */
|
||||||
0, /* Desired access */
|
0, /* Desired access */
|
||||||
NULL, /* Object attributes */
|
NULL, /* Object attributes */
|
||||||
NULL, /* Process handle */
|
NULL, /* Process handle */
|
||||||
|
@ -932,11 +938,9 @@ DriverEntry(
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a pointer to the thread object */
|
|
||||||
ObReferenceObjectByHandle(SendThread, THREAD_ALL_ACCESS, NULL, KernelMode, &SendThreadObject, NULL);
|
|
||||||
|
|
||||||
/* Create a UDP receive thread */
|
/* Create a UDP receive thread */
|
||||||
Status = PsCreateSystemThread(&ReceiveThread, /* Thread handle */
|
Status = PsCreateSystemThread(
|
||||||
|
&ReceiveThread, /* Thread handle */
|
||||||
0, /* Desired access */
|
0, /* Desired access */
|
||||||
NULL, /* Object attributes */
|
NULL, /* Object attributes */
|
||||||
NULL, /* Process handle */
|
NULL, /* Process handle */
|
||||||
|
@ -948,18 +952,9 @@ DriverEntry(
|
||||||
{
|
{
|
||||||
TDI_DbgPrint(MIN_TRACE, ("PsCreateSystemThread() failed for receive thread (Status = 0x%X).\n", Status));
|
TDI_DbgPrint(MIN_TRACE, ("PsCreateSystemThread() failed for receive thread (Status = 0x%X).\n", Status));
|
||||||
ZwClose(SendThread);
|
ZwClose(SendThread);
|
||||||
ObDereferenceObject(SendThreadObject); /* deref the extra ref we took above */
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a pointer to the thread object */
|
|
||||||
ObReferenceObjectByHandle(ReceiveThread, THREAD_ALL_ACCESS, NULL, KernelMode, &ReceiveThreadObject, NULL);
|
|
||||||
|
|
||||||
/* Don't need these for anything, so we might as well close them now.
|
|
||||||
The threads will call PsTerminateSystemThread themselves when they are done */
|
|
||||||
ZwClose(SendThread);
|
|
||||||
ZwClose(ReceiveThread);
|
|
||||||
|
|
||||||
DriverObject->DriverUnload = (PDRIVER_UNLOAD)TdiUnload;
|
DriverObject->DriverUnload = (PDRIVER_UNLOAD)TdiUnload;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
Loading…
Reference in a new issue