# include <resolv.h>
#endif
-#undef _WIN32_WINNT
-#define _WIN32_WINNT 0x500
#define WIN32_NO_STATUS
#include <winsock2.h>
#include <ws2tcpip.h>
#include "ddk/tdiinfo.h"
#include "tcpioctl.h"
+ #include "tdilib.h"
+
#ifndef ETH_ALEN
#define ETH_ALEN 6
#endif
} IPHLPAddrType;
/** Prototypes **/
- NTSTATUS openTcpFile(PHANDLE tcpFile);
- VOID closeTcpFile(HANDLE tcpFile);
- NTSTATUS tdiGetEntityIDSet( HANDLE tcpFile, TDIEntityID **entitySet,
- PDWORD numEntities );
- NTSTATUS tdiGetSetOfThings( HANDLE tcpFile, DWORD toiClass, DWORD toiType,
- DWORD toiId, DWORD teiEntity, DWORD teiInstance,
- DWORD fixedPart,
- DWORD entrySize, PVOID *tdiEntitySet,
- PDWORD numEntries );
- VOID tdiFreeThingSet( PVOID things );
NTSTATUS getNthIpEntity( HANDLE tcpFile, DWORD index, TDIEntityID *ent );
NTSTATUS tdiGetIpAddrsForIpEntity( HANDLE tcpFile, TDIEntityID *ent,
IPAddrEntry **addrs, PDWORD numAddrs );
-
int GetLongestChildKeyName( HANDLE RegHandle );
LONG OpenChildKeyRead( HANDLE RegHandle,
PWCHAR ChildKeyName,
NtUserCallOneParam((DWORD_PTR)bShow, ONEPARAM_ROUTINE_SHOWCURSOR)
#define NtUserGetDesktopMapping(Ptr) \
- (PVOID)NtUserCallOneParam((DWORD)Ptr, ONEPARAM_ROUTINE_GETDESKTOPMAPPING)
+ (PVOID)NtUserCallOneParam((DWORD_PTR)Ptr, ONEPARAM_ROUTINE_GETDESKTOPMAPPING)
#define NtUserSetCursorPos(x, y) \
(BOOL)NtUserCallTwoParam((DWORD)x, (DWORD)y, TWOPARAM_ROUTINE_SETCURSORPOS)
#define USER_BODY_TO_HEADER(ObjectBody) \
((PUSER_OBJECT_HEADER)(((PUSER_OBJECT_HEADER)ObjectBody) - 1))
+ #define HANDLEENTRY_INDESTROY 1
+
typedef struct _USER_HANDLE_ENTRY
{
void *ptr; /* pointer to object */
PTHREADINFO pti; // pointer to Win32ThreadInfo
PPROCESSINFO ppi; // pointer to W32ProcessInfo
};
- unsigned short type; /* object type (0 if free) */
+ unsigned char type; /* object type (0 if free) */
+ unsigned char flags;
unsigned short generation; /* generation counter */
} USER_HANDLE_ENTRY, * PUSER_HANDLE_ENTRY;
return TRUE;
else
return (NtUserQueryWindow(Wnd->head.h, QUERY_WINDOW_UNIQUE_PROCESS_ID) ==
- (DWORD)NtCurrentTeb()->ClientId.UniqueProcess );
+ (DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess );
}
BOOL
INT Index;
USHORT generation;
- Index = (((UINT)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
+ Index = (((UINT_PTR)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
if (Index < 0 || Index >= gHandleTable->nb_handles)
return NULL;
if (!gHandleEntries[Index].type || !gHandleEntries[Index].ptr)
return NULL;
- generation = (UINT)handle >> 16;
+ generation = (UINT_PTR)handle >> 16;
if (generation == gHandleEntries[Index].generation || !generation || generation == 0xffff)
return &gHandleEntries[Index];
static const BOOL g_ObjectHeapTypeShared[VALIDATE_TYPE_EVENT + 1] =
{
FALSE, /* VALIDATE_TYPE_FREE (not used) */
- TRUE, /* VALIDATE_TYPE_WIN */ /* FIXME: FALSE once WINDOW_OBJECT is deleted! */
- TRUE, /* VALIDATE_TYPE_MENU */
+ TRUE, /* VALIDATE_TYPE_WIN FALSE */
+ TRUE, /* VALIDATE_TYPE_MENU FALSE */
TRUE, /* VALIDATE_TYPE_CURSOR */
TRUE, /* VALIDATE_TYPE_MWPOS */
- TRUE, /* VALIDATE_TYPE_HOOK */
+ TRUE, /* VALIDATE_TYPE_HOOK FALSE */
FALSE, /* (not used) */
- TRUE, /* VALIDATE_TYPE_CALLPROC */
+ TRUE, /* VALIDATE_TYPE_CALLPROC FALSE */
TRUE, /* VALIDATE_TYPE_ACCEL */
FALSE, /* (not used) */
FALSE, /* (not used) */
uType = pEntry->type;
// Must have an entry and must be the same type!
- if ( (!pEntry) || (pEntry->type != uType) || !pEntry->ptr )
+ if ( (!pEntry) ||
+ (pEntry->type != uType) ||
+ !pEntry->ptr ||
+ (pEntry->flags & HANDLEENTRY_INDESTROY) )
{
switch ( uType )
{ // Test (with wine too) confirms these results!
return NULL;
}
+ // HACK HACK HACK!
+ typedef struct _WNDX
+ {
+ THRDESKHEAD head;
+ PWND pWnd;
+ } WNDX, *PWNDX;
+
//
// Validate a window handle and return the pointer to the object.
//
Wnd = ValidateHandle((HANDLE)hwnd, VALIDATE_TYPE_WIN);
if (Wnd != NULL)
{
- /* FIXME: Check if handle table entry is marked as deleting and
- return NULL in this case! */
-
#if 0
return Wnd;
#else
!!! REMOVE AS SOON AS WINDOW_OBJECT NO LONGER EXISTS !!!
*/
- if (*((PVOID*)Wnd) != NULL)
- return DesktopPtrToUser(*((PVOID*)Wnd));
+ if ( ((PWNDX)Wnd)->pWnd != NULL)
+ return DesktopPtrToUser( ((PWNDX)Wnd)->pWnd );
#endif
}
Wnd = ValidateHandleNoErr((HANDLE)hwnd, VALIDATE_TYPE_WIN);
if (Wnd != NULL)
{
- /* FIXME: Check if handle table entry is marked as deleting and
- return NULL in this case! */
-
#if 0
return Wnd;
#else
!!! REMOVE AS SOON AS WINDOW_OBJECT NO LONGER EXISTS !!!
*/
- if (*((PVOID*)Wnd) != NULL)
- return DesktopPtrToUser(*((PVOID*)Wnd));
+ if ( ((PWNDX)Wnd)->pWnd != NULL)
+ return DesktopPtrToUser( ((PWNDX)Wnd)->pWnd );
#endif
}
MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
if( !IrpSp->Parameters.DeviceIoControl.Type3InputBuffer ) {
+ MmUnlockPages( Irp->MdlAddress );
IoFreeMdl( Irp->MdlAddress );
Irp->MdlAddress = NULL;
return NULL;
} else return NULL;
}
- VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp ) {
- PVOID Buffer = MmGetSystemAddressForMdlSafe( Irp->MdlAddress, NormalPagePriority );
- if( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer == Buffer || Buffer == NULL ) {
- MmUnmapLockedPages( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer, Irp->MdlAddress );
- MmUnlockPages( Irp->MdlAddress );
- IoFreeMdl( Irp->MdlAddress );
- }
-
+ VOID UnlockRequest( PIRP Irp, PIO_STACK_LOCATION IrpSp )
+ {
+ MmUnlockPages( Irp->MdlAddress );
+ IoFreeMdl( Irp->MdlAddress );
Irp->MdlAddress = NULL;
}
if( !HandleArray[i].Handle ) continue;
if( NT_SUCCESS(Status) ) {
Status = ObReferenceObjectByHandle
- ( (PVOID)HandleArray[i].Handle,
+ ( (PVOID)(ULONG_PTR)HandleArray[i].Handle,
FILE_ALL_ACCESS,
NULL,
KernelMode,
for( i = 0; i < HandleCount; i++ ) {
if( HandleArray[i].Handle )
- ObDereferenceObject( (PVOID)HandleArray[i].Handle );
+ ObDereferenceObject( (PVOID)(ULONG_PTR)HandleArray[i].Handle );
}
ExFreePool( HandleArray );
HandleArray = NULL;
}
- /* Returns transitioned state or SOCKET_STATE_INVALID_TRANSITION */
- UINT SocketAcquireStateLock( PAFD_FCB FCB ) {
- NTSTATUS Status = STATUS_SUCCESS;
- PVOID CurrentThread = KeGetCurrentThread();
-
- ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
-
- AFD_DbgPrint(MAX_TRACE,("Called on %x, attempting to lock\n", FCB));
-
- /* Wait for the previous user to unlock the FCB state. There might be
- * multiple waiters waiting to change the state. We need to check each
- * time we get the event whether somebody still has the state locked */
-
+ BOOLEAN SocketAcquireStateLock( PAFD_FCB FCB ) {
if( !FCB ) return FALSE;
- if( CurrentThread == FCB->CurrentThread ) {
- FCB->LockCount++;
- AFD_DbgPrint(MID_TRACE,
- ("Same thread, lock count %d\n", FCB->LockCount));
- return TRUE;
- } else {
- AFD_DbgPrint(MID_TRACE,
- ("Thread %x opposes lock thread %x\n",
- CurrentThread, FCB->CurrentThread));
- }
-
-
- ExAcquireFastMutex( &FCB->Mutex );
-
- while( FCB->Locked ) {
- AFD_DbgPrint
- (MID_TRACE,("FCB %x is locked, waiting for notification\n",
- FCB));
- ExReleaseFastMutex( &FCB->Mutex );
- Status = KeWaitForSingleObject( &FCB->StateLockedEvent,
- UserRequest,
- KernelMode,
- FALSE,
- NULL );
- ExAcquireFastMutex( &FCB->Mutex );
- }
- FCB->Locked = TRUE;
- FCB->CurrentThread = CurrentThread;
- FCB->LockCount++;
- ExReleaseFastMutex( &FCB->Mutex );
-
- AFD_DbgPrint(MAX_TRACE,("Got lock (%d).\n", FCB->LockCount));
-
- return TRUE;
+ return !KeWaitForMutexObject(&FCB->Mutex,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
}
VOID SocketStateUnlock( PAFD_FCB FCB ) {
- #if DBG
- PVOID CurrentThread = KeGetCurrentThread();
- #endif
- ASSERT(FCB->LockCount > 0);
- ASSERT(KeGetCurrentIrql() <= APC_LEVEL);
-
- ExAcquireFastMutex( &FCB->Mutex );
- FCB->LockCount--;
-
- if( !FCB->LockCount ) {
- FCB->CurrentThread = NULL;
- FCB->Locked = FALSE;
-
- AFD_DbgPrint(MAX_TRACE,("Unlocked.\n"));
- KePulseEvent( &FCB->StateLockedEvent, IO_NETWORK_INCREMENT, FALSE );
- } else {
- AFD_DbgPrint(MAX_TRACE,("New lock count: %d (Thr: %x)\n",
- FCB->LockCount, CurrentThread));
- }
- ExReleaseFastMutex( &FCB->Mutex );
+ KeReleaseMutex(&FCB->Mutex, FALSE);
}
NTSTATUS NTAPI UnlockAndMaybeComplete
for( i = 0; i < Len; i++ ) {
if( i && !(i & 0xf) ) DbgPrint( "\n" );
- if( !(i & 0xf) ) DbgPrint( "%08x: ", (UINT)(Data + i) );
+ if( !(i & 0xf) ) DbgPrint( "%08x: ", (UINT_PTR)(Data + i) );
DbgPrint( " %02x", Data[i] & 0xff );
}
DbgPrint("\n");
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
+ NTSTATUS NTAPI
+ AfdGetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+ {
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+ if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+ if (FCB->DisconnectOptionsSize == 0)
+ return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
+
+ ASSERT(FCB->DisconnectOptions);
+
+ if (FCB->FilledDisconnectOptions < BufferSize) BufferSize = FCB->FilledDisconnectOptions;
+
+ RtlCopyMemory(Irp->UserBuffer,
+ FCB->DisconnectOptions,
+ BufferSize);
+
+ return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize);
+ }
+
+ NTSTATUS
+ NTAPI
+ AfdSetDisconnectOptions(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+ {
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ PVOID DisconnectOptions = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ UINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+ if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+ if (FCB->DisconnectOptions)
+ {
+ ExFreePool(FCB->DisconnectOptions);
+ FCB->DisconnectOptions = NULL;
+ FCB->DisconnectOptionsSize = 0;
+ FCB->FilledDisconnectOptions = 0;
+ }
+
+ FCB->DisconnectOptions = ExAllocatePool(PagedPool, DisconnectOptionsSize);
+ if (!FCB->DisconnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+ RtlCopyMemory(FCB->DisconnectOptions,
+ DisconnectOptions,
+ DisconnectOptionsSize);
+
+ FCB->DisconnectOptionsSize = DisconnectOptionsSize;
+
+ return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+ }
+
+ NTSTATUS
+ NTAPI
+ AfdSetDisconnectOptionsSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+ {
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ PUINT DisconnectOptionsSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+ if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+ if (BufferSize < sizeof(UINT))
+ return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
+
+ if (FCB->DisconnectOptions)
+ {
+ ExFreePool(FCB->DisconnectOptions);
+ FCB->DisconnectOptionsSize = 0;
+ FCB->FilledDisconnectOptions = 0;
+ }
+
+ FCB->DisconnectOptions = ExAllocatePool(PagedPool, *DisconnectOptionsSize);
+ if (!FCB->DisconnectOptions) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+ FCB->DisconnectOptionsSize = *DisconnectOptionsSize;
+
+ return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+ }
+
+ NTSTATUS NTAPI
+ AfdGetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+ {
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ UINT BufferSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+
+ if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+ if (FCB->DisconnectDataSize == 0)
+ return UnlockAndMaybeComplete(FCB, STATUS_INVALID_PARAMETER, Irp, 0);
+
+ ASSERT(FCB->DisconnectData);
+
+ if (FCB->FilledDisconnectData < BufferSize) BufferSize = FCB->FilledDisconnectData;
+
+ RtlCopyMemory(Irp->UserBuffer,
+ FCB->DisconnectData,
+ BufferSize);
+
+ return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, BufferSize);
+ }
+
+ NTSTATUS
+ NTAPI
+ AfdSetDisconnectData(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+ {
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ PVOID DisconnectData = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ UINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+ if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+ if (FCB->DisconnectData)
+ {
+ ExFreePool(FCB->DisconnectData);
+ FCB->DisconnectData = NULL;
+ FCB->DisconnectDataSize = 0;
+ FCB->FilledDisconnectData = 0;
+ }
+
+ FCB->DisconnectData = ExAllocatePool(PagedPool, DisconnectDataSize);
+ if (!FCB->DisconnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+ RtlCopyMemory(FCB->DisconnectData,
+ DisconnectData,
+ DisconnectDataSize);
+
+ FCB->DisconnectDataSize = DisconnectDataSize;
+
+ return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+ }
+
+ NTSTATUS
+ NTAPI
+ AfdSetDisconnectDataSize(PDEVICE_OBJECT DeviceObject, PIRP Irp,
+ PIO_STACK_LOCATION IrpSp)
+ {
+ PFILE_OBJECT FileObject = IrpSp->FileObject;
+ PAFD_FCB FCB = FileObject->FsContext;
+ PUINT DisconnectDataSize = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ UINT BufferSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+
+ if (!SocketAcquireStateLock(FCB)) return LostSocket(Irp);
+
+ if (BufferSize < sizeof(UINT))
+ return UnlockAndMaybeComplete(FCB, STATUS_BUFFER_TOO_SMALL, Irp, 0);
+
+ if (FCB->DisconnectData)
+ {
+ ExFreePool(FCB->DisconnectData);
+ FCB->DisconnectDataSize = 0;
+ FCB->FilledDisconnectData = 0;
+ }
+
+ FCB->DisconnectData = ExAllocatePool(PagedPool, *DisconnectDataSize);
+ if (!FCB->DisconnectData) return UnlockAndMaybeComplete(FCB, STATUS_NO_MEMORY, Irp, 0);
+
+ FCB->DisconnectDataSize = *DisconnectDataSize;
+
+ return UnlockAndMaybeComplete(FCB, STATUS_SUCCESS, Irp, 0);
+ }
+
static NTSTATUS NTAPI
AfdCreateSocket(PDEVICE_OBJECT DeviceObject, PIRP Irp,
PIO_STACK_LOCATION IrpSp) {
FCB->State = SOCKET_STATE_CREATED;
FCB->FileObject = FileObject;
FCB->DeviceExt = DeviceExt;
- FCB->Recv.Size = DEFAULT_RECEIVE_WINDOW_SIZE;
- FCB->Send.Size = DEFAULT_SEND_WINDOW_SIZE;
FCB->AddressFile.Handle = INVALID_HANDLE_VALUE;
FCB->Connection.Handle = INVALID_HANDLE_VALUE;
- KeInitializeSpinLock( &FCB->SpinLock );
- ExInitializeFastMutex( &FCB->Mutex );
- KeInitializeEvent( &FCB->StateLockedEvent, NotificationEvent, FALSE );
+ KeInitializeMutex( &FCB->Mutex, 0 );
for( i = 0; i < MAX_FUNCTIONS; i++ ) {
InitializeListHead( &FCB->PendingIrpList[i] );
FileObject->FsContext = FCB;
/* It seems that UDP sockets are writable from inception */
- if( FCB->Flags & SGID_CONNECTIONLESS ) {
+ if( FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS ) {
AFD_DbgPrint(MID_TRACE,("Packet oriented socket\n"));
- /* Allocate our backup buffer */
- FCB->Recv.Window = ExAllocatePool( NonPagedPool, FCB->Recv.Size );
- if( !FCB->Recv.Window ) Status = STATUS_NO_MEMORY;
- if( NT_SUCCESS(Status) )
- {
- FCB->Send.Window = ExAllocatePool( NonPagedPool, FCB->Send.Size );
- if( !FCB->Send.Window ) {
- if( FCB->Recv.Window ) ExFreePool( FCB->Recv.Window );
- Status = STATUS_NO_MEMORY;
- }
- }
+
/* A datagram socket is always sendable */
FCB->PollState |= AFD_EVENT_SEND;
PollReeval( FCB->DeviceExt, FCB->FileObject );
if( FCB->AddressFrom )
ExFreePool( FCB->AddressFrom );
+ if( FCB->ConnectInfo )
+ ExFreePool( FCB->ConnectInfo );
+
+ if( FCB->ConnectData )
+ ExFreePool( FCB->ConnectData );
+
+ if( FCB->DisconnectData )
+ ExFreePool( FCB->DisconnectData );
+
+ if( FCB->ConnectOptions )
+ ExFreePool( FCB->ConnectOptions );
+
+ if( FCB->DisconnectOptions )
+ ExFreePool( FCB->DisconnectOptions );
+
if( FCB->LocalAddress )
ExFreePool( FCB->LocalAddress );
PAFD_FCB FCB = FileObject->FsContext;
PAFD_DISCONNECT_INFO DisReq;
IO_STATUS_BLOCK Iosb;
- PTDI_CONNECTION_INFORMATION ConnInfo;
- NTSTATUS Status;
+ PTDI_CONNECTION_INFORMATION ConnectionReturnInfo;
+ NTSTATUS Status = STATUS_SUCCESS;
USHORT Flags = 0;
if( !SocketAcquireStateLock( FCB ) ) return LostSocket( Irp );
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
Irp, 0 );
- if (NULL == FCB->RemoteAddress)
- {
- ConnInfo = NULL;
- }
- else
- {
- Status = TdiBuildNullConnectionInfo
- ( &ConnInfo, FCB->RemoteAddress->Address[0].AddressType );
+ if (!(FCB->Flags & AFD_ENDPOINT_CONNECTIONLESS))
+ {
+ if( !FCB->ConnectInfo )
+ return UnlockAndMaybeComplete( FCB, STATUS_INVALID_PARAMETER,
+ Irp, 0 );
+
+ ASSERT(FCB->RemoteAddress);
- if( !NT_SUCCESS(Status) || !ConnInfo )
+ Status = TdiBuildNullConnectionInfo
+ ( &ConnectionReturnInfo, FCB->RemoteAddress->Address[0].AddressType );
+
+ if( !NT_SUCCESS(Status) )
return UnlockAndMaybeComplete( FCB, STATUS_NO_MEMORY,
- Irp, 0 );
- }
-
- if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
- Flags |= TDI_DISCONNECT_RELEASE;
- if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
- DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
- Flags |= TDI_DISCONNECT_ABORT;
-
- Status = TdiDisconnect( FCB->Connection.Object,
- &DisReq->Timeout,
- Flags,
- &Iosb,
- NULL,
- NULL,
- FCB->AddressFrom,
- ConnInfo);
-
- if (ConnInfo) ExFreePool( ConnInfo );
-
- FCB->PollState |= AFD_EVENT_DISCONNECT;
- PollReeval( FCB->DeviceExt, FCB->FileObject );
+ Irp, 0 );
+
+ if( DisReq->DisconnectType & AFD_DISCONNECT_SEND )
+ Flags |= TDI_DISCONNECT_RELEASE;
+ if( DisReq->DisconnectType & AFD_DISCONNECT_RECV ||
+ DisReq->DisconnectType & AFD_DISCONNECT_ABORT )
+ Flags |= TDI_DISCONNECT_ABORT;
+
+ FCB->ConnectInfo->UserData = FCB->DisconnectData;
+ FCB->ConnectInfo->UserDataLength = FCB->DisconnectDataSize;
+ FCB->ConnectInfo->Options = FCB->DisconnectOptions;
+ FCB->ConnectInfo->OptionsLength = FCB->DisconnectOptionsSize;
+
+ Status = TdiDisconnect( FCB->Connection.Object,
+ &DisReq->Timeout,
+ Flags,
+ &Iosb,
+ NULL,
+ NULL,
+ FCB->ConnectInfo,
+ ConnectionReturnInfo);
+
+ if (NT_SUCCESS(Status)) {
+ FCB->FilledDisconnectData = MIN(FCB->DisconnectDataSize, ConnectionReturnInfo->UserDataLength);
+ if (FCB->FilledDisconnectData)
+ {
+ RtlCopyMemory(FCB->DisconnectData,
+ ConnectionReturnInfo->UserData,
+ FCB->FilledDisconnectData);
+ }
+
+ FCB->FilledDisconnectOptions = MIN(FCB->DisconnectOptionsSize, ConnectionReturnInfo->OptionsLength);
+ if (FCB->FilledDisconnectOptions)
+ {
+ RtlCopyMemory(FCB->DisconnectOptions,
+ ConnectionReturnInfo->Options,
+ FCB->FilledDisconnectOptions);
+ }
+ }
+
+ ExFreePool( ConnectionReturnInfo );
+
+ FCB->PollState |= AFD_EVENT_DISCONNECT;
+ PollReeval( FCB->DeviceExt, FCB->FileObject );
+ } else
+ Status = STATUS_INVALID_PARAMETER;
return UnlockAndMaybeComplete( FCB, Status, Irp, 0 );
}
case IOCTL_AFD_GET_PEER_NAME:
return AfdGetPeerName( DeviceObject, Irp, IrpSp );
- case IOCTL_AFD_GET_TDI_HANDLES:
- DbgPrint("IOCTL_AFD_GET_TDI_HANDLES is UNIMPLEMENTED!\n");
- break;
+ case IOCTL_AFD_GET_CONNECT_DATA:
+ return AfdGetConnectData(DeviceObject, Irp, IrpSp);
case IOCTL_AFD_SET_CONNECT_DATA:
- DbgPrint("IOCTL_AFD_SET_CONNECT_DATA is UNIMPLEMENTED!\n");
- break;
-
- case IOCTL_AFD_SET_CONNECT_OPTIONS:
- DbgPrint("IOCTL_AFD_SET_CONNECT_OPTIONS is UNIMPLEMENTED!\n");
- break;
+ return AfdSetConnectData(DeviceObject, Irp, IrpSp);
case IOCTL_AFD_SET_DISCONNECT_DATA:
- DbgPrint("IOCTL_AFD_SET_DISCONNECT_DATA is UNIMPLEMENTED!\n");
- break;
+ return AfdSetDisconnectData(DeviceObject, Irp, IrpSp);
- case IOCTL_AFD_SET_DISCONNECT_OPTIONS:
- DbgPrint("IOCTL_AFD_SET_DISCONNECT_OPTIONS is UNIMPLEMENTED!\n");
- break;
+ case IOCTL_AFD_GET_DISCONNECT_DATA:
+ return AfdGetDisconnectData(DeviceObject, Irp, IrpSp);
- case IOCTL_AFD_GET_CONNECT_DATA:
- DbgPrint("IOCTL_AFD_GET_CONNECT_DATA is UNIMPLEMENTED!\n");
- break;
+ case IOCTL_AFD_SET_CONNECT_DATA_SIZE:
+ return AfdSetConnectDataSize(DeviceObject, Irp, IrpSp);
- case IOCTL_AFD_GET_CONNECT_OPTIONS:
- DbgPrint("IOCTL_AFD_GET_CONNECT_OPTIONS is UNIMPLEMENTED!\n");
- break;
+ case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE:
+ return AfdSetDisconnectDataSize(DeviceObject, Irp, IrpSp);
- case IOCTL_AFD_GET_DISCONNECT_DATA:
- DbgPrint("IOCTL_AFD_GET_DISCONNECT_DATA is UNIMPLEMENTED!\n");
- break;
+ case IOCTL_AFD_SET_CONNECT_OPTIONS:
+ return AfdSetConnectOptions(DeviceObject, Irp, IrpSp);
- case IOCTL_AFD_GET_DISCONNECT_OPTIONS:
- DbgPrint("IOCTL_AFD_GET_DISCONNECT_OPTIONS is UNIMPLEMENTED!\n");
- break;
+ case IOCTL_AFD_SET_DISCONNECT_OPTIONS:
+ return AfdSetDisconnectOptions(DeviceObject, Irp, IrpSp);
- case IOCTL_AFD_SET_CONNECT_DATA_SIZE:
- DbgPrint("IOCTL_AFD_SET_CONNECT_DATA_SIZE is UNIMPLEMENTED!\n");
- break;
+ case IOCTL_AFD_GET_CONNECT_OPTIONS:
+ return AfdGetConnectOptions(DeviceObject, Irp, IrpSp);
- case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE:
- DbgPrint("IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE is UNIMPLEMENTED!\n");
- break;
+ case IOCTL_AFD_GET_DISCONNECT_OPTIONS:
+ return AfdGetDisconnectOptions(DeviceObject, Irp, IrpSp);
- case IOCTL_AFD_SET_DISCONNECT_DATA_SIZE:
- DbgPrint("IOCTL_AFD_SET_DISCONNECT_DATA_SIZE is UNIMPLEMENTED!\n");
- break;
+ case IOCTL_AFD_SET_CONNECT_OPTIONS_SIZE:
+ return AfdSetConnectOptionsSize(DeviceObject, Irp, IrpSp);
case IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE:
- DbgPrint("IOCTL_AFD_SET_DISCONNECT_OPTIONS_SIZE is UNIMPLEMENTED!\n");
+ return AfdSetDisconnectOptionsSize(DeviceObject, Irp, IrpSp);
+
+ case IOCTL_AFD_GET_TDI_HANDLES:
+ DbgPrint("IOCTL_AFD_GET_TDI_HANDLES is UNIMPLEMENTED!\n");
break;
case IOCTL_AFD_DEFER_ACCEPT:
RtlZeroMemory(Descriptor, sizeof(RECEIVE_DESCRIPTOR));
Descriptor->RBADR =
- (ULONG)(Adapter->ReceiveBufferPtrPhys + Adapter->CurrentReceiveDescriptorIndex * BUFFER_SIZE);
+ (ULONG_PTR)(Adapter->ReceiveBufferPtrPhys + Adapter->CurrentReceiveDescriptorIndex * BUFFER_SIZE);
Descriptor->BCNT = (-BUFFER_SIZE) | 0xf000;
Descriptor->FLAGS |= RD_OWN;
return NDIS_STATUS_RESOURCES;
}
- if(((ULONG)Adapter->InitializationBlockVirt & 0x00000003) != 0)
+ if(((ULONG_PTR)Adapter->InitializationBlockVirt & 0x00000003) != 0)
{
DPRINT("address 0x%x not dword-aligned\n", Adapter->InitializationBlockVirt);
BREAKPOINT;
return NDIS_STATUS_RESOURCES;
}
- Adapter->InitializationBlockPhys = (PINITIALIZATION_BLOCK)NdisGetPhysicalAddressLow(PhysicalAddress);
+ Adapter->InitializationBlockPhys = (PINITIALIZATION_BLOCK)(ptrdiff_t)NdisGetPhysicalAddressLow(PhysicalAddress);
/* allocate the transport descriptor ring */
Adapter->TransmitDescriptorRingLength = sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS;
return NDIS_STATUS_RESOURCES;
}
- if(((ULONG)Adapter->TransmitDescriptorRingVirt & 0x00000003) != 0)
+ if(((ULONG_PTR)Adapter->TransmitDescriptorRingVirt & 0x00000003) != 0)
{
DPRINT("address 0x%x not dword-aligned\n", Adapter->TransmitDescriptorRingVirt);
BREAKPOINT;
return NDIS_STATUS_RESOURCES;
}
- Adapter->TransmitDescriptorRingPhys = (PTRANSMIT_DESCRIPTOR)NdisGetPhysicalAddressLow(PhysicalAddress);
+ Adapter->TransmitDescriptorRingPhys = (PTRANSMIT_DESCRIPTOR)(ptrdiff_t)NdisGetPhysicalAddressLow(PhysicalAddress);
RtlZeroMemory(Adapter->TransmitDescriptorRingVirt, sizeof(TRANSMIT_DESCRIPTOR) * NUMBER_OF_BUFFERS);
/* allocate the receive descriptor ring */
return NDIS_STATUS_RESOURCES;
}
- if(((ULONG)Adapter->ReceiveDescriptorRingVirt & 0x00000003) != 0)
+ if(((ULONG_PTR)Adapter->ReceiveDescriptorRingVirt & 0x00000003) != 0)
{
DPRINT("address 0x%x not dword-aligned\n", Adapter->ReceiveDescriptorRingVirt);
BREAKPOINT;
return NDIS_STATUS_RESOURCES;
}
- Adapter->ReceiveDescriptorRingPhys = (PRECEIVE_DESCRIPTOR)NdisGetPhysicalAddressLow(PhysicalAddress);
+ Adapter->ReceiveDescriptorRingPhys = (PRECEIVE_DESCRIPTOR)(ptrdiff_t)NdisGetPhysicalAddressLow(PhysicalAddress);
RtlZeroMemory(Adapter->ReceiveDescriptorRingVirt, sizeof(RECEIVE_DESCRIPTOR) * NUMBER_OF_BUFFERS);
/* allocate transmit buffers */
return NDIS_STATUS_RESOURCES;
}
- if(((ULONG)Adapter->TransmitBufferPtrVirt & 0x00000003) != 0)
+ if(((ULONG_PTR)Adapter->TransmitBufferPtrVirt & 0x00000003) != 0)
{
DPRINT("address 0x%x not dword-aligned\n", Adapter->TransmitBufferPtrVirt);
BREAKPOINT;
return NDIS_STATUS_RESOURCES;
}
- Adapter->TransmitBufferPtrPhys = (PCHAR)NdisGetPhysicalAddressLow(PhysicalAddress);
+ Adapter->TransmitBufferPtrPhys = (PCHAR)(ULONG_PTR)NdisGetPhysicalAddressLow(PhysicalAddress);
RtlZeroMemory(Adapter->TransmitBufferPtrVirt, BUFFER_SIZE * NUMBER_OF_BUFFERS);
/* allocate receive buffers */
return NDIS_STATUS_RESOURCES;
}
- if(((ULONG)Adapter->ReceiveBufferPtrVirt & 0x00000003) != 0)
+ if(((ULONG_PTR)Adapter->ReceiveBufferPtrVirt & 0x00000003) != 0)
{
DPRINT("address 0x%x not dword-aligned\n", Adapter->ReceiveBufferPtrVirt);
BREAKPOINT;
return NDIS_STATUS_RESOURCES;
}
- Adapter->ReceiveBufferPtrPhys = (PCHAR)NdisGetPhysicalAddressLow(PhysicalAddress);
+ Adapter->ReceiveBufferPtrPhys = (PCHAR)(ULONG_PTR)NdisGetPhysicalAddressLow(PhysicalAddress);
RtlZeroMemory(Adapter->ReceiveBufferPtrVirt, BUFFER_SIZE * NUMBER_OF_BUFFERS);
/* initialize tx descriptors */
TransmitDescriptor = Adapter->TransmitDescriptorRingVirt;
for(i = 0; i < NUMBER_OF_BUFFERS; i++)
{
- (TransmitDescriptor+i)->TBADR = (ULONG)Adapter->TransmitBufferPtrPhys + i * BUFFER_SIZE;
+ (TransmitDescriptor+i)->TBADR = (ULONG_PTR)Adapter->TransmitBufferPtrPhys + i * BUFFER_SIZE;
(TransmitDescriptor+i)->BCNT = 0xf000 | -BUFFER_SIZE; /* 2's compliment + set top 4 bits */
(TransmitDescriptor+i)->FLAGS = TD1_STP | TD1_ENP;
}
ReceiveDescriptor = Adapter->ReceiveDescriptorRingVirt;
for(i = 0; i < NUMBER_OF_BUFFERS; i++)
{
- (ReceiveDescriptor+i)->RBADR = (ULONG)Adapter->ReceiveBufferPtrPhys + i * BUFFER_SIZE;
+ (ReceiveDescriptor+i)->RBADR = (ULONG_PTR)Adapter->ReceiveBufferPtrPhys + i * BUFFER_SIZE;
(ReceiveDescriptor+i)->BCNT = 0xf000 | -BUFFER_SIZE; /* 2's compliment + set top 4 bits */
(ReceiveDescriptor+i)->FLAGS = RD_OWN;
}
/* set up receive ring */
DPRINT("Receive ring physical address: 0x%x\n", Adapter->ReceiveDescriptorRingPhys);
- Adapter->InitializationBlockVirt->RDRA = (ULONG)Adapter->ReceiveDescriptorRingPhys;
+ Adapter->InitializationBlockVirt->RDRA = (ULONG_PTR)Adapter->ReceiveDescriptorRingPhys;
Adapter->InitializationBlockVirt->RLEN = (LOG_NUMBER_OF_BUFFERS << 4) & 0xf0;
/* set up transmit ring */
DPRINT("Transmit ring physical address: 0x%x\n", Adapter->TransmitDescriptorRingPhys);
- Adapter->InitializationBlockVirt->TDRA = (ULONG)Adapter->TransmitDescriptorRingPhys;
+ Adapter->InitializationBlockVirt->TDRA = (ULONG_PTR)Adapter->TransmitDescriptorRingPhys;
Adapter->InitializationBlockVirt->TLEN = (LOG_NUMBER_OF_BUFFERS << 4) & 0xf0;
}
if(Adapter->InitializationBlockVirt)
{
- PhysicalAddress.u.LowPart = (ULONG)Adapter->InitializationBlockPhys;
+ PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->InitializationBlockPhys;
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->InitializationBlockLength,
FALSE, Adapter->InitializationBlockVirt, PhysicalAddress);
}
if(Adapter->TransmitDescriptorRingVirt)
{
- PhysicalAddress.u.LowPart = (ULONG)Adapter->TransmitDescriptorRingPhys;
+ PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->TransmitDescriptorRingPhys;
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitDescriptorRingLength,
FALSE, Adapter->TransmitDescriptorRingVirt, PhysicalAddress);
}
if(Adapter->ReceiveDescriptorRingVirt)
{
- PhysicalAddress.u.LowPart = (ULONG)Adapter->ReceiveDescriptorRingPhys;
+ PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->ReceiveDescriptorRingPhys;
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveDescriptorRingLength,
FALSE, Adapter->ReceiveDescriptorRingVirt, PhysicalAddress);
}
if(Adapter->TransmitBufferPtrVirt)
{
- PhysicalAddress.u.LowPart = (ULONG)Adapter->TransmitBufferPtrPhys;
+ PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->TransmitBufferPtrPhys;
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->TransmitBufferLength,
FALSE, Adapter->TransmitBufferPtrVirt, PhysicalAddress);
}
if(Adapter->ReceiveBufferPtrVirt)
{
- PhysicalAddress.u.LowPart = (ULONG)Adapter->ReceiveBufferPtrPhys;
+ PhysicalAddress.u.LowPart = (ULONG_PTR)Adapter->ReceiveBufferPtrPhys;
NdisMFreeSharedMemory(Adapter->MiniportAdapterHandle, Adapter->ReceiveBufferLength,
FALSE, Adapter->ReceiveBufferPtrVirt, PhysicalAddress);
}
/* set up csr1 and csr2 with init block */
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR1);
- NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG)Adapter->InitializationBlockPhys & 0xffff));
+ NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG_PTR)Adapter->InitializationBlockPhys & 0xffff));
NdisRawWritePortUshort(Adapter->PortOffset + RAP, CSR2);
- NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG)Adapter->InitializationBlockPhys >> 16) & 0xffff);
+ NdisRawWritePortUshort(Adapter->PortOffset + RDP, (USHORT)((ULONG_PTR)Adapter->InitializationBlockPhys >> 16) & 0xffff);
DPRINT("programmed with init block\n");
{
DPRINT("Called\n");
- ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
-
/* MiniportReset doesn't do anything at the moment... perhaps this should be fixed. */
*AddressingReset = FALSE;
* Adapter = Pointer to LAN_ADAPTER structure to free
*/
{
- exFreePool(Adapter);
+ ExFreePoolWithTag(Adapter, LAN_ADAPTER_TAG);
}
Adapter = WorkItem->Adapter;
BytesTransferred = WorkItem->BytesTransferred;
- exFreePool(WorkItem);
+ ExFreePoolWithTag(WorkItem, WQ_CONTEXT_TAG);
IPInitializePacket(&IPPacket, 0);
PNDIS_PACKET Packet,
NDIS_STATUS Status,
UINT BytesTransferred) {
- PLAN_WQ_ITEM WQItem = exAllocatePool(NonPagedPool, sizeof(LAN_WQ_ITEM));
+ PLAN_WQ_ITEM WQItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_WQ_ITEM),
+ WQ_CONTEXT_TAG);
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
TI_DbgPrint(DEBUG_DATALINK,("called\n"));
WQItem->BytesTransferred = BytesTransferred;
if (!ChewCreate( LanReceiveWorker, WQItem ))
- exFreePool(WQItem);
+ ExFreePoolWithTag(WQItem, WQ_CONTEXT_TAG);
}
VOID NTAPI ProtocolTransferDataComplete(
if (Adapter->MTU < Size) {
/* This is NOT a pointer. MSDN explicitly says so. */
NDIS_PER_PACKET_INFO_FROM_PACKET(NdisPacket,
- TcpLargeSendPacketInfo) = (PVOID)((ULONG)Adapter->MTU);
+ TcpLargeSendPacketInfo) = (PVOID)((ULONG_PTR)Adapter->MTU);
}
TcpipAcquireSpinLock( &Adapter->Lock, &OldIrql );
BOOLEAN Deallocate) {
NTSTATUS Status;
UNICODE_STRING Ustr = *ResultFirst;
- PWSTR new_string = ExAllocatePoolWithTag
+ PWSTR new_string = ExAllocatePool
(PagedPool,
- (ResultFirst->Length + Second->Length + sizeof(WCHAR)), TAG_STRING);
+ (ResultFirst->Length + Second->Length + sizeof(WCHAR)));
if( !new_string ) {
return STATUS_NO_MEMORY;
}
GetName( RegistryPath, &IF->Name );
Status = FindDeviceDescForAdapter( &IF->Name, &IF->Description );
+ if (!NT_SUCCESS(Status)) {
+ TI_DbgPrint(MIN_TRACE, ("Failed to get device description.\n"));
+ IPDestroyInterface(IF);
+ return FALSE;
+ }
TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n",
&IF->Description));
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
- IF = exAllocatePool(NonPagedPool, sizeof(LAN_ADAPTER));
+ IF = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_ADAPTER), LAN_ADAPTER_TAG);
if (!IF) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NDIS_STATUS_RESOURCES;
KeWaitForSingleObject(&IF->Event, UserRequest, KernelMode, FALSE, NULL);
else if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ\n", AdapterName));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NdisStatus;
}
default:
/* Unsupported media */
TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n"));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NDIS_STATUS_NOT_SUPPORTED;
}
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (NDISCall)\n", AdapterName));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NdisStatus;
}
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Query for maximum packet size failed.\n"));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NdisStatus;
}
IF->HWAddressLength);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Query for current hardware address failed.\n"));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NdisStatus;
}
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Query for maximum link speed failed.\n"));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NdisStatus;
}
/* Bind adapter to IP layer */
if( !BindAdapter(IF, RegistryPath) ) {
TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (BindAdapter)\n", AdapterName));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NDIS_STATUS_NOT_ACCEPTED;
}
<library>chew</library>
<library>ntoskrnl</library>
<library>hal</library>
- <!-- See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38269
<directory name="include">
<pch>precomp.h</pch>
</directory>
- -->
<directory name="datalink">
<file>lan.c</file>
</directory>
- <directory name="recmutex">
- <file>recmutex.c</file>
- </directory>
<directory name="tcpip">
<file>ainfo.c</file>
<file>buffer.c</file>
<file>fileobjs.c</file>
<file>iinfo.c</file>
<file>info.c</file>
- <file>irp.c</file>
<file>lock.c</file>
<file>main.c</file>
<file>ninfo.c</file>
<file>wait.c</file>
</directory>
<file>tcpip.rc</file>
- <!-- See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 -->
- <compilerflag compilerset="gcc">-fno-unit-at-a-time</compilerflag>
</module>
#include "precomp.h"
#include <pseh/pseh2.h>
+
+ NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) {
+ KIRQL OldIrql;
+
+ Irp->IoStatus.Status = Status;
+
+ if( Status == STATUS_PENDING )
+ IoMarkIrpPending( Irp );
+ else {
+ IoAcquireCancelSpinLock(&OldIrql);
+ (void)IoSetCancelRoutine( Irp, NULL );
+ IoReleaseCancelSpinLock(OldIrql);
+
+ IoCompleteRequest( Irp, IO_NETWORK_INCREMENT );
+ }
+
+ return Status;
+ }
+
NTSTATUS DispPrepareIrpForCancel(
PTRANSPORT_CONTEXT Context,
PIRP Irp,
* Count = Number of bytes sent or received
*/
{
- PIRP Irp;
- PIO_STACK_LOCATION IrpSp;
- PTRANSPORT_CONTEXT TranContext;
- KIRQL OldIrql;
+ PIRP Irp = Context;
TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n",
- Context, Status, Count));
-
- Irp = Context;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
- TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
-
- IoAcquireCancelSpinLock(&OldIrql);
-
- (void)IoSetCancelRoutine(Irp, NULL);
-
- IoReleaseCancelSpinLock(OldIrql);
+ Irp, Status, Count));
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Count;
TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n"));
}
- VOID DispDoDisconnect( PVOID Data ) {
- PDISCONNECT_TYPE DisType = (PDISCONNECT_TYPE)Data;
-
- TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect\n"));
- TcpipRecursiveMutexEnter(&TCPLock, TRUE);
- TCPDisconnect
- ( DisType->Context,
- DisType->Type,
- NULL,
- NULL,
- DispDataRequestComplete,
- DisType->Irp );
- TcpipRecursiveMutexLeave(&TCPLock);
- TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n"));
-
- DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0);
-
- exFreePool(DisType);
- }
-
VOID NTAPI DispCancelRequest(
PDEVICE_OBJECT Device,
PIRP Irp)
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
UCHAR MinorFunction;
- PDISCONNECT_TYPE DisType;
+ BOOLEAN DequeuedIrp = TRUE;
+
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
switch(MinorFunction) {
case TDI_SEND:
case TDI_RECEIVE:
- DisType = exAllocatePool(NonPagedPool, sizeof(DISCONNECT_TYPE));
- if (DisType)
- {
- DisType->Type = TDI_DISCONNECT_RELEASE |
- ((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0);
- DisType->Context = TranContext->Handle.ConnectionContext;
- DisType->Irp = Irp;
-
- TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
-
- if (!ChewCreate(DispDoDisconnect, DisType))
- exFreePool(DisType);
- }
-
- IoReleaseCancelSpinLock(Irp->CancelIrql);
- return;
+ DequeuedIrp = TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp );
+ break;
case TDI_SEND_DATAGRAM:
if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
break;
}
- DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
+ DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
break;
case TDI_RECEIVE_DATAGRAM:
break;
}
- DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
+ DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
break;
case TDI_CONNECT:
- TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
+ DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp);
break;
default:
TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction));
+ ASSERT(FALSE);
break;
}
- IoReleaseCancelSpinLock(Irp->CancelIrql);
+ if (DequeuedIrp)
- IRPFinish(Irp, STATUS_CANCELLED);
+ IRPFinish(Irp, STATUS_CANCELLED);
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
PCONNECTION_ENDPOINT Connection;
- /*NTSTATUS Status = STATUS_SUCCESS;*/
+
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
/* Try canceling the request */
Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
- TCPRemoveIRP(Connection, Irp);
-
- TCPAbortListenForSocket(
- Connection->AddressFile->Listener,
- Connection );
-
- IoReleaseCancelSpinLock(Irp->CancelIrql);
-
+ if (TCPAbortListenForSocket(Connection->AddressFile->Listener,
+ Connection))
+ {
- Irp->IoStatus.Information = 0;
- IRPFinish(Irp, STATUS_CANCELLED);
+ Irp->IoStatus.Information = 0;
+ IRPFinish(Irp, STATUS_CANCELLED);
+ }
TI_DbgPrint(MAX_TRACE, ("Leaving.\n"));
}
PFILE_OBJECT FileObject;
PADDRESS_FILE AddrFile = NULL;
NTSTATUS Status;
+ KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_INVALID_PARAMETER;
}
- if (Connection->AddressFile) {
- TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
- return STATUS_INVALID_PARAMETER;
- }
-
Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters;
Status = ObReferenceObjectByHandle(
return STATUS_INVALID_PARAMETER;
}
+ LockObject(Connection, &OldIrql);
+
+ if (Connection->AddressFile) {
+ ObDereferenceObject(FileObject);
+ UnlockObject(Connection, OldIrql);
+ TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n"));
+ return STATUS_INVALID_PARAMETER;
+ }
+
if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) {
ObDereferenceObject(FileObject);
+ UnlockObject(Connection, OldIrql);
TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n",
FileObject->FsContext2));
return STATUS_INVALID_PARAMETER;
TranContext = FileObject->FsContext;
if (!TranContext) {
ObDereferenceObject(FileObject);
+ UnlockObject(Connection, OldIrql);
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
return STATUS_INVALID_PARAMETER;
}
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
if (!AddrFile) {
+ UnlockObject(Connection, OldIrql);
ObDereferenceObject(FileObject);
TI_DbgPrint(MID_TRACE, ("No address file object.\n"));
return STATUS_INVALID_PARAMETER;
}
+ LockObjectAtDpcLevel(AddrFile);
+
+ ReferenceObject(AddrFile);
Connection->AddressFile = AddrFile;
/* Add connection endpoint to the address file */
+ ReferenceObject(Connection);
AddrFile->Connection = Connection;
/* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
ObDereferenceObject(FileObject);
+ UnlockObjectFromDpcLevel(AddrFile);
+ UnlockObject(Connection, OldIrql);
+
return Status;
}
/* Get associated connection endpoint file object. Quit if none exists */
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (!TranContext) {
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
}
done:
- TcpipRecursiveMutexLeave( &TCPLock );
-
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, 0);
} else
PCONNECTION_ENDPOINT Connection;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
+ KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
return STATUS_INVALID_PARAMETER;
}
+ LockObject(Connection, &OldIrql);
+
if (!Connection->AddressFile) {
+ UnlockObject(Connection, OldIrql);
TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n"));
return STATUS_INVALID_PARAMETER;
}
+ LockObjectAtDpcLevel(Connection->AddressFile);
+
/* Remove this connection from the address file */
+ DereferenceObject(Connection->AddressFile->Connection);
Connection->AddressFile->Connection = NULL;
+ UnlockObjectFromDpcLevel(Connection->AddressFile);
+
/* Remove the address file from this connection */
+ DereferenceObject(Connection->AddressFile);
Connection->AddressFile = NULL;
+ UnlockObject(Connection, OldIrql);
+
return STATUS_SUCCESS;
}
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters;
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
/* Get associated connection endpoint file object. Quit if none exists */
TranContext = IrpSp->FileObject->FsContext;
Irp );
done:
- TcpipRecursiveMutexLeave( &TCPLock );
-
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, 0);
} else
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status = STATUS_SUCCESS;
+ KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
/* Get associated connection endpoint file object. Quit if none exists */
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters;
- TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n",
- Connection->AddressFile ));
- ASSERT(Connection->AddressFile);
-
Status = DispPrepareIrpForCancel
(TranContext->Handle.ConnectionContext,
Irp,
(PDRIVER_CANCEL)DispCancelListenRequest);
+ LockObject(Connection, &OldIrql);
+
+ if (Connection->AddressFile == NULL)
+ {
+ TI_DbgPrint(MID_TRACE, ("No associated address file\n"));
+ UnlockObject(Connection, OldIrql);
+ Status = STATUS_INVALID_PARAMETER;
+ goto done;
+ }
+
+ LockObjectAtDpcLevel(Connection->AddressFile);
+
/* Listening will require us to create a listening socket and store it in
* the address file. It will be signalled, and attempt to complete an irp
* when a new connection arrives. */
Status = STATUS_NO_MEMORY;
if( NT_SUCCESS(Status) ) {
+ ReferenceObject(Connection->AddressFile);
Connection->AddressFile->Listener->AddressFile =
Connection->AddressFile;
Irp );
}
- done:
- TcpipRecursiveMutexLeave( &TCPLock );
+ UnlockObjectFromDpcLevel(Connection->AddressFile);
+ UnlockObject(Connection, OldIrql);
+ done:
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, 0);
} else
PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
- NTSTATUS Status;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters;
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (!TranContext) {
TI_DbgPrint(MID_TRACE, ("Bad transport context.\n"));
- TcpipRecursiveMutexLeave(&TCPLock);
return STATUS_INVALID_PARAMETER;
}
(FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) +
sizeof(TDI_ADDRESS_IP))) {
TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n"));
- TcpipRecursiveMutexLeave(&TCPLock);
return STATUS_BUFFER_TOO_SMALL;
}
AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress);
Address = (PTA_IP_ADDRESS)&AddressInfo->Address;
- switch ((ULONG)IrpSp->FileObject->FsContext2) {
+ switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
case TDI_TRANSPORT_ADDRESS_FILE:
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
RtlZeroMemory(
&Address->Address[0].Address[0].sin_zero,
sizeof(Address->Address[0].Address[0].sin_zero));
- TcpipRecursiveMutexLeave(&TCPLock);
return STATUS_SUCCESS;
case TDI_CONNECTION_FILE:
Endpoint =
(PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
- TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE );
- DbgPrint("Returning socket address %x\n", Address->Address[0].Address[0].in_addr);
RtlZeroMemory(
&Address->Address[0].Address[0].sin_zero,
sizeof(Address->Address[0].Address[0].sin_zero));
- TcpipRecursiveMutexLeave(&TCPLock);
- return STATUS_SUCCESS;
+ return TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE );
default:
TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
- TcpipRecursiveMutexLeave(&TCPLock);
return STATUS_INVALID_PARAMETER;
}
}
(FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) +
sizeof(PVOID))) {
TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n"));
- TcpipRecursiveMutexLeave(&TCPLock);
return STATUS_BUFFER_TOO_SMALL;
}
AddressInfo = (PTDI_CONNECTION_INFORMATION)
MmGetSystemAddressForMdl(Irp->MdlAddress);
- switch ((ULONG)IrpSp->FileObject->FsContext2) {
+ switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
case TDI_TRANSPORT_ADDRESS_FILE:
AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle;
Endpoint = AddrFile ? AddrFile->Connection : NULL;
default:
TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
- TcpipRecursiveMutexLeave(&TCPLock);
return STATUS_INVALID_PARAMETER;
}
if (!Endpoint) {
TI_DbgPrint(MID_TRACE, ("No connection object.\n"));
- TcpipRecursiveMutexLeave(&TCPLock);
return STATUS_INVALID_PARAMETER;
}
- Status = TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE );
+ return TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE );
+ }
+
+ case TDI_QUERY_MAX_DATAGRAM_INFO:
+ {
+ PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo = MmGetSystemAddressForMdl(Irp->MdlAddress);
+
+ MaxDatagramInfo->MaxDatagramSize = 0xFFFF;
- TcpipRecursiveMutexLeave(&TCPLock);
- return Status;
+ return STATUS_SUCCESS;
- }
+ }
}
- TcpipRecursiveMutexLeave(&TCPLock);
return STATUS_NOT_IMPLEMENTED;
}
IrpSp = IoGetCurrentIrpStackLocation(Irp);
ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
}
done:
- TcpipRecursiveMutexLeave( &TCPLock );
-
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, BytesReceived);
} else
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
}
done:
- TcpipRecursiveMutexLeave( &TCPLock );
-
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, BytesReceived);
} else
IrpSp = IoGetCurrentIrpStackLocation(Irp);
SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters);
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
}
done:
- TcpipRecursiveMutexLeave( &TCPLock );
-
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, BytesSent);
} else
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters);
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
-
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
(*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)));
if( (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send != NULL) )
+ {
+ ULONG DataUsed = 0;
Status = (*((PADDRESS_FILE)Request.Handle.AddressHandle)->Send)(
Request.Handle.AddressHandle,
DgramInfo->SendDatagramInformation,
DataBuffer,
BufferSize,
- &Irp->IoStatus.Information);
+ &DataUsed);
+ Irp->IoStatus.Information = DataUsed;
+ }
- else
+ else {
Status = STATUS_UNSUCCESSFUL;
- }
+ ASSERT(FALSE);
++ }
}
done:
- TcpipRecursiveMutexLeave( &TCPLock );
-
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, Irp->IoStatus.Information);
} else
Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters;
Status = STATUS_SUCCESS;
- TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ LockObject(AddrFile, &OldIrql);
/* Set the event handler. if an event handler is associated with
a specific event, it's flag (RegisteredXxxHandler) is TRUE.
Status = STATUS_INVALID_PARAMETER;
}
- TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ UnlockObject(AddrFile, OldIrql);
return Status;
}
*/
{
PTI_QUERY_CONTEXT QueryContext;
- UINT Count = 0;
QueryContext = (PTI_QUERY_CONTEXT)Context;
if (NT_SUCCESS(Status)) {
- Count = CopyBufferToBufferChain(
+ CopyBufferToBufferChain(
QueryContext->InputMdl,
FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context),
(PCHAR)&QueryContext->QueryInfo.Context,
QueryContext->Irp->IoStatus.Information = ByteCount;
QueryContext->Irp->IoStatus.Status = Status;
- exFreePool(QueryContext);
+ ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
}
TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
- switch ((ULONG)IrpSp->FileObject->FsContext2) {
+ switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
case TDI_TRANSPORT_ADDRESS_FILE:
Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
break;
IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
OutputBuffer = Irp->UserBuffer;
- QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
+ QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG);
if (QueryContext) {
_SEH2_TRY {
InputMdl = IoAllocateMdl(InputBuffer,
IoFreeMdl(OutputMdl);
}
- exFreePool(QueryContext);
+ ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
} else
Status = STATUS_INSUFFICIENT_RESOURCES;
} else if( InputBufferLength ==
Size = 0;
- QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT));
+ QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG);
if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES;
_SEH2_TRY {
if( !NT_SUCCESS(Status) || !InputMdl ) {
if( InputMdl ) IoFreeMdl( InputMdl );
- exFreePool(QueryContext);
+ ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
return Status;
}
TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
Info = (PTCP_REQUEST_SET_INFORMATION_EX)Irp->AssociatedIrp.SystemBuffer;
- switch ((ULONG)IrpSp->FileObject->FsContext2) {
+ switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) {
case TDI_TRANSPORT_ADDRESS_FILE:
Request.Handle.AddressHandle = TranContext->Handle.AddressHandle;
break;
<include>include</include>
<include base="ntoskrnl">include</include>
<define name="_NTHAL_" />
+ <define name="_X86BIOS_" />
<directory name="generic">
<directory name="bus">
<file>bushndlr.c</file>
<file>isabus.c</file>
<file>halbus.c</file>
+ <file>pcibus.c</file>
<file>pcidata.c</file>
<file>sysbus.c</file>
</directory>
<file>beep.c</file>
- <file>bios.c</file>
<file>cmos.c</file>
<file>dma.c</file>
<file>drive.c</file>
<file>display.c</file>
- <file>halinit.c</file>
- <file>misc.c</file>
- <file>portio.c</file>
<file>profil.c</file>
<file>reboot.c</file>
<file>sysinfo.c</file>
- <file>systimer.S</file>
<file>timer.c</file>
- <file>usage.c</file>
- <file>v86.s</file>
+ <if property="ARCH" value="i386">
+ <file>bios.c</file>
+ <file>halinit.c</file>
+ <file>misc.c</file>
+ <file>usage.c</file>
+ <directory name="i386">
+ <file>portio.c</file>
+ <file>systimer.S</file>
+ <file>v86.s</file>
+ </directory>
+ </if>
+ <if property="ARCH" value="amd64">
+ <directory name="amd64">
+ <file>halinit.c</file>
+ <file>irq.S</file>
+ <file>misc.c</file>
- <file>pic.c</file>
+ <file>systimer.S</file>
+ <file>usage.c</file>
+ <file>x86bios.c</file>
+ </directory>
+ </if>
</directory>
+ <if property="ARCH" value="amd64">
+ <directory name="mp">
+ <file>apic.c</file>
+ </directory>
+ </if>
<directory name="include">
<pch>hal.h</pch>
</directory>
<include base="ntoskrnl">include</include>
<define name="_NTHAL_" />
<directory name="generic">
- <file>irq.S</file>
- <file>processor.c</file>
+ <file>pic.c</file>
<file>spinlock.c</file>
</directory>
+ <directory name="up">
+ <file>processor.c</file>
+ <if property="ARCH" value="i386">
+ <file>irq.S</file>
+ </if>
+ </directory>
</module>
</group>
UCHAR Bits;
} SYSTEM_CONTROL_PORT_B_REGISTER, *PSYSTEM_CONTROL_PORT_B_REGISTER;
+ //
+ // See ISA System Architecture 3rd Edition (Tom Shanley, Don Anderson, John Swindle)
+ // P. 396, 397
+ //
+ // These ports are controlled by the i8259 Programmable Interrupt Controller (PIC)
+ //
+ #define PIC1_CONTROL_PORT 0x20
+ #define PIC1_DATA_PORT 0x21
+ #define PIC2_CONTROL_PORT 0xA0
+ #define PIC2_DATA_PORT 0xA1
+
+ //
+ // Definitions for ICW/OCW Bits
+ //
+ typedef enum _I8259_ICW1_OPERATING_MODE
+ {
+ Cascade,
+ Single
+ } I8259_ICW1_OPERATING_MODE;
+
+ typedef enum _I8259_ICW1_INTERRUPT_MODE
+ {
+ EdgeTriggered,
+ LevelTriggered
+ } I8259_ICW1_INTERRUPT_MODE;
+
+ typedef enum _I8259_ICW1_INTERVAL
+ {
+ Interval8,
+ Interval4
+ } I8259_ICW1_INTERVAL;
+
+ typedef enum _I8259_ICW4_SYSTEM_MODE
+ {
+ Mcs8085Mode,
+ New8086Mode
+ } I8259_ICW4_SYSTEM_MODE;
+
+ typedef enum _I8259_ICW4_EOI_MODE
+ {
+ NormalEoi,
+ AutomaticEoi
+ } I8259_ICW4_EOI_MODE;
+
+ typedef enum _I8259_ICW4_BUFFERED_MODE
+ {
+ NonBuffered,
+ NonBuffered2,
+ BufferedSlave,
+ BufferedMaster
+ } I8259_ICW4_BUFFERED_MODE;
+
+ //
+ // Definitions for ICW Registers
+ //
+ typedef union _I8259_ICW1
+ {
+ struct
+ {
+ UCHAR NeedIcw4:1;
+ I8259_ICW1_OPERATING_MODE OperatingMode:1;
+ I8259_ICW1_INTERVAL Interval:1;
+ I8259_ICW1_INTERRUPT_MODE InterruptMode:1;
+ UCHAR Init:1;
+ UCHAR InterruptVectorAddress:3;
+ };
+ UCHAR Bits;
+ } I8259_ICW1, *PI8259_ICW1;
+
+ typedef union _I8259_ICW2
+ {
+ struct
+ {
+ UCHAR Sbz:3;
+ UCHAR InterruptVector:5;
+ };
+ UCHAR Bits;
+ } I8259_ICW2, *PI8259_ICW2;
+
+ typedef union _I8259_ICW3
+ {
+ union
+ {
+ struct
+ {
+ UCHAR SlaveIrq0:1;
+ UCHAR SlaveIrq1:1;
+ UCHAR SlaveIrq2:1;
+ UCHAR SlaveIrq3:1;
+ UCHAR SlaveIrq4:1;
+ UCHAR SlaveIrq5:1;
+ UCHAR SlaveIrq6:1;
+ UCHAR SlaveIrq7:1;
+ };
+ struct
+ {
+ UCHAR SlaveId:3;
+ UCHAR Reserved:5;
+ };
+ };
+ UCHAR Bits;
+ } I8259_ICW3, *PI8259_ICW3;
+
+ typedef union _I8259_ICW4
+ {
+ struct
+ {
+ I8259_ICW4_SYSTEM_MODE SystemMode:1;
+ I8259_ICW4_EOI_MODE EoiMode:1;
+ I8259_ICW4_BUFFERED_MODE BufferedMode:2;
+ UCHAR SpecialFullyNestedMode:1;
+ UCHAR Reserved:3;
+ };
+ UCHAR Bits;
+ } I8259_ICW4, *PI8259_ICW4;
+
+ //
+ // See EISA System Architecture 2nd Edition (Tom Shanley, Don Anderson, John Swindle)
+ // P. 34, 35
+ //
+ // These ports are controlled by the i8259A Programmable Interrupt Controller (PIC)
+ //
+ #define EISA_ELCR_MASTER 0x4D0
+ #define EISA_ELCR_SLAVE 0x4D1
+
+ typedef union _EISA_ELCR
+ {
+ struct
+ {
+ struct
+ {
+ UCHAR Irq0Level:1;
+ UCHAR Irq1Level:1;
+ UCHAR Irq2Level:1;
+ UCHAR Irq3Level:1;
+ UCHAR Irq4Level:1;
+ UCHAR Irq5Level:1;
+ UCHAR Irq6Level:1;
+ UCHAR Irq7Level:1;
+ } Master;
+ struct
+ {
+ UCHAR Irq8Level:1;
+ UCHAR Irq9Level:1;
+ UCHAR Irq10Level:1;
+ UCHAR Irq11Level:1;
+ UCHAR Irq12Level:1;
+ UCHAR Irq13Level:1;
+ UCHAR Irq14Level:1;
+ UCHAR Irq15Level:1;
+ } Slave;
+ };
+ USHORT Bits;
+ } EISA_ELCR, *PEISA_ELCR;
+
//
// Mm PTE/PDE to Hal PTE/PDE
//
IN PVOID Handler,
IN KINTERRUPT_MODE Mode);
- /* irql.c */
- VOID NTAPI HalpInitPICs(VOID);
+ /* pic.c */
+ VOID NTAPI HalpInitializePICs(IN BOOLEAN EnableInterrupts);
/* udelay.c */
VOID NTAPI HalpInitializeClock(VOID);
VOID
);
+VOID
+NTAPI
+HalpSetInterruptGate(ULONG Index, PVOID Address);
+
#ifdef _M_AMD64
#define KfLowerIrql KeLowerIrql
#ifndef CONFIG_SMP
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: hal/halx86/apic.c
+ * FILE: hal/halx86/mp/apic.c
* PURPOSE:
* PROGRAMMER:
*/
LONG tt1, tt2;
BOOLEAN TSCPresent;
+ t1.QuadPart = 0;
+
DPRINT("Calibrating APIC timer for CPU %d\n", CPU);
APICSetupLVTT(1000000000);
CPUMap[CPU].BusSpeed%1000000);
}
-VOID
-SetInterruptGate(ULONG index, ULONG_PTR address)
-{
-#ifdef _M_AMD64
- KIDTENTRY64 *idt;
-
- idt = &KeGetPcr()->IdtBase[index];
-
- idt->OffsetLow = address & 0xffff;
- idt->Selector = KGDT_64_R0_CODE;
- idt->IstIndex = 0;
- idt->Reserved0 = 0;
- idt->Type = 0x0e;
- idt->Dpl = 0;
- idt->Present = 1;
- idt->OffsetMiddle = (address >> 16) & 0xffff;
- idt->OffsetHigh = address >> 32;
- idt->Reserved1 = 0;
- idt->Alignment = 0;
-#else
- KIDTENTRY *idt;
- KIDT_ACCESS Access;
-
- /* Set the IDT Access Bits */
- Access.Reserved = 0;
- Access.Present = 1;
- Access.Dpl = 0; /* Kernel-Mode */
- Access.SystemSegmentFlag = 0;
- Access.SegmentType = I386_INTERRUPT_GATE;
-
- idt = (KIDTENTRY*)((ULONG)KeGetPcr()->IDT + index * sizeof(KIDTENTRY));
- idt->Offset = (USHORT)(address & 0xffff);
- idt->Selector = KGDT_R0_CODE;
- idt->Access = Access.Value;
- idt->ExtendedOffset = (USHORT)(address >> 16);
-#endif
-}
-
VOID HaliInitBSP(VOID)
{
#ifdef CONFIG_SMP
BSPInitialized = TRUE;
/* Setup interrupt handlers */
- SetInterruptGate(LOCAL_TIMER_VECTOR, (ULONG_PTR)MpsTimerInterrupt);
- SetInterruptGate(ERROR_VECTOR, (ULONG_PTR)MpsErrorInterrupt);
- SetInterruptGate(SPURIOUS_VECTOR, (ULONG_PTR)MpsSpuriousInterrupt);
+ HalpSetInterruptGate(LOCAL_TIMER_VECTOR, MpsTimerInterrupt);
+ HalpSetInterruptGate(ERROR_VECTOR, MpsErrorInterrupt);
+ HalpSetInterruptGate(SPURIOUS_VECTOR, MpsSpuriousInterrupt);
#ifdef CONFIG_SMP
- SetInterruptGate(IPI_VECTOR, (ULONG_PTR)MpsIpiInterrupt);
+ HalpSetInterruptGate(IPI_VECTOR, MpsIpiInterrupt);
#endif
- DPRINT("APIC is mapped at 0x%X\n", APICBase);
+ DPRINT1("APIC is mapped at 0x%p\n", (PVOID)APICBase);
if (VerifyLocalAPIC())
{
}
else
{
- DPRINT("No APIC found\n");
+ DPRINT1("No APIC found\n");
ASSERT(FALSE);
}
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/mps.S
+ * FILE: hal/halx86/mp/mps.S
* PURPOSE: Intel MultiProcessor specification support
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
;
; COPYRIGHT: See COPYING in the top level directory
; PROJECT: ReactOS kernel
- ; FILE: ntoskrnl/hal/x86/mpsboot.c
+ ; FILE: hal/halx86/mp/mpsboot.c
; PURPOSE: Bootstrap code for application processors
; PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
; UPDATE HISTORY:
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: ntoskrnl/hal/x86/mpsirql.c
+ * FILE: hal/halx86/mp/mpsirql.c
* PURPOSE: Implements IRQLs for multiprocessor systems
* PROGRAMMERS: David Welch (welch@cwcom.net)
* Casper S. Hornstrup (chorns@users.sourceforge.net)
HalpLowerIrql (NewIrql, FALSE);
}
-
-/**********************************************************************
- * NAME EXPORTED
- * KeLowerIrql
- *
- * DESCRIPTION
- * Restores the irq level on the current processor
- *
- * ARGUMENTS
- * NewIrql = Irql to lower to
- *
- * RETURN VALUE
- * None
- *
- * NOTES
- */
-#undef KeLowerIrql
-VOID NTAPI
-KeLowerIrql (KIRQL NewIrql)
-{
- KfLowerIrql (NewIrql);
-}
-
-
/**********************************************************************
* NAME EXPORTED
* KfRaiseIrql
}
-/**********************************************************************
- * NAME EXPORTED
- * KeRaiseIrql
- *
- * DESCRIPTION
- * Raises the hardware priority (irql)
- *
- * ARGUMENTS
- * NewIrql = Irql to raise to
- * OldIrql (OUT) = Caller supplied storage for the previous irql
- *
- * RETURN VALUE
- * None
- *
- * NOTES
- * Calls KfRaiseIrql
- */
-#undef KeRaiseIrql
-VOID NTAPI
-KeRaiseIrql (KIRQL NewIrql,
- PKIRQL OldIrql)
-{
- *OldIrql = KfRaiseIrql (NewIrql);
-}
-
-
/**********************************************************************
* NAME EXPORTED
* KeRaiseIrqlToDpcLevel
VOID
NTAPI
-HalDisableSystemInterrupt(ULONG Vector,
- KIRQL Irql)
+HalDisableSystemInterrupt (ULONG Vector,
+ KIRQL Irql)
{
ULONG irq;
/* GLOBALS *******************************************************************/
- PICInitTable:
-
- /* Master PIC */
- .short 0x20 /* Port */
- .byte 0x11 /* Edge, cascade, CAI 8, ICW4 */
- .byte PRIMARY_VECTOR_BASE /* Base */
- .byte 4 /* IRQ 4 connected to slave */
- .byte 1 /* Non buffered, not nested, 8086 */
-
- /* Slave PIC */
- .short 0xA0 /* Port */
- .byte 0x11 /* Edge, cascade, CAI 8, ICW4 */
- .byte PRIMARY_VECTOR_BASE + 8 /* Base */
- .byte 2 /* Slave ID: Slave 2 */
- .byte 1 /* Non buffered, not nested, 8086 */
-
- /* End of initialization table */
- .short 0
-
KiI8259MaskTable:
.long 0 /* IRQL 0 */
.long 0 /* IRQL 1 */
.long 0 /* IRQL 31 */
HalpSpecialDismissTable:
- .rept 7
+ .rept 7
.long GenericIRQ /* IRQ 0-7 */
- .endr
+ .endr
.long IRQ7 /* IRQ 7 */
.rept 5
.long GenericIRQ /* IRQ 8-12 */
- .endr
+ .endr
.long IRQ13 /* IRQ 13 */
.long GenericIRQ /* IRQ 14 */
.long IRQ15 /* IRQ 15 */
- .rept 20
+ .rept 20
.long GenericIRQ /* IRQ 16-35 */
- .endr
+ .endr
#if DBG
.rept 172
.long InvalidIRQ /* IRQ 36-207 */
ret
.endfunc
- .globl _HalpInitPICs@0
- .func HalpInitPICs@0
- _HalpInitPICs@0:
-
- /* Save ESI and disable interrupts */
- push esi
- pushf
- cli
-
- /* Read the init table */
- lea esi, PICInitTable
- lodsw
-
- InitLoop:
-
- /* Put the port in EDX */
- movzx edx, ax
-
- /* Initialize the PIC, using a delay for each command */
- outsb
- jmp $+2
- inc edx
- outsb
- jmp $+2
- outsb
- jmp $+2
- outsb
- jmp $+2
-
- /* Mask all interrupts */
- mov al, 0xFF
- out dx, al
-
- /* Check if we're done, otherwise initialize next PIC */
- lodsw
- cmp ax, 0
- jnz InitLoop
-
- /* Read EISA Edge/Level Register */
- mov edx, 0x4D1
- in al, dx
- mov ah, al
- dec edx
- in al, dx
-
- /* Clear reserved bits and see if there's anything there */
- and eax, 0xDEF8
- cmp eax, 0xDEF8
- jz NoEisa
-
- /* FIXME */
- //UNHANDLED_PATH
-
- /* Restore interrupts and return */
- NoEisa:
- popf
- pop esi
- ret
- .endfunc
-
.globl @HalClearSoftwareInterrupt@4
.func @HalClearSoftwareInterrupt@4, @HalClearSoftwareInterrupt@4
@HalClearSoftwareInterrupt@4:
and ecx, 0xFF
/* Validate IRQL */
- #if DBG
+ #if DBG
cmp cl, PCR[KPCR_IRQL]
ja InvalidIrql
- #endif
+ #endif
/* Save flags since we'll disable interrupts */
pushf
_@KfRaiseIrql@4:
@KfRaiseIrql@4:
- /* Get the IRQL */
+ /* Get the IRQL */
movzx ecx, cl
mov eax, PCR[KPCR_IRQL]
#define WM_HOTKEY 786
#define WM_PRINT 791
#define WM_PRINTCLIENT 792
+
+ #define WM_DWMCOMPOSITIONCHANGED 0x031E
+ #define WM_DWMNCRENDERINGCHANGED 0x031F
+ #define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320
+ #define WM_DWMWINDOWMAXIMIZEDCHANGE 0x0321
+
#define WM_HANDHELDFIRST 856
#define WM_HANDHELDLAST 863
#define WM_AFXFIRST 864
int iVertSpacing;
int iTitleWrap;
LOGFONTA lfFont;
-} ICONMETRICSA,*LPICONMETRICSA;
+} ICONMETRICSA, *PICONMETRICSA, *LPICONMETRICSA;
typedef struct tagICONMETRICSW {
UINT cbSize;
int iVertSpacing;
int iTitleWrap;
LOGFONTW lfFont;
-} ICONMETRICSW,*LPICONMETRICSW;
+} ICONMETRICSW, *PICONMETRICSW, *LPICONMETRICSW;
#ifdef UNICODE
typedef ICONMETRICSW ICONMETRICS,*LPICONMETRICS;
#define wsprintf wsprintfW
#define wvsprintf wvsprintfW
-#ifndef NOGDI
+#if defined(_WINGDI_) && !defined(NOGDI)
#define ChangeDisplaySettings ChangeDisplaySettingsW
#define ChangeDisplaySettingsEx ChangeDisplaySettingsExW
#define CreateDesktop CreateDesktopW
#define EnumDisplaySettings EnumDisplaySettingsW
#define EnumDisplaySettingsEx EnumDisplaySettingsExW
#define EnumDisplayDevices EnumDisplayDevicesW
-#endif /* NOGDI */
+#endif /* _WINGDI_ && !NOGDI */
#else /* UNICODE */
#define EDITWORDBREAKPROC EDITWORDBREAKPROCA
#define PROPENUMPROC PROPENUMPROCA
typedef struct _PROCDESKHEAD
{
- HANDLE h;
- DWORD cLockObj;
+ HEAD;
DWORD hTaskWow;
struct _DESKTOP *rpdesk;
PVOID pSelf;
} PROCDESKHEAD, *PPROCDESKHEAD;
+ typedef struct _PROCMARKHEAD
+ {
+ HEAD;
+ ULONG hTaskWow;
+ PPROCESSINFO ppi;
+ } PROCMARKHEAD, *PPROCMARKHEAD;
+
#define UserHMGetHandle(obj) ((obj)->head.h)
/* Window Client Information structure */
PPROCESSINFO ppi;
} CLIENTINFO, *PCLIENTINFO;
-/* Make sure it fits exactly into the TEB */
-C_ASSERT(sizeof(CLIENTINFO) == FIELD_OFFSET(TEB, glDispatchTable) - FIELD_OFFSET(TEB, Win32ClientInfo));
+/* Make sure it fits into the TEB */
+C_ASSERT(sizeof(CLIENTINFO) <= sizeof(((PTEB)0)->Win32ClientInfo));
#define GetWin32ClientInfo() ((PCLIENTINFO)(NtCurrentTeb()->Win32ClientInfo))
NTAPI
NtUserTranslateMessage(
LPMSG lpMsg,
- HKL dwhkl );
+ UINT flags );
BOOL
NTAPI
LONG TCP_IPIdentification = 0;
static BOOLEAN TCPInitialized = FALSE;
static NPAGED_LOOKASIDE_LIST TCPSegmentList;
- LIST_ENTRY SignalledConnectionsList;
- KSPIN_LOCK SignalledConnectionsLock;
- LIST_ENTRY SleepingThreadsList;
- FAST_MUTEX SleepingThreadsLock;
- RECURSIVE_MUTEX TCPLock;
PORT_SET TCPPorts;
+ CLIENT_DATA ClientInfo;
- static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) {
- NTSTATUS Status = STATUS_SUCCESS;
- PTCP_COMPLETION_ROUTINE Complete;
+ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
+ {
- PTDI_BUCKET Bucket;
- PLIST_ENTRY Entry;
+ PTDI_BUCKET Bucket;
+ PLIST_ENTRY Entry;
+ NTSTATUS Status;
- PIRP Irp;
- PMDL Mdl;
+ PIRP Irp;
+ PMDL Mdl;
+ ULONG SocketError = 0;
+ KIRQL OldIrql;
+ PTCP_COMPLETION_ROUTINE Complete;
- ASSERT_LOCKED(&TCPLock);
+ if (ClientInfo.Unlocked)
+ LockObjectAtDpcLevel(Connection);
- TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
- Connection, Connection->SocketContext));
+ TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
+ Connection, Connection->SocketContext));
- if( Connection->SignalState & SEL_FIN ) {
- TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
+ if( Connection->SignalState & SEL_FIN ) {
+ TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
- while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
- &Connection->Lock )) != NULL)
+ /* If OskitTCP initiated the disconnect, try to read the socket error that occurred */
+ if (Connection->SocketContext)
+ SocketError = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext));
+
+ /* Default to STATUS_CANCELLED if we initiated the disconnect or no socket error was reported */
+ if (!Connection->SocketContext || !SocketError)
+ SocketError = STATUS_CANCELLED;
+
+ while (!IsListEmpty(&Connection->ReceiveRequest))
- {
+ {
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Complete = Bucket->Request.RequestNotifyObject;
+ Entry = RemoveHeadList( &Connection->ReceiveRequest );
- /* We have to notify oskittcp of the abortion */
- TCPDisconnect
- ( Connection,
- TDI_DISCONNECT_RELEASE | TDI_DISCONNECT_ABORT,
- NULL,
- NULL,
- Bucket->Request.RequestNotifyObject,
- (PIRP)Bucket->Request.RequestContext );
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
++ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+ Bucket->Status = SocketError;
+ Bucket->Information = 0;
- exFreePool(Bucket);
+ InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
+ }
- while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
- &Connection->Lock )) != NULL)
+ while (!IsListEmpty(&Connection->SendRequest))
- {
+ {
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Complete = Bucket->Request.RequestNotifyObject;
+ Entry = RemoveHeadList( &Connection->SendRequest );
- /* We have to notify oskittcp of the abortion */
- TCPDisconnect
- ( Connection,
- TDI_DISCONNECT_RELEASE,
- NULL,
- NULL,
- Bucket->Request.RequestNotifyObject,
- (PIRP)Bucket->Request.RequestContext );
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
++ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+ Bucket->Status = SocketError;
+ Bucket->Information = 0;
- exFreePool(Bucket);
+ InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
+ }
- while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
- &Connection->Lock )) != NULL)
+ while (!IsListEmpty(&Connection->ListenRequest))
- {
+ {
+ Entry = RemoveHeadList( &Connection->ListenRequest );
+
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Complete = Bucket->Request.RequestNotifyObject;
- /* We have to notify oskittcp of the abortion */
- TCPAbortListenForSocket(Connection->AddressFile->Listener,
- Connection);
+ Bucket->Status = SocketError;
+ Bucket->Information = 0;
+ DereferenceObject(Bucket->AssociatedEndpoint);
- Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+ InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
+ }
- while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
- &Connection->Lock )) != NULL)
+ while (!IsListEmpty(&Connection->ConnectRequest))
- {
+ {
+ Entry = RemoveHeadList( &Connection->ConnectRequest );
+
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Complete = Bucket->Request.RequestNotifyObject;
- Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+ Bucket->Status = SocketError;
+ Bucket->Information = 0;
+
+ InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
+ }
- Connection->SignalState = 0;
+ Connection->SignalState = SEL_FIN;
}
- /* Things that can happen when we try the initial connection */
- if( Connection->SignalState & SEL_CONNECT ) {
+ /* Things that can happen when we try the initial connection */
+ if( Connection->SignalState & SEL_CONNECT ) {
- while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
- &Connection->Lock )) != NULL ) {
+ while (!IsListEmpty(&Connection->ConnectRequest)) {
+ Entry = RemoveHeadList( &Connection->ConnectRequest );
-
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+
- TI_DbgPrint(DEBUG_TCP, ("Connect Event\n"));
-
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Complete = Bucket->Request.RequestNotifyObject;
- TI_DbgPrint(DEBUG_TCP,
- ("Completing Request %x\n", Bucket->Request.RequestContext));
- Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
+ Bucket->Status = STATUS_SUCCESS;
+ Bucket->Information = 0;
- /* Frees the bucket allocated in TCPConnect */
- exFreePool( Bucket );
+ InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
- }
+ }
+ }
- if( Connection->SignalState & SEL_ACCEPT ) {
- /* Handle readable on a listening socket --
- * TODO: Implement filtering
- */
- TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n",
- Connection,
- IsListEmpty(&Connection->ListenRequest) ?
- "empty" : "nonempty"));
+ if( Connection->SignalState & SEL_ACCEPT ) {
+ /* Handle readable on a listening socket --
+ * TODO: Implement filtering
+ */
-
+ TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n",
+ Connection,
+ IsListEmpty(&Connection->ListenRequest) ?
+ "empty" : "nonempty"));
- while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
- &Connection->Lock )) != NULL ) {
+ while (!IsListEmpty(&Connection->ListenRequest)) {
- PIO_STACK_LOCATION IrpSp;
+ PIO_STACK_LOCATION IrpSp;
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Entry = RemoveHeadList( &Connection->ListenRequest );
+
- Complete = Bucket->Request.RequestNotifyObject;
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Irp = Bucket->Request.RequestContext;
- IrpSp = IoGetCurrentIrpStackLocation( Irp );
+ Irp = Bucket->Request.RequestContext;
+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
- TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
+ TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
+
- Status = TCPServiceListeningSocket
- ( Connection->AddressFile->Listener,
- Bucket->AssociatedEndpoint,
- (PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
+ Status = TCPServiceListeningSocket
+ ( Connection->AddressFile->Listener,
+ Bucket->AssociatedEndpoint,
+ (PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
- TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
+ TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
- if( Status == STATUS_PENDING ) {
+ if( Status == STATUS_PENDING ) {
- ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, &Connection->Lock );
+ InsertHeadList( &Connection->ListenRequest, &Bucket->Entry );
- break;
- } else {
+ break;
+ } else {
- Complete( Bucket->Request.RequestContext, Status, 0 );
- exFreePool( Bucket );
+ Bucket->Status = Status;
+ Bucket->Information = 0;
+ DereferenceObject(Bucket->AssociatedEndpoint);
+
+ InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
- }
- }
+ }
+ }
+ }
- /* Things that happen after we're connected */
- if( Connection->SignalState & SEL_READ ) {
- TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
- IsListEmpty(&Connection->ReceiveRequest) ?
- "empty" : "nonempty"));
+ /* Things that happen after we're connected */
+ if( Connection->SignalState & SEL_READ ) {
+ TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n",
+ IsListEmpty(&Connection->ReceiveRequest) ?
+ "empty" : "nonempty"));
- while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
- &Connection->Lock )) != NULL ) {
+ while (!IsListEmpty(&Connection->ReceiveRequest)) {
- OSK_UINT RecvLen = 0, Received = 0;
- PVOID RecvBuffer = 0;
+ OSK_UINT RecvLen = 0, Received = 0;
+ PVOID RecvBuffer = 0;
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Entry = RemoveHeadList( &Connection->ReceiveRequest );
+
- Complete = Bucket->Request.RequestNotifyObject;
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Irp = Bucket->Request.RequestContext;
- Mdl = Irp->MdlAddress;
+ Irp = Bucket->Request.RequestContext;
+ Mdl = Irp->MdlAddress;
- TI_DbgPrint(DEBUG_TCP,
- ("Getting the user buffer from %x\n", Mdl));
+ TI_DbgPrint(DEBUG_TCP,
+ ("Getting the user buffer from %x\n", Mdl));
- NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
+ NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
- TI_DbgPrint(DEBUG_TCP,
- ("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
+ TI_DbgPrint(DEBUG_TCP,
+ ("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
- TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
- TI_DbgPrint
- (DEBUG_TCP,
- ("Connection->SocketContext: %x\n",
- Connection->SocketContext));
- TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
+ TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
+ TI_DbgPrint
+ (DEBUG_TCP,
+ ("Connection->SocketContext: %x\n",
+ Connection->SocketContext));
+ TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
- Status = TCPTranslateError
- ( OskitTCPRecv( Connection->SocketContext,
- RecvBuffer,
- RecvLen,
- &Received,
- 0 ) );
+ Status = TCPTranslateError
+ ( OskitTCPRecv( Connection->SocketContext,
+ RecvBuffer,
+ RecvLen,
+ &Received,
+ 0 ) );
- TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
+ TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
- if( Status == STATUS_SUCCESS ) {
- TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
- Received, Status));
-
- Complete( Bucket->Request.RequestContext,
- STATUS_SUCCESS, Received );
- exFreePool( Bucket );
- } else if( Status == STATUS_PENDING ) {
- ExInterlockedInsertHeadList
- ( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
+ if( Status == STATUS_PENDING ) {
+ InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry );
- break;
- } else {
- TI_DbgPrint(DEBUG_TCP,
- ("Completing Receive request: %x %x\n",
- Bucket->Request, Status));
+ break;
+ } else {
+ TI_DbgPrint(DEBUG_TCP,
+ ("Completing Receive request: %x %x\n",
+ Bucket->Request, Status));
- Complete( Bucket->Request.RequestContext, Status, 0 );
- exFreePool( Bucket );
+
+ Bucket->Status = Status;
+ Bucket->Information = (Status == STATUS_SUCCESS) ? Received : 0;
+
+ InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
- }
- }
- if( Connection->SignalState & SEL_WRITE ) {
- TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
- IsListEmpty(&Connection->SendRequest) ?
- "empty" : "nonempty"));
+ }
+ }
+ }
+ if( Connection->SignalState & SEL_WRITE ) {
+ TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
+ IsListEmpty(&Connection->SendRequest) ?
+ "empty" : "nonempty"));
- while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
- &Connection->Lock )) != NULL ) {
+ while (!IsListEmpty(&Connection->SendRequest)) {
- OSK_UINT SendLen = 0, Sent = 0;
- PVOID SendBuffer = 0;
+ OSK_UINT SendLen = 0, Sent = 0;
+ PVOID SendBuffer = 0;
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Entry = RemoveHeadList( &Connection->SendRequest );
+
- Complete = Bucket->Request.RequestNotifyObject;
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
- Irp = Bucket->Request.RequestContext;
- Mdl = Irp->MdlAddress;
+ Irp = Bucket->Request.RequestContext;
+ Mdl = Irp->MdlAddress;
- TI_DbgPrint(DEBUG_TCP,
- ("Getting the user buffer from %x\n", Mdl));
+ TI_DbgPrint(DEBUG_TCP,
+ ("Getting the user buffer from %x\n", Mdl));
- NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
+ NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
- TI_DbgPrint(DEBUG_TCP,
- ("Writing %d bytes to %x\n", SendLen, SendBuffer));
+ TI_DbgPrint(DEBUG_TCP,
+ ("Writing %d bytes to %x\n", SendLen, SendBuffer));
- TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
- TI_DbgPrint
+ TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
+ TI_DbgPrint
(DEBUG_TCP,
("Connection->SocketContext: %x\n",
Connection->SocketContext));
- Status = TCPTranslateError
- ( OskitTCPSend( Connection->SocketContext,
- SendBuffer,
- SendLen,
- &Sent,
- 0 ) );
+ Status = TCPTranslateError
+ ( OskitTCPSend( Connection->SocketContext,
+ SendBuffer,
+ SendLen,
+ &Sent,
+ 0 ) );
- TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
+ TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
- if( Status == STATUS_SUCCESS ) {
- TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n",
- Sent, Status));
-
- Complete( Bucket->Request.RequestContext,
- STATUS_SUCCESS, Sent );
- exFreePool( Bucket );
- } else if( Status == STATUS_PENDING ) {
- ExInterlockedInsertHeadList
- ( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock );
+ if( Status == STATUS_PENDING ) {
+ InsertHeadList( &Connection->SendRequest, &Bucket->Entry );
- break;
- } else {
- TI_DbgPrint(DEBUG_TCP,
- ("Completing Send request: %x %x\n",
- Bucket->Request, Status));
+ break;
+ } else {
+ TI_DbgPrint(DEBUG_TCP,
+ ("Completing Send request: %x %x\n",
+ Bucket->Request, Status));
- Complete( Bucket->Request.RequestContext, Status, 0 );
- exFreePool( Bucket );
+
+ Bucket->Status = Status;
+ Bucket->Information = (Status == STATUS_SUCCESS) ? Sent : 0;
+
+ InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
- }
- }
+ }
+ }
+ }
- Connection->SignalState = 0;
- Connection->Signalled = FALSE;
+ ReferenceObject(Connection);
+ if (ClientInfo.Unlocked)
+ {
+ UnlockObjectFromDpcLevel(Connection);
+ KeReleaseSpinLock(&ClientInfo.Lock, ClientInfo.OldIrql);
- }
+}
+ else
+ {
+ UnlockObject(Connection, Connection->OldIrql);
+ }
+
+ while ((Entry = ExInterlockedRemoveHeadList(&Connection->CompletionQueue,
+ &Connection->Lock)))
+ {
+ Bucket = CONTAINING_RECORD(Entry, TDI_BUCKET, Entry);
+ Complete = Bucket->Request.RequestNotifyObject;
- VOID DrainSignals() {
- PCONNECTION_ENDPOINT Connection;
- PLIST_ENTRY ListEntry;
+ Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
- while( (ListEntry = ExInterlockedRemoveHeadList(&SignalledConnectionsList,
- &SignalledConnectionsLock)) != NULL) {
- Connection = CONTAINING_RECORD( ListEntry, CONNECTION_ENDPOINT,
- SignalList );
- HandleSignalledConnection( Connection );
- }
- }
+ ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
+ }
+
+ if (!ClientInfo.Unlocked)
+ {
+ LockObject(Connection, &OldIrql);
+ }
+ else
+ {
+ KeAcquireSpinLock(&ClientInfo.Lock, &ClientInfo.OldIrql);
+ }
+ DereferenceObject(Connection);
+
+ /* If the socket is dead, remove the reference we added for oskit */
+ if (Connection->SignalState & SEL_FIN)
+ DereferenceObject(Connection);
+ }
+
+ VOID ConnectionFree(PVOID Object) {
+ PCONNECTION_ENDPOINT Connection = Object;
+ KIRQL OldIrql;
+
+ TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
+
+ TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
+ RemoveEntryList(&Connection->ListEntry);
+ TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
+
+ ExFreePoolWithTag( Connection, CONN_ENDPT_TAG );
+ }
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) {
PCONNECTION_ENDPOINT Connection =
- exAllocatePool(NonPagedPool, sizeof(CONNECTION_ENDPOINT));
+ ExAllocatePoolWithTag(NonPagedPool, sizeof(CONNECTION_ENDPOINT),
+ CONN_ENDPT_TAG);
if (!Connection)
return Connection;
RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));
/* Initialize spin lock that protects the connection endpoint file object */
- TcpipInitializeSpinLock(&Connection->Lock);
+ KeInitializeSpinLock(&Connection->Lock);
InitializeListHead(&Connection->ConnectRequest);
InitializeListHead(&Connection->ListenRequest);
InitializeListHead(&Connection->ReceiveRequest);
InitializeListHead(&Connection->SendRequest);
+ InitializeListHead(&Connection->CompletionQueue);
/* Save client context pointer */
Connection->ClientContext = ClientContext;
- return Connection;
- }
+ /* Add an extra reference for oskit */
+ Connection->RefCount = 2;
+ Connection->Free = ConnectionFree;
- VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) {
- TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
- exFreePool( Connection );
+ /* Add connection endpoint to global list */
+ ExInterlockedInsertTailList(&ConnectionEndpointListHead,
+ &Connection->ListEntry,
+ &ConnectionEndpointListLock);
+
+ return Connection;
}
NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
UINT Family, UINT Type, UINT Proto ) {
NTSTATUS Status;
+ KIRQL OldIrql;
- ASSERT_LOCKED(&TCPLock);
+ LockObject(Connection, &OldIrql);
TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, "
"Proto %d\n",
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
Connection->SocketContext));
+ UnlockObject(Connection, OldIrql);
+
return Status;
}
* This is the low level interface for receiving TCP data
*/
{
+ KIRQL OldIrql;
+
TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to oskit\n",
IPPacket->TotalSize,
IPPacket->HeaderSize));
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
+ KeAcquireSpinLock(&ClientInfo.Lock, &OldIrql);
+ ClientInfo.Unlocked = TRUE;
+ ClientInfo.OldIrql = OldIrql;
OskitTCPReceiveDatagram( IPPacket->Header,
IPPacket->TotalSize,
IPPacket->HeaderSize );
- DrainSignals();
-
- TcpipRecursiveMutexLeave( &TCPLock );
+ ClientInfo.Unlocked = FALSE;
+ KeReleaseSpinLock(&ClientInfo.Lock, OldIrql);
}
/* event.c */
void *data, OSK_PCHAR file, OSK_UINT line );
void TCPMemShutdown( void );
- int TCPSleep( void *ClientData, void *token, int priority, char *msg,
- int tmio );
-
- void TCPWakeup( void *ClientData, void *token );
-
OSKITTCP_EVENT_HANDLERS EventHandlers = {
NULL, /* Client Data */
TCPSocketState, /* SocketState */
TCPFindInterface, /* FindInterface */
TCPMalloc, /* Malloc */
TCPFree, /* Free */
- TCPSleep, /* Sleep */
- TCPWakeup /* Wakeup */
+ NULL, /* Sleep */
+ NULL, /* Wakeup */
};
static KEVENT TimerLoopEvent;
while ( 1 ) {
if (Next == NextFast) {
NextFast += 2;
- }
+ }
if (Next == NextSlow) {
NextSlow += 5;
}
PsTerminateSystemThread(Status);
}
- TcpipRecursiveMutexEnter( &TCPLock, TRUE );
TimerOskitTCP( Next == NextFast, Next == NextSlow );
- if (Next == NextSlow) {
- DrainSignals();
- }
- TcpipRecursiveMutexLeave( &TCPLock );
Current = Next;
if (10 <= Current) {
TimerThread, NULL);
}
-
NTSTATUS TCPStartup(VOID)
/*
* FUNCTION: Initializes the TCP subsystem
{
NTSTATUS Status;
- TcpipRecursiveMutexInit( &TCPLock );
- ExInitializeFastMutex( &SleepingThreadsLock );
- KeInitializeSpinLock( &SignalledConnectionsLock );
- InitializeListHead( &SleepingThreadsList );
- InitializeListHead( &SignalledConnectionsList );
Status = TCPMemStartup();
if ( ! NT_SUCCESS(Status) ) {
return Status;
return Status;
}
- TcpipRecursiveMutexEnter(&TCPLock, TRUE);
+ KeInitializeSpinLock(&ClientInfo.Lock);
+ ClientInfo.Unlocked = FALSE;
+
RegisterOskitTCPEventHandlers( &EventHandlers );
InitOskitTCP();
- TcpipRecursiveMutexLeave(&TCPLock);
/* Register this protocol with IP layer */
IPRegisterProtocol(IPPROTO_TCP, TCPReceive);
case 0: Status = STATUS_SUCCESS; break;
case OSK_EADDRNOTAVAIL: Status = STATUS_INVALID_ADDRESS; break;
case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break;
- case OSK_ECONNREFUSED:
- case OSK_ECONNRESET: Status = STATUS_REMOTE_NOT_LISTENING; break;
+ case OSK_ECONNREFUSED: Status = STATUS_REMOTE_NOT_LISTENING; break;
+ case OSK_ECONNRESET:
+ case OSK_ECONNABORTED: Status = STATUS_REMOTE_DISCONNECT; break;
case OSK_EWOULDBLOCK:
case OSK_EINPROGRESS: Status = STATUS_PENDING; break;
case OSK_EINVAL: Status = STATUS_INVALID_PARAMETER; break;
USHORT RemotePort;
PTDI_BUCKET Bucket;
PNEIGHBOR_CACHE_ENTRY NCE;
+ KIRQL OldIrql;
TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n"));
- ASSERT_LOCKED(&TCPLock);
-
Status = AddrBuildAddress
((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress,
&RemoteAddress,
return Status;
}
- if (!(NCE = RouteGetRouteToDestination(&RemoteAddress)))
- {
- return STATUS_NETWORK_UNREACHABLE;
- }
-
- if (Connection->State & SEL_FIN)
- {
- return STATUS_REMOTE_DISCONNECT;
- }
-
/* Freed in TCPSocketState */
TI_DbgPrint(DEBUG_TCP,
("Connecting to address %x:%x\n",
AddressToConnect.sin_family = AF_INET;
AddressToBind = AddressToConnect;
- AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
+
+ LockObject(Connection, &OldIrql);
+
+ if (!Connection->AddressFile)
+ {
+ UnlockObject(Connection, OldIrql);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (AddrIsUnspecified(&Connection->AddressFile->Address))
+ {
+ if (!(NCE = RouteGetRouteToDestination(&RemoteAddress)))
+ {
+ UnlockObject(Connection, OldIrql);
+ return STATUS_NETWORK_UNREACHABLE;
+ }
+
+ AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
+ }
+ else
+ {
+ AddressToBind.sin_addr.s_addr = Connection->AddressFile->Address.Address.IPv4Address;
+ }
Status = TCPTranslateError
( OskitTCPBind( Connection->SocketContext,
Status = TCPTranslateError
( OskitTCPConnect( Connection->SocketContext,
- Connection,
&AddressToConnect,
sizeof(AddressToConnect) ) );
if (Status == STATUS_PENDING)
{
- Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
- if( !Bucket ) return STATUS_NO_MEMORY;
+ Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG );
+ if( !Bucket )
+ {
+ UnlockObject(Connection, OldIrql);
+ return STATUS_NO_MEMORY;
+ }
Bucket->Request.RequestNotifyObject = (PVOID)Complete;
Bucket->Request.RequestContext = Context;
-
+
- IoMarkIrpPending((PIRP)Context);
-
- ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, &Connection->Lock );
+ InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
}
}
+ UnlockObject(Connection, OldIrql);
+
return Status;
}
PTDI_CONNECTION_INFORMATION ReturnInfo,
PTCP_COMPLETION_ROUTINE Complete,
PVOID Context ) {
- NTSTATUS Status;
-
- ASSERT_LOCKED(&TCPLock);
+ NTSTATUS Status = STATUS_INVALID_PARAMETER;
+ KIRQL OldIrql;
TI_DbgPrint(DEBUG_TCP,("started\n"));
- switch( Flags & (TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE) ) {
- case 0:
- case TDI_DISCONNECT_ABORT:
- Flags = 0;
- break;
+ LockObject(Connection, &OldIrql);
- case TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE:
- Flags = 2;
- break;
+ if (Flags & TDI_DISCONNECT_RELEASE)
+ Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext));
- case TDI_DISCONNECT_RELEASE:
- Flags = 1;
- break;
- }
+ if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
+ Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD));
- Status = TCPTranslateError
- ( OskitTCPShutdown( Connection->SocketContext, Flags ) );
+ UnlockObject(Connection, OldIrql);
TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status));
}
NTSTATUS TCPClose
- ( PCONNECTION_ENDPOINT Connection ) {
+ ( PCONNECTION_ENDPOINT Connection )
+ {
+ KIRQL OldIrql;
NTSTATUS Status;
+ PVOID Socket;
- TI_DbgPrint(DEBUG_TCP,("TCPClose started\n"));
+ /* We don't rely on SocketContext == NULL for socket
+ * closure anymore but we still need it to determine
+ * if we caused the closure
+ */
+ LockObject(Connection, &OldIrql);
+ Socket = Connection->SocketContext;
+ Connection->SocketContext = NULL;
- ASSERT_LOCKED(&TCPLock);
+ /* We need to close here otherwise oskit will never indicate
+ * SEL_FIN and we will never fully close the connection
+ */
+ Status = TCPTranslateError( OskitTCPClose( Socket ) );
- /* Make our code remove all pending IRPs */
- Connection->State |= SEL_FIN;
- DrainSignals();
+ if (!NT_SUCCESS(Status))
+ {
+ Connection->SocketContext = Socket;
+ UnlockObject(Connection, OldIrql);
+ return Status;
+ }
- Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) );
- if (Status == STATUS_SUCCESS)
- Connection->SocketContext = NULL;
+ if (Connection->AddressFile)
+ DereferenceObject(Connection->AddressFile);
- TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status));
+ UnlockObject(Connection, OldIrql);
+
+ DereferenceObject(Connection);
return Status;
}
UINT DataLen, Received = 0;
NTSTATUS Status;
PTDI_BUCKET Bucket;
+ KIRQL OldIrql;
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
ReceiveLength, Connection->SocketContext));
- ASSERT_LOCKED(&TCPLock);
-
- ASSERT_KM_POINTER(Connection->SocketContext);
-
- /* Closing */
- if (Connection->State & SEL_FIN)
- {
- *BytesReceived = 0;
- return STATUS_REMOTE_DISCONNECT;
- }
-
NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
+ LockObject(Connection, &OldIrql);
+
Status = TCPTranslateError
( OskitTCPRecv
( Connection->SocketContext,
/* Keep this request around ... there was no data yet */
if( Status == STATUS_PENDING ) {
/* Freed in TCPSocketState */
- Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
+ Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG );
if( !Bucket ) {
TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n"));
+ UnlockObject(Connection, OldIrql);
return STATUS_NO_MEMORY;
}
Bucket->Request.RequestContext = Context;
*BytesReceived = 0;
- IoMarkIrpPending((PIRP)Context);
-
- ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock );
+ InsertTailList( &Connection->ReceiveRequest, &Bucket->Entry );
TI_DbgPrint(DEBUG_TCP,("Queued read irp\n"));
} else {
TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received));
*BytesReceived = Received;
}
+ UnlockObject(Connection, OldIrql);
+
TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
return Status;
UINT Sent = 0;
NTSTATUS Status;
PTDI_BUCKET Bucket;
+ KIRQL OldIrql;
- ASSERT_LOCKED(&TCPLock);
+ LockObject(Connection, &OldIrql);
TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
SendLength, Connection->SocketContext));
- ASSERT_KM_POINTER(Connection->SocketContext);
-
TI_DbgPrint(DEBUG_TCP,("Connection = %x\n", Connection));
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n",
Connection->SocketContext));
- /* Closing */
- if (Connection->State & SEL_FIN)
- {
- *BytesSent = 0;
- return STATUS_REMOTE_DISCONNECT;
- }
-
Status = TCPTranslateError
( OskitTCPSend( Connection->SocketContext,
(OSK_PCHAR)BufferData, SendLength,
/* Keep this request around ... there was no data yet */
if( Status == STATUS_PENDING ) {
/* Freed in TCPSocketState */
- Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) );
+ Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG );
if( !Bucket ) {
+ UnlockObject(Connection, OldIrql);
TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n"));
return STATUS_NO_MEMORY;
}
Bucket->Request.RequestNotifyObject = Complete;
Bucket->Request.RequestContext = Context;
*BytesSent = 0;
-
+
- IoMarkIrpPending((PIRP)Context);
-
- ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock );
+ InsertTailList( &Connection->SendRequest, &Bucket->Entry );
TI_DbgPrint(DEBUG_TCP,("Queued write irp\n"));
} else {
TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent));
*BytesSent = Sent;
}
-
+
+ UnlockObject(Connection, OldIrql);
+
TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
return Status;
}
- VOID TCPTimeout(VOID) {
- /* Now handled by TimerThread */
- }
-
UINT TCPAllocatePort( UINT HintPort ) {
if( HintPort ) {
if( AllocatePort( &TCPPorts, HintPort ) ) return HintPort;
OSK_UI16 LocalPort, RemotePort;
PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address;
NTSTATUS Status;
+ KIRQL OldIrql;
- ASSERT_LOCKED(&TCPLock);
+ LockObject(Connection, &OldIrql);
Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext,
&LocalAddress, &LocalPort,
&RemoteAddress, &RemotePort));
+
+ UnlockObject(Connection, OldIrql);
+
if (!NT_SUCCESS(Status))
return Status;
return Status;
}
- VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) {
+ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) {
PLIST_ENTRY Entry;
PLIST_ENTRY ListHead[4];
KIRQL OldIrql;
PTDI_BUCKET Bucket;
UINT i = 0;
+ BOOLEAN Found = FALSE;
ListHead[0] = &Endpoint->SendRequest;
ListHead[1] = &Endpoint->ReceiveRequest;
ListHead[2] = &Endpoint->ConnectRequest;
ListHead[3] = &Endpoint->ListenRequest;
- TcpipAcquireSpinLock( &Endpoint->Lock, &OldIrql );
+ LockObject(Endpoint, &OldIrql);
for( i = 0; i < 4; i++ )
{
if( Bucket->Request.RequestContext == Irp )
{
RemoveEntryList( &Bucket->Entry );
- exFreePool( Bucket );
+ ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG );
+ Found = TRUE;
break;
}
}
}
- TcpipReleaseSpinLock( &Endpoint->Lock, OldIrql );
+ UnlockObject(Endpoint, OldIrql);
+
+ return Found;
}
/* EOF */
--- /dev/null
-<module name="tdilib" type="staticlibrary">
+ <?xml version="1.0"?>
+ <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
-</module>
++<!-- module name="tdilib" type="staticlibrary">
+ <include base="iphlpapi">.</include>
+ <include base="tdilib">.</include>
+ <library>ntdll</library>
+ <file>enum.c</file>
+ <file>handle.c</file>
++</module -->
extern PULONG KiInterruptTemplateDispatch;
extern PULONG KiInterruptTemplate2ndDispatch;
extern ULONG KiUnexpectedEntrySize;
- extern UCHAR P0BootStack[];
- extern UCHAR KiDoubleFaultStack[];
+ extern ULONG_PTR KiDoubleFaultStack;
extern EX_PUSH_LOCK KernelAddressSpaceLock;
extern ULONG KiMaximumDpcQueueDepth;
extern ULONG KiMinimumDpcRate;
extern ULONG_PTR KiBugCheckData[5];
extern ULONG KiFreezeFlag;
extern ULONG KiDPCTimeout;
+ extern PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch;
/* MACROS *************************************************************************/
IN PVOID SystemArgument2
);
- ULONG
- NTAPI
- KiComputeTimerTableIndex(
- IN LONGLONG TimeValue
- );
-
ULONG
NTAPI
KeSetProcess(
VOID
NTAPI
- KiSystemStartupReal(
+ KiSystemStartup(
IN PLOADER_PARAMETER_BLOCK LoaderBlock
);
VOID
NTAPI
KeRosDumpStackFrames(
- PULONG Frame,
+ PULONG_PTR Frame,
ULONG FrameCount
);
VOID
);
+ NTSTATUS
+ NTAPI
+ KiRaiseException(
+ IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PCONTEXT Context,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PKTRAP_FRAME TrapFrame,
+ IN BOOLEAN SearchFrames
+ );
+
+ NTSTATUS
+ NTAPI
+ KiContinue(
+ IN PCONTEXT Context,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PKTRAP_FRAME TrapFrame
+ );
+
+ VOID
+ FASTCALL
+ KiServiceExit(
+ IN PKTRAP_FRAME TrapFrame,
+ IN NTSTATUS Status
+ );
+
+ VOID
+ FASTCALL
+ KiServiceExit2(
+ IN PKTRAP_FRAME TrapFrame
+ );
+
#ifndef HAL_INTERRUPT_SUPPORT_IN_C
VOID
NTAPI
);
VOID
+ FASTCALL
KiIdleLoop(
VOID
);
+PVOID
+NTAPI
+KiPcToFileHeader(IN PVOID Eip,
+ OUT PLDR_DATA_TABLE_ENTRY *LdrEntry,
+ IN BOOLEAN DriversOnly,
+ OUT PBOOLEAN InKernel);
+
+PVOID
+NTAPI
+KiRosPcToUserFileHeader(IN PVOID Eip,
+ OUT PLDR_DATA_TABLE_ENTRY *LdrEntry);
+
#include "ke_x.h"
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */
}
#ifndef CONFIG_SMP
-//
-// Spinlock Acquire at IRQL >= DISPATCH_LEVEL
-//
-FORCEINLINE
-VOID
-KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
-{
- /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
- UNREFERENCED_PARAMETER(SpinLock);
-}
-
-//
-// Spinlock Release at IRQL >= DISPATCH_LEVEL
-//
-FORCEINLINE
-VOID
-KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
-{
- /* On UP builds, spinlocks don't exist at IRQL >= DISPATCH */
- UNREFERENCED_PARAMETER(SpinLock);
-}
//
// This routine protects against multiple CPU acquires, it's meaningless on UP.
#else
-//
-// Spinlock Acquisition at IRQL >= DISPATCH_LEVEL
-//
-FORCEINLINE
-VOID
-KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
-{
- /* Make sure that we don't own the lock already */
- if (((KSPIN_LOCK)KeGetCurrentThread() | 1) == *SpinLock)
- {
- /* We do, bugcheck! */
- KeBugCheckEx(SPIN_LOCK_ALREADY_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0);
- }
-
- /* Start acquire loop */
- for (;;)
- {
- /* Try to acquire it */
- if (InterlockedBitTestAndSet((PLONG)SpinLock, 0))
- {
- /* Value changed... wait until it's unlocked */
- while (*(volatile KSPIN_LOCK *)SpinLock == 1)
- {
-#if DBG
- /* On debug builds, we use a much slower but useful routine */
- //Kii386SpinOnSpinLock(SpinLock, 5);
-
- /* FIXME: Do normal yield for now */
- YieldProcessor();
-#else
- /* Otherwise, just yield and keep looping */
- YieldProcessor();
-#endif
- }
- }
- else
- {
-#if DBG
- /* On debug builds, we OR in the KTHREAD */
- *SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1;
-#endif
- /* All is well, break out */
- break;
- }
- }
-}
-
-//
-// Spinlock Release at IRQL >= DISPATCH_LEVEL
-//
-FORCEINLINE
-VOID
-KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
-{
-#if DBG
- /* Make sure that the threads match */
- if (((KSPIN_LOCK)KeGetCurrentThread() | 1) != *SpinLock)
- {
- /* They don't, bugcheck */
- KeBugCheckEx(SPIN_LOCK_NOT_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0);
- }
-#endif
- /* Clear the lock */
- InterlockedAnd((PLONG)SpinLock, 0);
-}
-
FORCEINLINE
VOID
KiAcquireDispatcherObject(IN DISPATCHER_HEADER* Object)
return STATUS_WAIT_0;
}
+ ULONG
+ FORCEINLINE
+ KiComputeTimerTableIndex(IN ULONGLONG DueTime)
+ {
+ return (DueTime / KeMaximumIncrement) & (TIMER_TABLE_SIZE - 1);
+ }
+
//
// Called from KiCompleteTimer, KiInsertTreeTimer, KeSetSystemTime
// to remove timer entries
#if defined(_PPC_)
#include <ppcmmu/mmu.h>
#define KERNEL_RVA(x) RVA(x,0x80800000)
-#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)x + KernelBase) >> PAGE_SHIFT)
+#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)(x) + KernelBase) >> PAGE_SHIFT)
#else
#define KERNEL_RVA(x) RVA(x,KSEG0_BASE)
-#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)x &~ KSEG0_BASE) >> PAGE_SHIFT)
+#define KERNEL_DESCRIPTOR_PAGE(x) (((ULONG_PTR)(x) & ~KSEG0_BASE) >> PAGE_SHIFT)
#endif
typedef struct _BIOS_MEMORY_DESCRIPTOR
/* GLOBALS *******************************************************************/
+/* Function pointer for early debug prints */
+ULONG (*FrLdrDbgPrint)(const char *Format, ...);
+
/* FreeLDR Loader Data */
PROS_LOADER_PARAMETER_BLOCK KeRosLoaderBlock;
ADDRESS_RANGE KeMemoryMap[64];
VOID
NTAPI
KiRosFixupComponentTree(IN PCONFIGURATION_COMPONENT_DATA p,
- IN ULONG i)
+ IN ULONG_PTR i)
{
PCONFIGURATION_COMPONENT pp;
/* Build entries for ReactOS memory ranges, which uses ARC Descriptors */
KiRosBuildOsMemoryMap();
-#if defined(_X86_)
+#if defined(_X86_) || defined(_M_AMD64)
/* Build entries for the reserved map, which uses ARC Descriptors */
KiRosBuildReservedMemoryMap();
#endif
/* Now mark the remainder of the FreeLDR 6MB area as "in use" */
KiRosAllocateNtDescriptor(LoaderMemoryData,
KERNEL_DESCRIPTOR_PAGE(RosEntry->ModEnd),
- KERNEL_DESCRIPTOR_PAGE((0x80800000 + 0x600000)) -
+ KERNEL_DESCRIPTOR_PAGE((RosLoaderBlock->KernelBase + 0x600000)) -
KERNEL_DESCRIPTOR_PAGE(RosEntry->ModEnd),
0,
&Base);
LoaderBlock->Extension->MajorVersion = 5;
LoaderBlock->Extension->MinorVersion = 2;
+
+// FIXME FIXME FIXME NOW!!!!
+
/* FreeLDR hackllocates 1536 static pages for the initial boot images */
LoaderBlock->Extension->LoaderPagesSpanned = 1536 * PAGE_SIZE;
KiSetupSyscallHandler();
VOID
- FASTCALL
- KiRosPrepareForSystemStartup(IN ULONG Dummy,
- IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
+ NTAPI
+ KiRosPrepareForSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
{
PLOADER_PARAMETER_BLOCK NtLoaderBlock;
ULONG size, i = 0, *ent;
/* Save pointer to ROS Block */
KeRosLoaderBlock = LoaderBlock;
+ /* Get debugging function */
+ FrLdrDbgPrint = LoaderBlock->FrLdrDbgPrint;
+
/* Save memory manager data */
KeMemoryMapRangeCount = 0;
if (LoaderBlock->Flags & MB_FLAGS_MMAP_INFO)
{
/* We have a memory map from the nice BIOS */
- ent = ((PULONG)(LoaderBlock->MmapAddr - sizeof(ULONG)));
+ ent = ((PULONG)(LoaderBlock->MmapAddr - sizeof(ULONG))); // FIXME: this is ugly
size = *ent;
i = 0;
/* Save data */
LoaderBlock->MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
- LoaderBlock->MmapAddr = (ULONG)KeMemoryMap;
+ LoaderBlock->MmapAddr = (ULONG_PTR)KeMemoryMap;
}
else
{
/* Nothing from BIOS */
LoaderBlock->MmapLength = 0;
- LoaderBlock->MmapAddr = (ULONG)KeMemoryMap;
+ LoaderBlock->MmapAddr = (ULONG_PTR)KeMemoryMap;
}
/* Convert the loader block */
#endif
/* Do general System Startup */
- KiSystemStartupReal(NtLoaderBlock);
+ KiSystemStartup(NtLoaderBlock);
}
Prcb->VendorString[sizeof(Prcb->VendorString) - sizeof(CHAR)] = ANSI_NULL;
/* Now check the CPU Type */
- if (!strcmp(Prcb->VendorString, CmpIntelID))
+ if (!strcmp((PCHAR)Prcb->VendorString, CmpIntelID))
{
return CPU_INTEL;
}
- else if (!strcmp(Prcb->VendorString, CmpAmdID))
+ else if (!strcmp((PCHAR)Prcb->VendorString, CmpAmdID))
{
return CPU_AMD;
}
- else if (!strcmp(Prcb->VendorString, CmpCyrixID))
+ else if (!strcmp((PCHAR)Prcb->VendorString, CmpCyrixID))
{
DPRINT1("Cyrix CPU support not fully tested!\n");
return CPU_CYRIX;
}
- else if (!strcmp(Prcb->VendorString, CmpTransmetaID))
+ else if (!strcmp((PCHAR)Prcb->VendorString, CmpTransmetaID))
{
DPRINT1("Transmeta CPU support not fully tested!\n");
return CPU_TRANSMETA;
}
- else if (!strcmp(Prcb->VendorString, CmpCentaurID))
+ else if (!strcmp((PCHAR)Prcb->VendorString, CmpCentaurID))
{
DPRINT1("Centaur CPU support not fully tested!\n");
return CPU_CENTAUR;
}
- else if (!strcmp(Prcb->VendorString, CmpRiseID))
+ else if (!strcmp((PCHAR)Prcb->VendorString, CmpRiseID))
{
DPRINT1("Rise CPU support not fully tested!\n");
return CPU_RISE;
Tss = (PKTSS)KiDoubleFaultTSS;
KiInitializeTSS(Tss);
Tss->CR3 = __readcr3();
- Tss->Esp0 = PtrToUlong(KiDoubleFaultStack);
- Tss->Esp = PtrToUlong(KiDoubleFaultStack);
+ Tss->Esp0 = KiDoubleFaultStack;
+ Tss->Esp = KiDoubleFaultStack;
Tss->Eip = PtrToUlong(KiTrap08);
Tss->Cs = KGDT_R0_CODE;
Tss->Fs = KGDT_R0_PCR;
Tss = (PKTSS)KiNMITSS;
KiInitializeTSS(Tss);
Tss->CR3 = __readcr3();
- Tss->Esp0 = PtrToUlong(KiDoubleFaultStack);
- Tss->Esp = PtrToUlong(KiDoubleFaultStack);
+ Tss->Esp0 = KiDoubleFaultStack;
+ Tss->Esp = KiDoubleFaultStack;
Tss->Eip = PtrToUlong(KiTrap02);
Tss->Cs = KGDT_R0_CODE;
Tss->Fs = KGDT_R0_PCR;
KiSaveProcessorControlState(&Prcb->ProcessorState);
}
+ BOOLEAN
+ NTAPI
+ KiIsNpxPresent(VOID)
+ {
+ ULONG Cr0;
+ USHORT Magic;
+
+ /* Set magic */
+ Magic = 0xFFFF;
+
+ /* Read CR0 and mask out FPU flags */
+ Cr0 = __readcr0() & ~(CR0_MP | CR0_TS | CR0_EM | CR0_ET);
+
+ /* Store on FPU stack */
+ asm volatile ("fninit;" "fnstsw %0" : "+m"(Magic));
+
+ /* Magic should now be cleared */
+ if (Magic & 0xFF)
+ {
+ /* You don't have an FPU -- enable emulation for now */
+ __writecr0(Cr0 | CR0_EM | CR0_TS);
+ return FALSE;
+ }
+
+ /* You have an FPU, enable it */
+ Cr0 |= CR0_ET;
+
+ /* Enable INT 16 on 486 and higher */
+ if (KeGetCurrentPrcb()->CpuType >= 3) Cr0 |= CR0_NE;
+
+ /* Set FPU state */
+ __writecr0(Cr0 | CR0_EM | CR0_TS);
+ return TRUE;
+ }
+
+ BOOLEAN
+ NTAPI
+ KiIsNpxErrataPresent(VOID)
+ {
+ BOOLEAN ErrataPresent;
+ ULONG Cr0;
+ volatile double Value1, Value2;
+
+ /* Disable interrupts */
+ _disable();
+
+ /* Read CR0 and remove FPU flags */
+ Cr0 = __readcr0();
+ __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
+
+ /* Initialize FPU state */
+ asm volatile ("fninit");
+
+ /* Multiply the magic values and divide, we should get the result back */
+ Value1 = 4195835.0;
+ Value2 = 3145727.0;
+ ErrataPresent = (Value1 * Value2 / 3145727.0) != 4195835.0;
+
+ /* Restore CR0 */
+ __writecr0(Cr0);
+
+ /* Enable interrupts */
+ _enable();
+
+ /* Return if there's an errata */
+ return ErrataPresent;
+ }
+
+ NTAPI
+ VOID
+ KiFlushNPXState(IN PFLOATING_SAVE_AREA SaveArea)
+ {
+ ULONG EFlags, Cr0;
+ PKTHREAD Thread, NpxThread;
+ PFX_SAVE_AREA FxSaveArea;
+
+ /* Save volatiles and disable interrupts */
+ EFlags = __readeflags();
+ _disable();
+
+ /* Save the PCR and get the current thread */
+ Thread = KeGetCurrentThread();
+
+ /* Check if we're already loaded */
+ if (Thread->NpxState != NPX_STATE_LOADED)
+ {
+ /* If there's nothing to load, quit */
+ if (!SaveArea) return;
+
+ /* Need FXSR support for this */
+ ASSERT(KeI386FxsrPresent == TRUE);
+
+ /* Check for sane CR0 */
+ Cr0 = __readcr0();
+ if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
+ {
+ /* Mask out FPU flags */
+ __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
+ }
+
+ /* Get the NPX thread and check its FPU state */
+ NpxThread = KeGetCurrentPrcb()->NpxThread;
+ if ((NpxThread) && (NpxThread->NpxState == NPX_STATE_LOADED))
+ {
+ /* Get the FX frame and store the state there */
+ FxSaveArea = KiGetThreadNpxArea(NpxThread);
+ Ke386FxSave(FxSaveArea);
+
+ /* NPX thread has lost its state */
+ NpxThread->NpxState = NPX_STATE_NOT_LOADED;
+ }
+
+ /* Now load NPX state from the NPX area */
+ FxSaveArea = KiGetThreadNpxArea(Thread);
+ Ke386FxStore(FxSaveArea);
+ }
+ else
+ {
+ /* Check for sane CR0 */
+ Cr0 = __readcr0();
+ if (Cr0 & (CR0_MP | CR0_TS | CR0_EM))
+ {
+ /* Mask out FPU flags */
+ __writecr0(Cr0 & ~(CR0_MP | CR0_TS | CR0_EM));
+ }
+
+ /* Get FX frame */
+ FxSaveArea = KiGetThreadNpxArea(Thread);
+ Thread->NpxState = NPX_STATE_NOT_LOADED;
+
+ /* Save state if supported by CPU */
+ if (KeI386FxsrPresent) Ke386FxSave(FxSaveArea);
+ }
+
+ /* Now save the FN state wherever it was requested */
+ if (SaveArea) Ke386FnSave(SaveArea);
+
+ /* Clear NPX thread */
+ KeGetCurrentPrcb()->NpxThread = NULL;
+
+ /* Add the CR0 from the NPX frame */
+ Cr0 |= NPX_STATE_NOT_LOADED;
+ Cr0 |= FxSaveArea->Cr0NpxState;
+ __writecr0(Cr0);
+
+ /* Restore interrupt state */
+ __writeeflags(EFlags);
+ }
+
/* PUBLIC FUNCTIONS **********************************************************/
/*
#define Running 2
#define WrDispatchInt 0x1F
- Dividend: .float 4195835.0
- Divisor: .float 3145727.0
- Result1: .float 0
- Result2: .float 0
-
/* FUNCTIONS ****************************************************************/
- .globl _KiIsNpxErrataPresent@0
- .func KiIsNpxErrataPresent@0
- _KiIsNpxErrataPresent@0:
-
- /* Disable interrupts */
- cli
-
- /* Get CR0 and mask out FPU flags */
- mov eax, cr0
- mov ecx, eax
- and eax, ~(CR0_MP + CR0_TS + CR0_EM)
- mov cr0, eax
-
- /* Initialize the FPU */
- fninit
-
- /* Do the divison and inverse multiplication */
- fld qword ptr Dividend
- fstp qword ptr Result1
- fld qword ptr Divisor
- fstp qword ptr Result2
- fld qword ptr Result1
- fdiv qword ptr Result2
- fmul qword ptr Result2
-
- /* Do the compare and check flags */
- fcomp qword ptr Result1
- fstsw ax
- sahf
-
- /* Restore CR0 and interrupts */
- mov cr0, ecx
- sti
-
- /* Return errata status */
- xor eax, eax
- jz NoErrata
- inc eax
-
- NoErrata:
- ret
- .endfunc
-
- .globl _KiIsNpxPresent@0
- .func KiIsNpxPresent@0
- _KiIsNpxPresent@0:
-
- /* Save stack */
- push ebp
-
- /* Get CR0 and mask out FPU flags */
- mov eax, cr0
- and eax, ~(CR0_MP + CR0_TS + CR0_EM + CR0_ET)
-
- /* Initialize the FPU and assume FALSE for return */
- xor edx, edx
- fninit
-
- /* Save magic value on stack */
- mov ecx, 0x42424242
- push ecx
-
- /* Setup stack for FPU store */
- mov ebp ,esp
- fnstsw [ebp]
-
- /* Now check if our magic got cleared */
- cmp byte ptr [ebp], 0
- jnz NoFpu
-
- /* Enable FPU, set return to TRUE */
- or eax, CR0_ET
- mov edx, 1
-
- /* If this is a 486 or higher, enable INT 16 as well */
- cmp dword ptr fs:KPCR_PRCB_CPU_TYPE, 3
- jbe NoFpu
- or eax, CR0_NE
-
- NoFpu:
- /* Set emulation enabled during the first boot phase and set the CR0 */
- or eax, (CR0_EM + CR0_TS)
- mov cr0, eax
-
- /* Restore stack */
- pop eax
- pop ebp
-
- /* Return true or false */
- mov eax, edx
- ret
- .endfunc
-
- .globl _KiFlushNPXState@4
- .func KiFlushNPXState@4
- _KiFlushNPXState@4:
-
- /* Save volatiles and disable interrupts */
- push esi
- push edi
- push ebx
- pushfd
- cli
-
- /* Save the PCR and get the current thread */
- mov edi, fs:[KPCR_SELF]
- mov esi, [edi+KPCR_CURRENT_THREAD]
-
- /* Check if we're already loaded */
- cmp byte ptr [esi+KTHREAD_NPX_STATE], NPX_STATE_LOADED
- je IsValid
-
- /* Check if we're supposed to get it */
- cmp dword ptr [esp+20], 0
- je Return
-
- #if DBG
- /* Assert Fxsr support */
- test byte ptr _KeI386FxsrPresent, 1
- jnz AssertOk
- int 3
- AssertOk:
- #endif
-
- /* Get CR0 and test if it's valid */
- mov ebx, cr0
- test bl, CR0_MP + CR0_TS + CR0_EM
- jz Cr0OK
-
- /* Enable fnsave to work */
- and ebx, ~(CR0_MP + CR0_TS + CR0_EM)
- mov cr0, ebx
-
- Cr0OK:
- /* Check if we are the NPX Thread */
- mov eax, [edi+KPCR_NPX_THREAD]
- or eax, eax
- jz DontSave
-
- /* Check if it's not loaded */
- cmp byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
- jnz DontSave
-
- #if DBG
- /* We are the NPX Thread with an unloaded NPX State... this isn't normal! */
- int 3
- #endif
-
- /* Save the NPX State */
- mov ecx, [eax+KTHREAD_INITIAL_STACK]
- sub ecx, NPX_FRAME_LENGTH
- fxsave [ecx]
- mov byte ptr [eax+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
-
- DontSave:
- /* Load the NPX State */
- mov ecx, [esi+KTHREAD_INITIAL_STACK]
- sub ecx, NPX_FRAME_LENGTH
- fxrstor [ecx]
-
- /* Get the CR0 state and destination */
- mov edx, [ecx+FN_CR0_NPX_STATE]
- mov ecx, [esp+20]
- jmp DoneLoad
-
- IsValid:
- /* We already have a valid state, flush it */
- mov ebx, cr0
- test bl, CR0_MP + CR0_TS + CR0_EM
- jz Cr0OK2
-
- /* Enable fnsave to work */
- and ebx, ~(CR0_MP + CR0_TS + CR0_EM)
- mov cr0, ebx
-
- Cr0OK2:
- /* Get the kernel stack */
- mov ecx, [esi+KTHREAD_INITIAL_STACK]
- test byte ptr _KeI386FxsrPresent, 1
- lea ecx, [ecx-NPX_FRAME_LENGTH]
-
- /* Set the NPX State */
- mov byte ptr [esi+KTHREAD_NPX_STATE], NPX_STATE_NOT_LOADED
-
- /* Get Cr0 */
- mov edx, [ecx+FN_CR0_NPX_STATE]
- jz DoneLoad
-
- /* Save the FX State */
- fxsave [ecx]
-
- /* Check if we also have to save it in the parameter */
- mov ecx, [esp+20]
- jecxz NoSave
-
- DoneLoad:
- /* Save the Fn state in the parameter we got */
- fnsave [ecx]
- fwait
-
- NoSave:
- /* Clear eax */
- xor eax, eax
-
- /* Add NPX State */
- or ebx, NPX_STATE_NOT_LOADED
-
- /* Clear the NPX thread */
- mov [edi+KPCR_NPX_THREAD], eax
-
- /* Add saved CR0 into NPX State, and set it */
- or ebx, edx
- mov cr0, ebx
-
- /* Re-enable interrupts and return */
- Return:
- popf
- pop ebx
- pop edi
- pop esi
- ret 4
-
- .endfunc
-
- /*++
- * KiThreadStartup
- *
- * The KiThreadStartup routine is the beginning of any thread.
- *
- * Params:
- * SystemRoutine - Pointer to the System Startup Routine. Either
- * PspUserThreadStartup or PspSystemThreadStartup
- *
- * StartRoutine - For Kernel Threads only, specifies the starting execution
- * point of the new thread.
- *
- * StartContext - For Kernel Threads only, specifies a pointer to variable
- * context data to be sent to the StartRoutine above.
- *
- * UserThread - Indicates whether or not this is a user thread. This tells
- * us if the thread has a context or not.
- *
- * TrapFrame - Pointer to the KTHREAD to which the caller wishes to
- * switch from.
- *
- * Returns:
- * Should never return for a system thread. Returns through the System Call
- * Exit Dispatcher for a user thread.
- *
- * Remarks:
- * If a return from a system thread is detected, a bug check will occur.
- *
- *--*/
- .func KiThreadStartup@156
- .globl _KiThreadStartup@156
- _KiThreadStartup@156:
-
- /*
- * Clear all the non-volatile registers, so the thread won't be tempted to
- * expect any static data (like some badly coded usermode/win9x apps do)
- */
- xor ebx, ebx
- xor esi, esi
- xor edi, edi
- xor ebp, ebp
-
- /* It's now safe to go to APC */
- mov ecx, APC_LEVEL
- call @KfLowerIrql@4
-
- /*
- * Call the System Routine which is right on our stack now.
- * After we pop the pointer, the Start Routine/Context will be on the
- * stack, as parameters to the System Routine
- */
- pop eax
- call eax
-
- /* The thread returned... was it a user-thread? */
- pop ecx
- or ecx, ecx
- jz BadThread
-
- /* Yes it was, set our trapframe for the System Call Exit Dispatcher */
- mov ebp, esp
-
- /* Exit back to user-mode */
- jmp _KiServiceExit2
-
- BadThread:
-
- /* A system thread returned...this is very bad! */
- int 3
- .endfunc
-
/*++
- * KiSwapContextInternal
+ * KiSwapContextInternal
*
+ * \brief
* The KiSwapContextInternal routine switches context to another thread.
*
+ * BOOLEAN USERCALL KiSwapContextInternal();
+ *
* Params:
* ESI - Pointer to the KTHREAD to which the caller wishes to
* switch to.
* EDI - Pointer to the KTHREAD to which the caller wishes to
* switch from.
*
- * Returns:
- * None.
+ * \returns
+ * APC state.
*
- * Remarks:
+ * \remarks
* Absolutely all registers except ESP can be trampled here for maximum code flexibility.
*
*--*/
#endif
.endfunc
-/*++
- * KiSwapContext
+/**
+ * KiSwapContext
*
+ * \brief
* The KiSwapContext routine switches context to another thread.
*
- * Params:
- * TargetThread - Pointer to the KTHREAD to which the caller wishes to
- * switch to.
+ * BOOLEAN FASTCALL
+ * KiSwapContext(PKTHREAD CurrentThread, PKTHREAD TargetThread);
+ *
+ * \param CurrentThread
+ * Pointer to the KTHREAD of the current thread.
+ *
+ * \param TargetThread
+ * Pointer to the KTHREAD to which the caller wishes to switch to.
*
- * Returns:
+ * \returns
* The WaitStatus of the Target Thread.
*
- * Remarks:
+ * \remarks
* This is a wrapper around KiSwapContextInternal which will save all the
* non-volatile registers so that the Internal function can use all of
* them. It will also save the old current thread and set the new one.
#endif
.endfunc
- .globl _KiSwapProcess@8
- .func KiSwapProcess@8
- _KiSwapProcess@8:
-
- /* Get process pointers */
- mov edx, [esp+4]
- mov eax, [esp+8]
-
- #ifdef CONFIG_SMP
- /* Update active processors */
- mov ecx, fs:[KPCR_SET_MEMBER]
- lock xor [edx+KPROCESS_ACTIVE_PROCESSORS], ecx
- lock xor [eax+KPROCESS_ACTIVE_PROCESSORS], ecx
-
- /* Sanity check */
- #if DBG
- test [edx+KPROCESS_ACTIVE_PROCESSORS], ecx
- jz WrongCpu1
- test [eax+KPROCESS_ACTIVE_PROCESSORS], ecx
- jnz WrongCpu2
- #endif
- #endif
-
- /* Check if their LDTs changed */
- mov ecx, [edx+KPROCESS_LDT_DESCRIPTOR0]
- or ecx, [eax+KPROCESS_LDT_DESCRIPTOR0]
- jnz NewLdt
-
- /* Update CR3 */
- mov eax, [edx+KPROCESS_DIRECTORY_TABLE_BASE]
- mov cr3, eax
-
- /* Get the KTSS */
- mov ecx, fs:[KPCR_TSS]
-
- /* Clear GS on process swap */
- xor eax, eax
- mov gs, ax
-
- /* Update IOPM offset */
- mov ax, [edx+KPROCESS_IOPM_OFFSET]
- mov [ecx+KTSS_IOMAPBASE], ax
-
- /* Return */
- ret 8
-
- NewLdt:
- /* FIXME: TODO */
- int 3
-
- #if DBG
- WrongCpu1:
- int 3
- WrongCpu2:
- int 3
- #endif
- .endfunc
-
.globl _Ki386SetupAndExitToV86Mode@4
.func Ki386SetupAndExitToV86Mode@4
_Ki386SetupAndExitToV86Mode@4:
NTAPI
MiFreeContiguousMemory(IN PVOID BaseAddress)
{
- KIRQL OldIrql;
PFN_NUMBER PageFrameIndex, LastPage, PageCount;
PMMPFN Pfn1, StartPfn;
PAGED_CODE();
// Now get the PFN entry for this, and make sure it's the correct one
//
Pfn1 = MiGetPfnEntry(PageFrameIndex);
- if (Pfn1->u3.e1.StartOfAllocation == 0)
+ if ((!Pfn1) || (Pfn1->u3.e1.StartOfAllocation == 0))
{
//
// This probably means you did a free on an address that was in between
//
MmUnmapIoSpace(BaseAddress, PageCount << PAGE_SHIFT);
- //
- // Lock the PFN database
- //
- OldIrql = KeAcquireQueuedSpinLock(LockQueuePfnLock);
-
//
// Loop all the pages
//
//
MmReleasePageMemoryConsumer(MC_NPPOOL, PageFrameIndex);
} while (++PageFrameIndex < LastPage);
-
- //
- // Release the PFN lock
- //
- KeReleaseQueuedSpinLock(LockQueuePfnLock, OldIrql);
}
/* PUBLIC FUNCTIONS ***********************************************************/
VOID
NTAPI
MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress,
- IN ULONG NumberOfBytes,
+ IN SIZE_T NumberOfBytes,
IN MEMORY_CACHING_TYPE CacheType)
{
//
<library>bootvid</library>
<library>wdmguid</library>
<dependency>bugcodes</dependency>
- <!-- See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38269
<directory name="include">
<pch>precomp.h</pch>
</directory>
- -->
<directory name="ke">
<if property="ARCH" value="i386">
<directory name="i386">
- <file first="true">boot.S</file>
<file>abios.c</file>
<file>cpu.c</file>
+ <file>context.c</file>
<file>ctxswitch.S</file>
<file>exp.c</file>
<file>irqobj.c</file>
<file>ldt.c</file>
<file>mtrr.c</file>
<file>patpge.c</file>
- <file>systimer.S</file>
<file>thrdini.c</file>
<file>trap.s</file>
<file>traphdlr.c</file>
<file>kiinit.c</file>
<file>stubs_asm.s</file>
<file>thrdini.c</file>
- <file>time.c</file>
<file>trap.s</file>
<file>trapc.c</file>
<file>usercall.c</file>
<file>ctxhelp.S</file>
</directory>
</if>
+ <if property="ARCH" value="amd64">
+ <directory name="amd64">
+ <file first="true">boot.S</file>
+ <file>context.c</file>
+ <file>cpu.c</file>
+ <file>ctxswitch.S</file>
+ <file>except.c</file>
+ <file>interrupt.c</file>
+ <file>irql.c</file>
+ <file>kiinit.c</file>
+ <file>spinlock.c</file>
+ <file>stubs.c</file>
+ <file>thrdini.c</file>
+ <file>trap.S</file>
+ </directory>
+ </if>
<file>apc.c</file>
<file>balmgr.c</file>
<file>bug.c</file>
<file>dpc.c</file>
<file>eventobj.c</file>
<file>except.c</file>
- <file>freeldr.c</file>
+ <if property="ARCH" value="i386">
+ <file>freeldr.c</file>
+ </if>
<file>freeze.c</file>
<file>gate.c</file>
<file>gmutex.c</file>
<file>queue.c</file>
<file>semphobj.c</file>
<file>spinlock.c</file>
+ <file>time.c</file>
<file>thrdschd.c</file>
<file>thrdobj.c</file>
<file>timerobj.c</file>
<file>cmhardwr.c</file>
</directory>
</if>
+ <if property="ARCH" value="amd64">
+ <directory name="i386">
+ <file>cmhardwr.c</file>
+ </directory>
+ </if>
<if property="ARCH" value="arm">
<directory name="arm">
<file>cmhardwr.c</file>
<file>ioport.S</file>
</directory>
</if>
+ <if property="ARCH" value="amd64">
+ <directory name="amd64">
+ <file>fastinterlck.c</file>
+ </directory>
+ </if>
<file>atom.c</file>
<file>callback.c</file>
<file>dbgctrl.c</file>
</if>
</directory>
</if>
+ <if property="ARCH" value="amd64">
+ <directory name="amd64">
+ <if property="KDBG" value="1">
+ <group>
+ <file>i386-dis.c</file>
+ <file>kdb_help.S</file>
+ <file>kdb.c</file>
+ <file>setjmp.S</file>
+ </group>
+ </if>
+ </directory>
+ </if>
<if property="KDBG" value="1">
<file>kdb.c</file>
<file>kdb_cli.c</file>
</if>
<file>kdbg.c</file>
</directory>
+ <if property="ARCH" value="amd64">
+ <directory name="amd64">
+ <file>kd.c</file>
+ <file>kdmemsup.c</file>
+ </directory>
+ </if>
<file>kdinit.c</file>
<file>kdio.c</file>
<file>kdmain.c</file>
<file>page.c</file>
</directory>
</if>
+ <if property="ARCH" value="amd64">
+ <directory name="amd64">
+ <file>init.c</file>
+ <file>page.c</file>
+ </directory>
+ </if>
<directory name="ARM3">
<if property="ARCH" value="i386">
<directory name="i386">
<file>psctx.c</file>
</directory>
</if>
+ <if property="ARCH" value="amd64">
+ <directory name="amd64">
+ <file>psctx.c</file>
+ </directory>
+ </if>
<file>debug.c</file>
<file>job.c</file>
<file>kill.c</file>
</directory>
<file>ntoskrnl.rc</file>
<linkerscript>ntoskrnl_$(ARCH).lnk</linkerscript>
-
- <!-- See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38054#c7 -->
- <compilerflag compilerset="gcc">-fno-unit-at-a-time</compilerflag>
</group>
if (pMsg->message == WM_PAINT)
{
/* send a WM_NCPAINT and WM_ERASEBKGND if the non-client area is still invalid */
- HRGN hrgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
+ HRGN hrgn = IntSysCreateRectRgn( 0, 0, 0, 0 );
co_UserGetUpdateRgn( Window, hrgn, TRUE );
- GreDeleteObject( hrgn );
+ REGION_FreeRgnByHandle( hrgn );
}
return retval;
}
BOOL APIENTRY
NtUserTranslateMessage(LPMSG lpMsg,
- HKL dwhkl)
+ UINT flags)
{
NTSTATUS Status;
MSG SafeMsg;
RETURN( FALSE);
}
- RETURN( IntTranslateKbdMessage(&SafeMsg, dwhkl));
+ RETURN( IntTranslateKbdMessage(&SafeMsg, flags));
CLEANUP:
DPRINT("Leave NtUserTranslateMessage: ret=%i\n",_ret_);
#include "gdidbg.c"
-/* static */ /* FIXME: -fno-unit-at-a-time breaks this */
+static
BOOL INTERNAL_CALL GDI_CleanupDummy(PVOID ObjectBody);
/** GLOBALS *******************************************************************/
/*
* Dummy GDI Cleanup Callback
*/
-/* static */ /* FIXME: -fno-unit-at-a-time breaks this */
+static
BOOL INTERNAL_CALL
GDI_CleanupDummy(PVOID ObjectBody)
{
hPtr = GdiHandleCache->Handle + Offset;
- if ( oType == hctRegionHandle)
+ if ( pAttr && oType == hctRegionHandle)
{
if ( Number < CACHE_REGION_ENTRIES )
{
break;
case GDI_OBJECT_TYPE_REGION:
- if (bPEBCacheHandle(hObject, hctRegionHandle, pAttr))
+ /* If pAttr NULL, the probability is high for System Region. */
+ if ( pAttr &&
+ bPEBCacheHandle(hObject, hctRegionHandle, pAttr))
{
+ /* User space handle only! */
return TRUE;
}
if (pAttr)
{
KeEnterCriticalRegion();
FreeObjectAttr(pAttr);
+ Entry->UserData = NULL;
KeLeaveCriticalRegion();
}
break;
/** PUBLIC FUNCTIONS **********************************************************/
+ BOOL
+ FASTCALL
+ IntGdiSetRegionOwner(HRGN hRgn, DWORD OwnerMask)
+ {
+ INT Index;
+ PGDI_TABLE_ENTRY Entry;
+ /*
+ System Regions:
+ These regions do not use attribute sections and when allocated, use gdiobj
+ level functions.
+ */
+ // FIXME! HAX!!! Remove this once we get everything right!
+ KeEnterCriticalRegion();
+ Index = GDI_HANDLE_GET_INDEX(hRgn);
+ Entry = &GdiHandleTable->Entries[Index];
+ if (Entry->UserData) FreeObjectAttr(Entry->UserData);
+ Entry->UserData = NULL;
+ KeLeaveCriticalRegion();
+ //
+ if ((OwnerMask == GDI_OBJ_HMGR_PUBLIC) || OwnerMask == GDI_OBJ_HMGR_NONE)
+ {
+ return GDIOBJ_SetOwnership(hRgn, NULL);
+ }
+ if (OwnerMask == GDI_OBJ_HMGR_POWNED)
+ {
+ return GDIOBJ_SetOwnership((HGDIOBJ) hRgn, PsGetCurrentProcess() );
+ }
+ return FALSE;
+ }
+
BOOL
FASTCALL
IntGdiSetBrushOwner(PBRUSH pbr, DWORD OwnerMask)
return TRUE;
}
-
BOOL
FASTCALL
IntGdiSetDCOwnerEx( HDC hDC, DWORD OwnerMask, BOOL NoSetBrush)
return Ret;
}
-
W32KAPI
HANDLE
APIENTRY
if ( att != NULL )
{
const XMLAttribute* installbase = moduleNode.GetAttribute ( "installbase", false );
+
+ if(installbase)
+ this->installbase = installbase->value;
+ else
+ this->installbase = "";
+
install = new FileLocation ( InstallDirectory,
installbase ? installbase->value : "",
att->value,
switch ( type )
{
case Kernel:
- return "KiSystemStartup";
+ if (Environment::GetArch() == "arm") return "KiSystemStartup";
+ return "KiSystemStartup@4";
case KeyboardLayout:
case KernelModeDLL:
case KernelModeDriver: