/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/cc/cacheman.c
IN BOOLEAN BcbListHeld
)
{
- LARGE_INTEGER i;
+ LARGE_INTEGER i;
UNIMPLEMENTED;
/* FUNCTIONS *****************************************************************/
-VOID
+VOID
CcInitCacheZeroPage(VOID)
{
NTSTATUS Status;
Buffer = pTemp;
}
#endif
- Length = Length - TempLength;
+ Length = Length - TempLength;
previous = current;
current = current->NextInChain;
CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
current2 = current2->NextInChain;
current_size += Bcb->CacheSegmentSize;
}
-
+
/*
* Create an MDL which contains all their pages.
*/
Buffer = pTemp;
}
#endif
- Length = Length - TempLength;
+ Length = Length - TempLength;
CcRosReleaseCacheSegment(Bcb, previous, TRUE, FALSE, FALSE);
current_size += Bcb->CacheSegmentSize;
}
return(STATUS_SUCCESS);
}
-NTSTATUS
+NTSTATUS
ReadCacheSegment(PCACHE_SEGMENT CacheSeg)
{
ULONG Size;
MmBuildMdlForNonPagedPool(Mdl);
Mdl->MdlFlags |= MDL_IO_PAGE_READ;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
- Status = IoPageRead(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, & Event, &IoStatus);
+ Status = IoPageRead(CacheSeg->Bcb->FileObject, Mdl, &SegOffset, & Event, &IoStatus);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
}
if (CacheSeg->Bcb->CacheSegmentSize > Size)
{
- memset ((char*)CacheSeg->BaseAddress + Size, 0,
+ memset ((char*)CacheSeg->BaseAddress + Size, 0,
CacheSeg->Bcb->CacheSegmentSize - Size);
}
return STATUS_SUCCESS;
}
-NTSTATUS
+NTSTATUS
WriteCacheSegment(PCACHE_SEGMENT CacheSeg)
{
ULONG Size;
KIRQL oldirql;
PLIST_ENTRY current_entry;
PCACHE_SEGMENT current;
-
+
DPRINT("CcCopyRead(FileObject %x, FileOffset %x, "
"Length %d, Wait %d, Buffer %x, IoStatus %x)\n",
FileObject, (ULONG)FileOffset->QuadPart, Length, Wait,
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
ReadOffset = (ULONG)FileOffset->QuadPart;
-
+
DPRINT("AllocationSize %d, FileSize %d\n",
(ULONG)Bcb->AllocationSize.QuadPart,
(ULONG)Bcb->FileSize.QuadPart);
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
{
- current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
+ current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
if (!current->Valid && current->FileOffset < ReadOffset + Length
&& current->FileOffset + Bcb->CacheSegmentSize > ReadOffset)
{
TempLength = min (Length, Bcb->CacheSegmentSize - TempLength);
Status = CcRosRequestCacheSegment(Bcb,
- ROUND_DOWN(ReadOffset,
+ ROUND_DOWN(ReadOffset,
Bcb->CacheSegmentSize),
&BaseAddress, &Valid, &CacheSeg);
if (!NT_SUCCESS(Status))
return FALSE;
}
}
- memcpy (Buffer, (char*)BaseAddress + ReadOffset % Bcb->CacheSegmentSize,
+ memcpy (Buffer, (char*)BaseAddress + ReadOffset % Bcb->CacheSegmentSize,
TempLength);
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, FALSE, FALSE);
ReadLength += TempLength;
Length -= TempLength;
ReadOffset += TempLength;
Buffer = (PVOID)((char*)Buffer + TempLength);
- }
+ }
while (Length > 0)
{
TempLength = min(max(Bcb->CacheSegmentSize, MAX_RW_LENGTH), Length);
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
{
- CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
+ CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
if (!CacheSeg->Valid)
{
- if ((WriteOffset >= CacheSeg->FileOffset &&
+ if ((WriteOffset >= CacheSeg->FileOffset &&
WriteOffset < CacheSeg->FileOffset + Bcb->CacheSegmentSize)
- || (WriteOffset + Length > CacheSeg->FileOffset &&
- WriteOffset + Length <= CacheSeg->FileOffset +
+ || (WriteOffset + Length > CacheSeg->FileOffset &&
+ WriteOffset + Length <= CacheSeg->FileOffset +
Bcb->CacheSegmentSize))
{
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
return(FALSE);
}
}
- memcpy ((char*)BaseAddress + WriteOffset % Bcb->CacheSegmentSize,
+ memcpy ((char*)BaseAddress + WriteOffset % Bcb->CacheSegmentSize,
Buffer, TempLength);
CcRosReleaseCacheSegment(Bcb, CacheSeg, TRUE, TRUE, FALSE);
-
+
Length -= TempLength;
WriteOffset += TempLength;
#if defined(__GNUC__)
}
#endif
}
-
+
while (Length > 0)
{
TempLength = min (Bcb->CacheSegmentSize, Length);
ULONG i;
IO_STATUS_BLOCK Iosb;
KEVENT Event;
-
+
DPRINT("CcZeroData(FileObject %x, StartOffset %I64x, EndOffset %I64x, "
- "Wait %d)\n", FileObject, StartOffset->QuadPart, EndOffset->QuadPart,
+ "Wait %d)\n", FileObject, StartOffset->QuadPart, EndOffset->QuadPart,
Wait);
-
+
Length = EndOffset->u.LowPart - StartOffset->u.LowPart;
WriteOffset.QuadPart = StartOffset->QuadPart;
/* File is not cached */
Mdl = alloca(MmSizeOfMdl(NULL, MAX_ZERO_LENGTH));
-
+
while (Length > 0)
{
if (Length + WriteOffset.u.LowPart % PAGE_SIZE > MAX_ZERO_LENGTH)
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = Iosb.Status;
}
- MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
+ MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
if (!NT_SUCCESS(Status))
{
return(FALSE);
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
{
- CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
+ CacheSeg = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
if (!CacheSeg->Valid)
{
- if ((WriteOffset.u.LowPart >= CacheSeg->FileOffset &&
+ if ((WriteOffset.u.LowPart >= CacheSeg->FileOffset &&
WriteOffset.u.LowPart < CacheSeg->FileOffset + Bcb->CacheSegmentSize)
- || (WriteOffset.u.LowPart + Length > CacheSeg->FileOffset &&
- WriteOffset.u.LowPart + Length <=
+ || (WriteOffset.u.LowPart + Length > CacheSeg->FileOffset &&
+ WriteOffset.u.LowPart + Length <=
CacheSeg->FileOffset + Bcb->CacheSegmentSize))
{
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
Status = ReadCacheSegment(current);
if (!NT_SUCCESS(Status))
{
- DPRINT1("ReadCacheSegment failed, status %x\n",
+ DPRINT1("ReadCacheSegment failed, status %x\n",
Status);
}
}
Length -= TempLength;
current = current->NextInChain;
- }
+ }
current = CacheSeg;
while (current != NULL)
-/* $Id:$
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
#ifndef VACB_MAPPING_GRANULARITY
#define VACB_MAPPING_GRANULARITY (256 * 1024)
#endif
-
+
/* GLOBALS *****************************************************************/
extern FAST_MUTEX ViewLock;
{
UNIMPLEMENTED;
- LARGE_INTEGER i;
+ LARGE_INTEGER i;
i.QuadPart = 0;
return i;
}
{
UNIMPLEMENTED;
- LARGE_INTEGER i;
+ LARGE_INTEGER i;
i.QuadPart = 0;
return i;
}
LIST_ENTRY FreeListHead;
NTSTATUS Status;
- DPRINT("CcSetFileSizes(FileObject %x, FileSizes %x)\n",
+ DPRINT("CcSetFileSizes(FileObject %x, FileSizes %x)\n",
FileObject, FileSizes);
DPRINT("AllocationSize %d, FileSize %d, ValidDataLength %d\n",
(ULONG)FileSizes->AllocationSize.QuadPart,
*/
if (Bcb == NULL)
return;
-
+
if (FileSizes->AllocationSize.QuadPart < Bcb->AllocationSize.QuadPart)
{
InitializeListHead(&FreeListHead);
}
}
}
-
+
Bcb->AllocationSize = FileSizes->AllocationSize;
Bcb->FileSize = FileSizes->FileSize;
KeReleaseSpinLock(&Bcb->BcbLock, oldirql);
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/cc/fs.c
* Used by CcMdlReadComplete@8 and FsRtl
*
*/
-VOID
+VOID
STDCALL
CcMdlReadCompleteDev(IN PMDL MdlChain,
IN PFILE_OBJECT FileObject)
{
PMDL Mdl;
-
+
/* Free MDLs */
while ((Mdl = MdlChain))
{
{
PDEVICE_OBJECT DeviceObject = NULL;
PFAST_IO_DISPATCH FastDispatch;
-
+
/* Get Fast Dispatch Data */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
-
+
/* Check if we support Fast Calls, and check this one */
if (FastDispatch && FastDispatch->MdlReadComplete)
{
MdlChain,
DeviceObject);
}
-
+
/* Use slow path */
CcMdlReadCompleteDev(MdlChain, FileObject);
}
{
PDEVICE_OBJECT DeviceObject = NULL;
PFAST_IO_DISPATCH FastDispatch;
-
+
/* Get Fast Dispatch Data */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
-
+
/* Check if we support Fast Calls, and check this one */
if (FastDispatch && FastDispatch->MdlWriteComplete)
{
MdlChain,
DeviceObject);
}
-
+
/* Use slow path */
CcMdlWriteCompleteDev(FileOffset, MdlChain, FileObject);
}
NTSTATUS Status;
PINTERNAL_BCB iBcb;
ULONG ROffset;
-
+
DPRINT("CcMapData(FileObject %x, FileOffset %d, Length %d, Wait %d,"
" pBcb %x, pBuffer %x)\n", FileObject, (ULONG)FileOffset->QuadPart,
Length, Wait, pBcb, pBuffer);
-
+
ReadOffset = (ULONG)FileOffset->QuadPart;
Bcb = FileObject->SectionObjectPointer->SharedCacheMap;
ASSERT(Bcb);
DPRINT("AllocationSize %d, FileSize %d\n",
(ULONG)Bcb->AllocationSize.QuadPart,
(ULONG)Bcb->FileSize.QuadPart);
-
+
if (ReadOffset % Bcb->CacheSegmentSize + Length > Bcb->CacheSegmentSize)
{
return(FALSE);
CcUnpinData (IN PVOID Bcb)
{
PINTERNAL_BCB iBcb = Bcb;
- CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE,
+ CcRosReleaseCacheSegment(iBcb->CacheSegment->Bcb, iBcb->CacheSegment, TRUE,
iBcb->Dirty, FALSE);
if (--iBcb->RefCount == 0)
{
/* NOTES **********************************************************************
*
- * This is not the NT implementation of a file cache nor anything much like
- * it.
+ * This is not the NT implementation of a file cache nor anything much like
+ * it.
*
- * The general procedure for a filesystem to implement a read or write
+ * The general procedure for a filesystem to implement a read or write
* dispatch routine is as follows
- *
+ *
* (1) If caching for the FCB hasn't been initiated then so do by calling
* CcInitializeFileCache.
- *
+ *
* (2) For each 4k region which is being read or written obtain a cache page
- * by calling CcRequestCachePage.
+ * by calling CcRequestCachePage.
*
- * (3) If either the page is being read or not completely written, and it is
+ * (3) If either the page is being read or not completely written, and it is
* not up to date then read its data from the underlying medium. If the read
- * fails then call CcReleaseCachePage with VALID as FALSE and return a error.
- *
+ * fails then call CcReleaseCachePage with VALID as FALSE and return a error.
+ *
* (4) Copy the data into or out of the page as necessary.
- *
+ *
* (5) Release the cache page
*/
/* INCLUDES ******************************************************************/
/* GLOBALS *******************************************************************/
/*
- * If CACHE_BITMAP is defined, the cache manager uses one large memory region
- * within the kernel address space and allocate/deallocate space from this block
- * over a bitmap. If CACHE_BITMAP is used, the size of the mdl mapping region
+ * If CACHE_BITMAP is defined, the cache manager uses one large memory region
+ * within the kernel address space and allocate/deallocate space from this block
+ * over a bitmap. If CACHE_BITMAP is used, the size of the mdl mapping region
* must be reduced (ntoskrnl\mm\mdl.c, MI_MDLMAPPING_REGION_SIZE).
*/
//#define CACHE_BITMAP
}
NewTarget = WriteCount[0];
-
+
Target = max(NewTarget, Target);
current_entry = DirtySegmentListHead.Flink;
}
while (current_entry != &DirtySegmentListHead && Target > 0)
{
- current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
+ current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
DirtySegmentListEntry);
current_entry = current_entry->Flink;
Locked = ExTryToAcquireFastMutex(¤t->Lock);
}
ExReleaseFastMutex(&ViewLock);
PagesPerSegment = current->Bcb->CacheSegmentSize / PAGE_SIZE;
- Status = CcRosFlushCacheSegment(current);
+ Status = CcRosFlushCacheSegment(current);
ExReleaseFastMutex(¤t->Lock);
if (!NT_SUCCESS(Status) && (Status != STATUS_END_OF_FILE))
{
* ARGUMENTS:
* Target - The number of pages to be freed.
* Priority - The priority of free (currently unused).
- * NrFreed - Points to a variable where the number of pages
+ * NrFreed - Points to a variable where the number of pages
* actually freed is returned.
*/
{
DPRINT("CcRosTrimCache(Target %d)\n", Target);
*NrFreed = 0;
-
+
InitializeListHead(&FreeList);
-
+
ExAcquireFastMutex(&ViewLock);
current_entry = CacheSegmentLRUListHead.Flink;
while (current_entry != &CacheSegmentLRUListHead && Target > 0)
{
- current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
+ current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
CacheSegmentLRUListEntry);
current_entry = current_entry->Flink;
-
+
KeAcquireSpinLock(¤t->Bcb->BcbLock, &oldIrql);
if (current->ReferenceCount == 0)
{
{
ULONG i;
NTSTATUS Status;
-
+
current->ReferenceCount++;
last = current;
current->PageOut = TRUE;
while (!IsListEmpty(&FreeList))
{
current_entry = RemoveHeadList(&FreeList);
- current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
+ current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
CcRosInternalFreeCacheSegment(current);
}
return(STATUS_SUCCESS);
}
-NTSTATUS
+NTSTATUS
CcRosReleaseCacheSegment(PBCB Bcb,
PCACHE_SEGMENT CacheSeg,
BOOLEAN Valid,
KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
ExReleaseFastMutex(&ViewLock);
ExReleaseFastMutex(&CacheSeg->Lock);
-
+
return(STATUS_SUCCESS);
}
-PCACHE_SEGMENT
+PCACHE_SEGMENT
CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset)
{
PLIST_ENTRY current_entry;
current_entry = Bcb->BcbSegmentListHead.Flink;
while (current_entry != &Bcb->BcbSegmentListHead)
{
- current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
+ current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
if (current->FileOffset <= FileOffset &&
(current->FileOffset + Bcb->CacheSegmentSize) > FileOffset)
/* There is window between the call to CcRosLookupCacheSegment
* and CcRosCreateCacheSegment. We must check if a segment on
* the fileoffset exist. If there exist a segment, we release
- * our new created segment and return the existing one.
+ * our new created segment and return the existing one.
*/
KeAcquireSpinLock(&Bcb->BcbLock, &oldIrql);
current_entry = Bcb->BcbSegmentListHead.Flink;
previous = NULL;
while (current_entry != &Bcb->BcbSegmentListHead)
{
- current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
+ current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT,
BcbSegmentListEntry);
if (current->FileOffset <= FileOffset &&
(current->FileOffset + Bcb->CacheSegmentSize) > FileOffset)
KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
StartingOffset = RtlFindClearBitsAndSet(&CiCacheSegMappingRegionAllocMap, Bcb->CacheSegmentSize / PAGE_SIZE, CiCacheSegMappingRegionHint);
-
+
if (StartingOffset == 0xffffffff)
{
DPRINT1("Out of CacheSeg mapping space\n");
if (CiCacheSegMappingRegionHint == StartingOffset)
{
- CiCacheSegMappingRegionHint += Bcb->CacheSegmentSize / PAGE_SIZE;
+ CiCacheSegMappingRegionHint += Bcb->CacheSegmentSize / PAGE_SIZE;
}
KeReleaseSpinLock(&CiCacheSegMappingRegionLock, oldIrql);
Length = ROUND_UP(Length, Bcb->CacheSegmentSize);
#if defined(__GNUC__)
- CacheSegList = alloca(sizeof(PCACHE_SEGMENT) *
+ CacheSegList = alloca(sizeof(PCACHE_SEGMENT) *
(Length / Bcb->CacheSegmentSize));
#elif defined(_MSC_VER)
- CacheSegList = _alloca(sizeof(PCACHE_SEGMENT) *
+ CacheSegList = _alloca(sizeof(PCACHE_SEGMENT) *
(Length / Bcb->CacheSegmentSize));
#else
#error Unknown compiler for alloca intrinsic stack allocation "function"
}
}
Previous->NextInChain = NULL;
-
+
return(STATUS_SUCCESS);
}
return(STATUS_SUCCESS);
}
-NTSTATUS STDCALL
+NTSTATUS STDCALL
CcRosRequestCacheSegment(PBCB Bcb,
ULONG FileOffset,
PVOID* BaseAddress,
}
#ifdef CACHE_BITMAP
#else
-STATIC VOID
-CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
+STATIC VOID
+CcFreeCachePage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty)
{
ASSERT(SwapEntry == 0);
}
}
#endif
-NTSTATUS
+NTSTATUS
CcRosInternalFreeCacheSegment(PCACHE_SEGMENT CacheSeg)
/*
* FUNCTION: Releases a cache segment associated with a BCB
/* Unmap all the pages. */
for (i = 0; i < RegionSize; i++)
{
- MmDeleteVirtualMapping(NULL,
+ MmDeleteVirtualMapping(NULL,
CacheSeg->BaseAddress + (i * PAGE_SIZE),
FALSE,
NULL,
KeAcquireSpinLock(&CiCacheSegMappingRegionLock, &oldIrql);
/* Deallocate all the pages used. */
Base = (ULONG)(CacheSeg->BaseAddress - CiCacheSegMappingRegionBase) / PAGE_SIZE;
-
+
RtlClearBits(&CiCacheSegMappingRegionAllocMap, Base, RegionSize);
CiCacheSegMappingRegionHint = min (CiCacheSegMappingRegionHint, Base);
{
Offset = *FileOffset;
}
- else
+ else
{
Offset.QuadPart = (LONGLONG)0;
Length = Bcb->FileSize.u.LowPart;
}
-
+
if (IoStatus)
{
IoStatus->Status = STATUS_SUCCESS;
}
}
-NTSTATUS
+NTSTATUS
CcRosDeleteFileCache(PFILE_OBJECT FileObject, PBCB Bcb)
/*
* FUNCTION: Releases the BCB associated with a file object
Bcb->BcbRemoveListEntry.Flink = NULL;
}
- FileObject->SectionObjectPointer->SharedCacheMap = NULL;
+ FileObject->SectionObjectPointer->SharedCacheMap = NULL;
/*
* Release all cache segments.
}
InsertHeadList(&FreeList, ¤t->BcbSegmentListEntry);
}
- KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
+ KeReleaseSpinLock(&Bcb->BcbLock, oldIrql);
ExReleaseFastMutex(&ViewLock);
ObDereferenceObject (Bcb->FileObject);
current = CONTAINING_RECORD(current_entry, CACHE_SEGMENT, BcbSegmentListEntry);
Status = CcRosInternalFreeCacheSegment(current);
}
- ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
+ ExFreeToNPagedLookasideList(&BcbLookasideList, Bcb);
ExAcquireFastMutex(&ViewLock);
}
return(STATUS_SUCCESS);
ExReleaseFastMutex(&ViewLock);
}
-NTSTATUS STDCALL
+NTSTATUS STDCALL
CcRosReleaseFileCache(PFILE_OBJECT FileObject)
/*
* FUNCTION: Called by the file system when a handle to a file object
return(STATUS_SUCCESS);
}
-NTSTATUS
+NTSTATUS
CcTryToInitializeFileCache(PFILE_OBJECT FileObject)
{
PBCB Bcb;
}
-NTSTATUS STDCALL
+NTSTATUS STDCALL
CcRosInitializeFileCache(PFILE_OBJECT FileObject,
ULONG CacheSegmentSize)
/*
Bcb->CacheSegmentSize = CacheSegmentSize;
if (FileObject->FsContext)
{
- Bcb->AllocationSize =
+ Bcb->AllocationSize =
((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->AllocationSize;
- Bcb->FileSize =
+ Bcb->FileSize =
((PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)->FileSize;
}
KeInitializeSpinLock(&Bcb->BcbLock);
DbgPrint("LazyCloseThread: Terminating\n");
break;
}
-
+
ExAcquireFastMutex(&ViewLock);
CcTimeStamp++;
if (CcTimeStamp >= 30)
#endif
NTSTATUS Status;
KPRIORITY Priority;
-
+
DPRINT("CcInitView()\n");
#ifdef CACHE_BITMAP
BoundaryAddressMultiple.QuadPart = 0;
RtlClearAllBits(&CiCacheSegMappingRegionAllocMap);
KeInitializeSpinLock(&CiCacheSegMappingRegionLock);
-#endif
+#endif
InitializeListHead(&CacheSegmentListHead);
InitializeListHead(&DirtySegmentListHead);
InitializeListHead(&CacheSegmentLRUListHead);
20);
MmInitializeMemoryConsumer(MC_CACHE, CcRosTrimCache);
-
+
CcInitCacheZeroPage();
- CcTimeStamp = 0;
+ CcTimeStamp = 0;
LazyCloseThreadShouldTerminate = FALSE;
KeInitializeEvent (&LazyCloseThreadEvent, SynchronizationEvent, FALSE);
Status = PsCreateSystemThread(&LazyCloseThreadHandle,
/* List entry into the global key object list */
LIST_ENTRY ListEntry;
-
+
/* Time stamp for the last access by the parse routine */
ULONG TimeStamp;
} KEY_OBJECT, *PKEY_OBJECT;
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/cm/ntfunc.c
IN OUT PLARGE_INTEGER Cookie)
{
PREGISTRY_CALLBACK Callback;
-
+
PAGED_CODE();
-
+
ASSERT(Function && Cookie);
-
+
Callback = ExAllocatePoolWithTag(PagedPool,
sizeof(REGISTRY_CALLBACK),
TAG('C', 'M', 'c', 'b'));
Callback->Function = Function;
Callback->Context = Context;
Callback->PendingDelete = FALSE;
-
+
/* add it to the callback list and receive a cookie for the callback */
ExAcquireFastMutex(&CmiCallbackLock);
/* FIXME - to receive a unique cookie we'll just return the pointer to the
InsertTailList(&CmiCallbackHead, &Callback->ListEntry);
ExReleaseFastMutex(&CmiCallbackLock);
-
+
*Cookie = Callback->Cookie;
return STATUS_SUCCESS;
}
CmUnRegisterCallback(IN LARGE_INTEGER Cookie)
{
PLIST_ENTRY CurrentEntry;
-
+
PAGED_CODE();
ExAcquireFastMutex(&CmiCallbackLock);
}
}
}
-
+
ExReleaseFastMutex(&CmiCallbackLock);
return STATUS_UNSUCCESSFUL;
IN PVOID Argument2)
{
PLIST_ENTRY CurrentEntry;
-
+
PAGED_CODE();
-
+
ExAcquireFastMutex(&CmiCallbackLock);
for(CurrentEntry = CmiCallbackHead.Flink;
ExAcquireRundownProtectionEx(&CurrentCallback->RundownRef, 1))
{
NTSTATUS Status;
-
+
/* don't hold locks during the callbacks! */
ExReleaseFastMutex(&CmiCallbackLock);
-
+
Status = CurrentCallback->Function(CurrentCallback->Context,
Argument1,
Argument2);
ExReleaseRundownProtectionEx(&CurrentCallback->RundownRef, 1);
}
}
-
+
ExReleaseFastMutex(&CmiCallbackLock);
-
+
return STATUS_SUCCESS;
}
PVOID Object;
PWSTR Start;
unsigned i;
-
+
PAGED_CODE();
DPRINT("NtCreateKey (Name %wZ KeyHandle %x Root %x)\n",
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
-
+
ObDereferenceObject(Object);
if (Disposition)
KPROCESSOR_MODE PreviousMode;
PKEY_OBJECT KeyObject;
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT1("NtDeleteKey(KeyHandle %x) called\n", KeyHandle);
-
+
PreviousMode = ExGetPreviousMode();
/* Verify that the handle is valid and is a registry key */
ULONG NameSize, ClassSize;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
DPRINT("KH %x I %d KIC %x KI %x L %d RL %x\n",
Status = STATUS_BUFFER_OVERFLOW;
CHECKPOINT;
}
- else if (Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) -
+ else if (Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) -
NameSize < ClassSize)
{
- ClassSize = Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) -
+ ClassSize = Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) -
NameSize;
Status = STATUS_BUFFER_OVERFLOW;
CHECKPOINT;
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
-
+
PAGED_CODE();
DPRINT("KH %x I %d KVIC %x KVI %x L %d RL %x\n",
}
else
{
- ValueBasicInformation = (PKEY_VALUE_BASIC_INFORMATION)
+ ValueBasicInformation = (PKEY_VALUE_BASIC_INFORMATION)
KeyValueInformation;
ValueBasicInformation->TitleIndex = 0;
ValueBasicInformation->Type = ValueCell->DataType;
case KeyValuePartialInformation:
DataSize = ValueCell->DataSize & REG_DATA_SIZE_MASK;
- *ResultLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]) +
+ *ResultLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]) +
DataSize;
if (Length < FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data[0]))
Status = STATUS_BUFFER_OVERFLOW;
CHECKPOINT;
}
-
+
if (!(ValueCell->DataSize & REG_DATA_IN_OFFSET))
{
DataCell = CmiGetCell (RegistryHive, ValueCell->DataOffset, NULL);
- RtlCopyMemory(ValuePartialInformation->Data,
+ RtlCopyMemory(ValuePartialInformation->Data,
DataCell->Data,
DataSize);
}
else
{
- RtlCopyMemory(ValuePartialInformation->Data,
- &ValueCell->DataOffset,
+ RtlCopyMemory(ValuePartialInformation->Data,
+ &ValueCell->DataOffset,
DataSize);
}
}
}
else
{
- ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
+ ValueFullInformation = (PKEY_VALUE_FULL_INFORMATION)
KeyValueInformation;
ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueCell->DataType;
ValueFullInformation->NameLength = NameSize;
- ValueFullInformation->DataOffset =
+ ValueFullInformation->DataOffset =
(ULONG_PTR)ValueFullInformation->Name -
(ULONG_PTR)ValueFullInformation +
ValueFullInformation->NameLength;
ValueFullInformation->DataOffset =
ROUND_UP(ValueFullInformation->DataOffset, sizeof(PVOID));
ValueFullInformation->DataLength = ValueCell->DataSize & REG_DATA_SIZE_MASK;
-
+
if (Length - FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name[0]) <
NameSize)
{
PKEY_OBJECT KeyObject;
PREGISTRY_HIVE RegistryHive;
KPROCESSOR_MODE PreviousMode;
-
+
PAGED_CODE();
DPRINT("NtFlushKey (KeyHandle %lx) called\n", KeyHandle);
-
+
PreviousMode = ExGetPreviousMode();
/* Verify that the handle is valid and is a registry key */
PVOID Object;
HANDLE hKey;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtOpenKey(KH %x DA %x OA %x OA->ON '%wZ'\n",
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
PKEY_CELL KeyCell;
ULONG NameSize, ClassSize;
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("NtQueryKey(KH %x KIC %x KI %x L %d RL %x)\n",
Status = STATUS_BUFFER_OVERFLOW;
CHECKPOINT;
}
- else if (Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) -
+ else if (Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) -
NameSize < ClassSize)
{
- ClassSize = Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) -
+ ClassSize = Length - FIELD_OFFSET(KEY_NODE_INFORMATION, Name[0]) -
NameSize;
Status = STATUS_BUFFER_OVERFLOW;
CHECKPOINT;
Status = STATUS_BUFFER_OVERFLOW;
CHECKPOINT;
}
-
+
if (ClassSize)
{
ClassCell = CmiGetCell (KeyObject->RegistryHive,
PKEY_VALUE_BASIC_INFORMATION ValueBasicInformation;
PKEY_VALUE_PARTIAL_INFORMATION ValuePartialInformation;
PKEY_VALUE_FULL_INFORMATION ValueFullInformation;
-
+
PAGED_CODE();
DPRINT("NtQueryValueKey(KeyHandle %x ValueName %S Length %x)\n",
}
else
{
- ValueBasicInformation = (PKEY_VALUE_BASIC_INFORMATION)
+ ValueBasicInformation = (PKEY_VALUE_BASIC_INFORMATION)
KeyValueInformation;
ValueBasicInformation->TitleIndex = 0;
ValueBasicInformation->Type = ValueCell->DataType;
ValueFullInformation->TitleIndex = 0;
ValueFullInformation->Type = ValueCell->DataType;
ValueFullInformation->NameLength = NameSize;
- ValueFullInformation->DataOffset =
+ ValueFullInformation->DataOffset =
(ULONG_PTR)ValueFullInformation->Name -
(ULONG_PTR)ValueFullInformation +
ValueFullInformation->NameLength;
PDATA_CELL NewDataCell;
PHBIN pBin;
ULONG DesiredAccess;
-
+
PAGED_CODE();
DPRINT("NtSetValueKey(KeyHandle %x ValueName '%wZ' Type %d)\n",
{
PKEY_OBJECT KeyObject;
NTSTATUS Status;
-
+
PAGED_CODE();
/* Verify that the handle is valid and is a registry key */
ULONG BufferSize;
ULONG Length;
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT ("NtLoadKey2() called\n");
IN ULONG Length,
IN BOOLEAN Asynchronous)
{
- return NtNotifyChangeMultipleKeys(KeyHandle,
+ return NtNotifyChangeMultipleKeys(KeyHandle,
0,
NULL,
Event,
NTSTATUS Status;
PUCHAR DataPtr;
ULONG i;
-
+
PAGED_CODE();
/* Verify that the handle is valid and is a registry key */
PREGISTRY_HIVE TempHive;
PKEY_OBJECT KeyObject;
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT ("NtSaveKey() called\n");
{
PKEY_OBJECT KeyObject;
NTSTATUS Status;
-
+
PAGED_CODE();
if (KeyInformationClass != KeyWriteTimeInformation)
{
PREGISTRY_HIVE RegistryHive;
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT ("NtUnloadKey() called\n");
NtInitializeRegistry (IN BOOLEAN SetUpBoot)
{
NTSTATUS Status;
-
+
PAGED_CODE();
if (CmiRegistryInitialized == TRUE)
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/cm/regfile.c
//BinHeader->DateModified.dwHighDateTime
-
+
if (BinHeader->BinSize != REG_BLOCK_SIZE)
{
DbgPrint("BinSize is %.08x (should be a multiple of %.08x)\n",
CmiMarkBlockDirty(RegistryHive, KeyCellOffset);
CmiMarkBlockDirty(RegistryHive, ValueListCellOffset);
}
- else if (KeyCell->NumberOfValues >=
+ else if (KeyCell->NumberOfValues >=
(((ULONG)ABS_VALUE(ValueListCell->CellSize) - sizeof(VALUE_LIST_CELL)) / sizeof(BLOCK_OFFSET)))
{
#if 0
Status = STATUS_SUCCESS;
*HashBlock = NULL;
- NewHashSize = sizeof(HASH_TABLE_CELL) +
+ NewHashSize = sizeof(HASH_TABLE_CELL) +
(SubKeyCount * sizeof(HASH_RECORD));
Status = CmiAllocateCell (RegistryHive,
NewHashSize,
while (1)
{
- Status = KeWaitForSingleObject(&CmiWorkerTimer,
- Executive,
- KernelMode,
- FALSE,
+ Status = KeWaitForSingleObject(&CmiWorkerTimer,
+ Executive,
+ KernelMode,
+ FALSE,
NULL);
if (Status == STATUS_SUCCESS)
{
CmInitHives(BOOLEAN SetupBoot)
{
PCHAR BaseAddress;
-
+
/* Load Registry Hives. This one can be missing. */
if (CachedModules[SystemRegistry]) {
BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart;
CmImportSystemHive(BaseAddress,
CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
}
-
+
BaseAddress = (PCHAR)CachedModules[HardwareRegistry]->ModStart;
CmImportHardwareHive(BaseAddress,
CachedModules[HardwareRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
-
+
/* Create dummy keys if no hardware hive was found */
CmImportHardwareHive (NULL, 0);
/* Initialize volatile registry settings */
if (SetupBoot == FALSE) CmInit2((PCHAR)KeLoaderBlock.CommandLine);
-}
+}
VOID INIT_FUNCTION
CmInitializeRegistry(VOID)
KEBUGCHECK(0);
}
- /* Start the timer */
+ /* Start the timer */
DueTime.QuadPart = -1;
KeSetTimerEx(&CmiWorkerTimer, DueTime, 5000, NULL); /* 5sec */
/* Build volatile registry store */
Status = CmiCreateVolatileHive (&CmiVolatileHive);
ASSERT(NT_SUCCESS(Status));
-
+
InitializeListHead(&CmiCallbackHead);
ExInitializeFastMutex(&CmiCallbackLock);
MiniNT = TRUE;
else if (!_strnicmp(CommandLine, "DEBUGPORT=PICE", 14))
PiceStart = 1;
-
+
/* Add a space between the options */
if (Position != 0)
SystemStartOptions[Position++] = L' ';
{
DPRINT1 ("Hive is still in use (hc %d, rc %d)\n", ObGetObjectHandleCount (KeyObject), ObGetObjectPointerCount (KeyObject));
ObDereferenceObject (KeyObject);
-
+
/* Release registry lock */
ExReleaseResourceLite (&CmiRegistryLock);
KeLeaveCriticalRegion();
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/cm/regobj.c
if (NT_SUCCESS(Status))
{
DPRINT("LinkPath '%wZ'\n", &LinkPath);
-
+
ExReleaseResourceLite(&CmiRegistryLock);
KeLeaveCriticalRegion();
ParentKey->NumberOfSubKeys--;
DPRINT("Dereference parent key: 0x%x\n", ParentKey);
-
+
ObDereferenceObject(ParentKey);
return STATUS_SUCCESS;
}
{
PKEY_OBJECT CurKey;
ULONG Index;
-
+
DPRINT("Scanning key list for: %wZ (Parent: %wZ)\n",
KeyName, &Parent->Name);
}
}
}
-
+
if (Index < Parent->NumberOfSubKeys)
{
if (CurKey->Flags & KO_MARKED_FOR_DELETE)
}
Message.Header.MessageSize = sizeof(LPC_DBG_MESSAGE);
- Message.Header.DataSize = sizeof(LPC_DBG_MESSAGE) -
+ Message.Header.DataSize = sizeof(LPC_DBG_MESSAGE) -
sizeof(LPC_MESSAGE);
Message.Type = DBG_EVENT_CREATE_THREAD;
Message.Status = STATUS_SUCCESS;
Message.Data.CreateThread.Reserved = 0;
Message.Data.CreateThread.StartAddress = StartAddress;
-
+
/* FIXME: Freeze all threads in process */
/* Send the message to the process's debug port and wait for a reply */
- Status =
+ Status =
LpcSendDebugMessagePort(PsGetCurrentThread()->ThreadsProcess->DebugPort,
&Message,
&Reply);
POBJECT_TYPE DbgkDebugObjectType;
/* FUNCTIONS *****************************************************************/
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtCreateDebugObject(OUT PHANDLE DebugHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
PDBGK_DEBUG_OBJECT DebugObject;
HANDLE hDebug;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtCreateDebugObject(0x%x, 0x%x, 0x%x)\n", DebugHandle, DesiredAccess, ObjectAttributes);
-
+
/* Check Output Safety */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(DebugHandle,
sizeof(HANDLE),
sizeof(ULONG));
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Create the Object */
Status = ObCreateObject(PreviousMode,
DbgkDebugObjectType,
0,
0,
(PVOID*)&DebugObject);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Initialize the Debug Object's Fast Mutex */
ExInitializeFastMutex(&DebugObject->Mutex);
-
+
/* Initialize the State Event List */
InitializeListHead(&DebugObject->StateEventListEntry);
-
+
/* Initialize the Debug Object's Wait Event */
KeInitializeEvent(&DebugObject->Event, NotificationEvent, 0);
-
+
/* Set the Flags */
DebugObject->KillProcessOnExit = KillProcessOnExit;
-
+
/* Insert it */
Status = ObInsertObject((PVOID)DebugObject,
NULL,
NULL,
&hDebug);
ObDereferenceObject(DebugObject);
-
+
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*DebugHandle = hDebug;
-
+
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
{
UNIMPLEMENTED;
-
+
return STATUS_NOT_IMPLEMENTED;
}
{
UNIMPLEMENTED;
-
+
return STATUS_NOT_IMPLEMENTED;
}
{
UNIMPLEMENTED;
-
+
return STATUS_NOT_IMPLEMENTED;
}
{
UNIMPLEMENTED;
-
+
return STATUS_NOT_IMPLEMENTED;
}
OUT PULONG ReturnLength OPTIONAL)
{
UNIMPLEMENTED;
-
+
return STATUS_NOT_IMPLEMENTED;
}
/* EOF */
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/callback.c
* PURPOSE: Executive callbacks
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Alex Ionescu (alex@relsoft.net)
*/
PINT_CALLBACK_OBJECT Callback;
NTSTATUS Status;
HANDLE Handle;
-
+
PAGED_CODE();
/* Open a handle to the callback if it exists */
* ExRegisterCallback
*
* FUNCTION:
- * Allows a function to associate a callback pointer (Function)
+ * Allows a function to associate a callback pointer (Function)
* to a created Callback object
*
* ARGUMENTS:
PINT_CALLBACK_OBJECT CallbackObject = (PINT_CALLBACK_OBJECT)OpaqueCallbackObject;
PCALLBACK_REGISTRATION CallbackRegistration = NULL;
KIRQL OldIrql;
-
+
PAGED_CODE();
/* Create reference to Callback Object */
PCALLBACK_REGISTRATION CallbackRegistration;
PINT_CALLBACK_OBJECT CallbackObject;
KIRQL OldIrql;
-
+
PAGED_CODE();
/* Convert Handle to valid Structure Pointer */
/* FUNCTIONS *****************************************************************/
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtSystemDebugControl(DEBUG_CONTROL_CODE ControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
ULONG OutputBufferLength,
PULONG ReturnLength)
{
- switch (ControlCode)
+ switch (ControlCode)
{
case DebugGetTraceInformation:
case DebugSetInternalBreakpoint:
case DebugQuerySpecialCalls:
case DebugDbgBreakPoint:
break;
-
+
case DebugDbgLoadSymbols:
KDB_LOADUSERMODULE_HOOK((PLDR_MODULE) InputBuffer);
break;
-
+
default:
break;
}
-
+
return STATUS_SUCCESS;
}
/*
* @implemented
*/
-VOID
+VOID
STDCALL
ExRaiseAccessViolation(VOID)
{
/*
* @implemented
*/
-VOID
+VOID
STDCALL
ExRaiseStatus(IN NTSTATUS Status)
{
ExceptionRecord.NumberParameters = 0;
ExceptionRecord.ExceptionCode = Status;
ExceptionRecord.ExceptionFlags = 0;
-
+
/* Call the Rtl Function */
RtlRaiseException(&ExceptionRecord);
}
VOID
STDCALL
ExRaiseHardError(IN NTSTATUS ErrorStatus,
- IN ULONG NumberOfParameters,
+ IN ULONG NumberOfParameters,
IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL,
- IN PVOID *Parameters,
- IN HARDERROR_RESPONSE_OPTION ResponseOption,
+ IN PVOID *Parameters,
+ IN HARDERROR_RESPONSE_OPTION ResponseOption,
OUT PHARDERROR_RESPONSE Response)
{
UNIMPLEMENTED;
}
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtRaiseHardError(IN NTSTATUS ErrorStatus,
IN ULONG NumberOfParameters,
IN PUNICODE_STRING UnicodeStringParameterMask OPTIONAL,
OUT PHARDERROR_RESPONSE Response)
{
DPRINT1("Hard error %x\n", ErrorStatus);
-
+
/* Call the Executive Function (WE SHOULD PUT SEH HERE/CAPTURE!) */
ExRaiseHardError(ErrorStatus,
NumberOfParameters,
Parameters,
ResponseOption,
Response);
-
+
/* Return Success */
return STATUS_SUCCESS;
}
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtSetDefaultHardErrorPort(IN HANDLE PortHandle)
{
-
+
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_UNSUCCESSFUL;
-
+
/* Check if we have the Privilege */
if(!SeSinglePrivilegeCheck(SeTcbPrivilege, PreviousMode)) {
-
+
DPRINT1("NtSetDefaultHardErrorPort: Caller requires the SeTcbPrivilege privilege!\n");
return STATUS_PRIVILEGE_NOT_HELD;
}
-
+
/* Only called once during bootup, make sure we weren't called yet */
if(!ExReadyForErrors) {
-
+
Status = ObReferenceObjectByHandle(PortHandle,
0,
LpcPortObjectType,
PreviousMode,
(PVOID*)&ExpDefaultErrorPort,
NULL);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Save the data */
ExpDefaultErrorPortProcess = PsGetCurrentProcess();
ExReadyForErrors = TRUE;
}
}
-
+
return Status;
}
-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/nt/event.c
* PURPOSE: Named event support
- *
+ *
* PROGRAMMERS: Alex Ionescu(alex@relsoft.net) - Fixed bugs/commented
* Philip Susi and David Welch
*/
EVENT_ALL_ACCESS};
static const INFORMATION_CLASS_INFO ExEventInfoClass[] = {
-
+
/* EventBasicInformation */
ICI_SQ_SAME( sizeof(EVENT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY),
};
/* FUNCTIONS *****************************************************************/
-VOID
+VOID
INIT_FUNCTION
ExpInitializeEventImplementation(VOID)
{
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtClearEvent(IN HANDLE EventHandle)
{
PKEVENT Event;
NTSTATUS Status;
-
+
PAGED_CODE();
-
+
/* Reference the Object */
Status = ObReferenceObjectByHandle(EventHandle,
EVENT_MODIFY_STATE,
ExGetPreviousMode(),
(PVOID*)&Event,
NULL);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Clear the Event and Dereference */
KeClearEvent(Event);
ObDereferenceObject(Event);
}
-
+
/* Return Status */
return Status;
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtCreateEvent(OUT PHANDLE EventHandle,
IN ACCESS_MASK DesiredAccess,
PKEVENT Event;
HANDLE hEvent;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtCreateEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
-
+
/* Check Output Safety */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(EventHandle,
sizeof(HANDLE),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Create the Object */
Status = ObCreateObject(PreviousMode,
ExEventObjectType,
0,
0,
(PVOID*)&Event);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Initalize the Event */
KeInitializeEvent(Event,
EventType,
InitialState);
-
+
/* Insert it */
Status = ObInsertObject((PVOID)Event,
NULL,
NULL,
&hEvent);
ObDereferenceObject(Event);
-
+
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*EventHandle = hEvent;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtOpenEvent(OUT PHANDLE EventHandle,
IN ACCESS_MASK DesiredAccess,
HANDLE hEvent;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
- PAGED_CODE();
+
+ PAGED_CODE();
DPRINT("NtOpenEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, DesiredAccess, ObjectAttributes);
/* Check Output Safety */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(EventHandle,
sizeof(HANDLE),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Open the Object */
Status = ObOpenObjectByName(ObjectAttributes,
ExEventObjectType,
DesiredAccess,
NULL,
&hEvent);
-
+
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*EventHandle = hEvent;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
-
+
/* Return status */
return Status;
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtPulseEvent(IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL)
PKEVENT Event;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtPulseEvent(EventHandle 0%x PreviousState 0%x)\n",
EventHandle, PreviousState);
/* Check buffer validity */
if(PreviousState && PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(PreviousState,
sizeof(LONG),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Open the Object */
Status = ObReferenceObjectByHandle(EventHandle,
EVENT_MODIFY_STATE,
PreviousMode,
(PVOID*)&Event,
NULL);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
-
+
/* Pulse the Event */
LONG Prev = KePulseEvent(Event, EVENT_INCREMENT, FALSE);
ObDereferenceObject(Event);
-
- /* Return it */
+
+ /* Return it */
if(PreviousState) {
-
+
_SEH_TRY {
-
+
*PreviousState = Prev;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtQueryEvent(IN HANDLE EventHandle,
IN EVENT_INFORMATION_CLASS EventInformationClass,
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
PEVENT_BASIC_INFORMATION BasicInfo = (PEVENT_BASIC_INFORMATION)EventInformation;
-
+
PAGED_CODE();
DPRINT("NtQueryEvent(0x%x, 0x%x, 0x%x)\n", EventHandle, EventInformationClass);
-
+
/* Check buffers and class validity */
DefaultQueryInfoBufferCheck(EventInformationClass,
ExEventInfoClass,
PreviousMode,
&Status);
if(!NT_SUCCESS(Status)) {
-
+
/* Invalid buffers */
DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
return Status;
}
-
+
/* Get the Object */
Status = ObReferenceObjectByHandle(EventHandle,
EVENT_QUERY_STATE,
PreviousMode,
(PVOID*)&Event,
NULL);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
_SEH_TRY {
-
+
/* Return Event Type and State */
BasicInfo->EventType = Event->Header.Type;
BasicInfo->EventState = KeReadStateEvent(Event);
/* Return length */
if(ReturnLength) *ReturnLength = sizeof(EVENT_BASIC_INFORMATION);
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
/* Dereference the Object */
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtResetEvent(IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL)
PKEVENT Event;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtResetEvent(EventHandle 0%x PreviousState 0%x)\n",
EventHandle, PreviousState);
/* Check buffer validity */
if(PreviousState && PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(PreviousState,
sizeof(LONG),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
PreviousMode,
(PVOID*)&Event,
NULL);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
-
+
/* Reset the Event */
LONG Prev = KeResetEvent(Event);
ObDereferenceObject(Event);
-
- /* Return it */
+
+ /* Return it */
if(PreviousState) {
-
+
_SEH_TRY {
-
+
*PreviousState = Prev;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtSetEvent(IN HANDLE EventHandle,
OUT PLONG PreviousState OPTIONAL)
PKEVENT Event;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtSetEvent(EventHandle 0%x PreviousState 0%x)\n",
EventHandle, PreviousState);
/* Check buffer validity */
if(PreviousState != NULL && PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(PreviousState,
sizeof(LONG),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
PreviousMode,
(PVOID*)&Event,
NULL);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
LONG Prev = KeSetEvent(Event, EVENT_INCREMENT, FALSE);
ObDereferenceObject(Event);
- /* Return it */
+ /* Return it */
if(PreviousState) {
-
+
_SEH_TRY {
-
+
*PreviousState = Prev;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
HANDLE hEventPair;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtCreateEventPair: %x\n", EventPairHandle);
-
+
/* Check Output Safety */
if(PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(EventPairHandle,
sizeof(HANDLE),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Create the Object */
DPRINT("Creating EventPair\n");
Status = ObCreateObject(PreviousMode,
0,
0,
(PVOID*)&EventPair);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Initalize the Event */
DPRINT("Initializing EventPair\n");
KeInitializeEventPair(EventPair);
-
+
/* Insert it */
Status = ObInsertObject((PVOID)EventPair,
NULL,
NULL,
&hEventPair);
ObDereferenceObject(EventPair);
-
+
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*EventPairHandle = hEventPair;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
return Status;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtOpenEventPair(OUT PHANDLE EventPairHandle,
IN ACCESS_MASK DesiredAccess,
HANDLE hEventPair;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
/* Check Output Safety */
if(PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(EventPairHandle,
sizeof(HANDLE),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Open the Object */
Status = ObOpenObjectByName(ObjectAttributes,
ExEventPairObjectType,
DesiredAccess,
NULL,
&hEventPair);
-
+
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*EventPairHandle = hEventPair;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
-
+
/* Return status */
return Status;
}
PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("NtSetHighEventPair(EventPairHandle %x)\n", EventPairHandle);
-
+
/* Open the Object */
Status = ObReferenceObjectByHandle(EventPairHandle,
SYNCHRONIZE,
PreviousMode,
(PVOID*)&EventPair,
NULL);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Set the Event */
KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
/* Dereference Object */
ObDereferenceObject(EventPair);
}
-
+
/* Return status */
return Status;
}
PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
-
+
/* Open the Object */
Status = ObReferenceObjectByHandle(EventPairHandle,
SYNCHRONIZE,
PreviousMode,
(PVOID*)&EventPair,
NULL);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Set the Event */
KeSetEvent(&EventPair->HighEvent, EVENT_INCREMENT, FALSE);
-
+
/* Wait for the Other one */
KeWaitForSingleObject(&EventPair->LowEvent,
WrEventPair,
/* Dereference Object */
ObDereferenceObject(EventPair);
}
-
+
/* Return status */
return Status;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtSetLowEventPair(IN HANDLE EventPairHandle)
{
PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
DPRINT1("NtSetHighEventPair(EventPairHandle %x)\n", EventPairHandle);
-
+
/* Open the Object */
Status = ObReferenceObjectByHandle(EventPairHandle,
SYNCHRONIZE,
PreviousMode,
(PVOID*)&EventPair,
NULL);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Set the Event */
KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
/* Dereference Object */
ObDereferenceObject(EventPair);
}
-
+
/* Return status */
return Status;
}
PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
-
+
/* Open the Object */
Status = ObReferenceObjectByHandle(EventPairHandle,
SYNCHRONIZE,
PreviousMode,
(PVOID*)&EventPair,
NULL);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Set the Event */
KeSetEvent(&EventPair->LowEvent, EVENT_INCREMENT, FALSE);
-
+
/* Wait for the Other one */
KeWaitForSingleObject(&EventPair->HighEvent,
WrEventPair,
/* Dereference Object */
ObDereferenceObject(EventPair);
}
-
+
/* Return status */
return Status;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtWaitLowEventPair(IN HANDLE EventPairHandle)
{
PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
-
+
/* Open the Object */
Status = ObReferenceObjectByHandle(EventPairHandle,
SYNCHRONIZE,
PreviousMode,
(PVOID*)&EventPair,
NULL);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Wait for the Event */
KeWaitForSingleObject(&EventPair->LowEvent,
WrEventPair,
/* Dereference Object */
ObDereferenceObject(EventPair);
}
-
+
/* Return status */
return Status;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtWaitHighEventPair(IN HANDLE EventPairHandle)
{
PKEVENT_PAIR EventPair;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("NtSetHighWaitLowEventPair(EventPairHandle %x)\n", EventPairHandle);
-
+
/* Open the Object */
Status = ObReferenceObjectByHandle(EventPairHandle,
SYNCHRONIZE,
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Wait for the Event */
KeWaitForSingleObject(&EventPair->HighEvent,
WrEventPair,
/* Dereference Object */
ObDereferenceObject(EventPair);
}
-
+
/* Return status */
return Status;
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/fmutex.c
* PURPOSE: Implements fast mutexes
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/handle.c
* PURPOSE: Generic Executive Handle Tables
- *
+ *
* PROGRAMMERS: Thomas Weidenmueller <w3seek@reactos.com>
*
* TODO:
ExCreateHandleTable(IN PEPROCESS QuotaProcess OPTIONAL)
{
PHANDLE_TABLE HandleTable;
-
+
PAGED_CODE();
-
+
if(!ExpInitialized)
{
KEBUGCHECK(0);
}
-
+
if(QuotaProcess != NULL)
{
/* FIXME - Charge process quota before allocating the handle table! */
{
/* FIXME - return the quota to the process */
}
-
+
return HandleTable;
}
{
PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp;
PEPROCESS QuotaProcess;
-
+
PAGED_CODE();
-
+
ASSERT(HandleTable);
-
+
KeEnterCriticalRegion();
-
+
/* ensure there's no other operations going by acquiring an exclusive lock */
ExAcquireHandleTableLockExclusive(HandleTable);
-
+
ASSERT(!(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING));
-
+
HandleTable->Flags |= EX_HANDLE_TABLE_CLOSING;
-
+
KePulseEvent(&HandleTable->HandleContentionEvent,
EVENT_INCREMENT,
FALSE);
-
+
/* remove the handle table from the global handle table list */
ExAcquireHandleTableListLock();
RemoveEntryList(&HandleTable->HandleTableList);
ExReleaseHandleTableListLock();
-
+
/* call the callback function to cleanup the objects associated with the
handle table */
if(DestroyHandleCallback != NULL)
if((*mlp) != NULL)
{
PHANDLE_TABLE_ENTRY curee, laste;
-
+
for(curee = *mlp, laste = *mlp + N_SUBHANDLE_ENTRIES;
curee != laste;
curee++)
}
}
}
-
+
QuotaProcess = HandleTable->QuotaProcess;
-
+
/* free the tables */
for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS;
tlp != lasttlp;
if((*mlp) != NULL)
{
ExFreePool(*mlp);
-
+
if(QuotaProcess != NULL)
{
/* FIXME - return the quota to the process */
}
ExFreePool(*tlp);
-
+
if(QuotaProcess != NULL)
{
/* FIXME - return the quota to the process */
}
}
}
-
+
ExReleaseHandleTableLock(HandleTable);
-
+
KeLeaveCriticalRegion();
-
+
/* free the handle table */
ExDeleteResource(&HandleTable->HandleTableLock);
ExFreePool(HandleTable);
-
+
if(QuotaProcess != NULL)
{
/* FIXME - return the quota to the process */
IN PHANDLE_TABLE SourceHandleTable)
{
PHANDLE_TABLE HandleTable;
-
+
PAGED_CODE();
-
+
ASSERT(SourceHandleTable);
HandleTable = ExCreateHandleTable(QuotaProcess);
{
PHANDLE_TABLE_ENTRY **tlp, **srctlp, **etlp, *mlp, *srcmlp, *emlp, stbl, srcstbl, estbl;
LONG tli, mli, eli;
-
+
tli = mli = eli = 0;
-
+
/* make sure the other handle table isn't being changed during the duplication */
ExAcquireHandleTableLockShared(SourceHandleTable);
-
+
/* allocate enough tables */
etlp = SourceHandleTable->Table + N_TOPLEVEL_POINTERS;
for(srctlp = SourceHandleTable->Table, tlp = HandleTable->Table;
{
/* FIXME - Charge process quota before allocating the handle table! */
}
-
+
*tlp = ExAllocatePoolWithTag(PagedPool,
N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY),
TAG('E', 'x', 'H', 't'));
if(*tlp != NULL)
{
RtlZeroMemory(*tlp, N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY));
-
+
KeMemoryBarrier();
-
+
emlp = *srctlp + N_MIDDLELEVEL_POINTERS;
for(srcmlp = *srctlp, mlp = *tlp;
srcmlp != emlp;
DPRINT1("Failed to duplicate handle table 0x%x\n", SourceHandleTable);
ExReleaseHandleTableLock(SourceHandleTable);
-
+
ExDestroyHandleTable(HandleTable,
NULL,
NULL);
}
}
}
-
+
/* release the source handle table */
ExReleaseHandleTableLock(SourceHandleTable);
}
-
+
return HandleTable;
}
OUT PLONG Handle)
{
PHANDLE_TABLE_ENTRY Entry = NULL;
-
+
PAGED_CODE();
-
+
ASSERT(HandleTable);
ASSERT(Handle);
ASSERT(KeGetCurrentThread() != NULL);
-
+
DPRINT("HT[0x%x]: HandleCount: %d\n", HandleTable, HandleTable->HandleCount);
-
+
if(HandleTable->HandleCount < EX_MAX_HANDLES)
{
ULONG tli, mli, eli;
-
+
if(HandleTable->FirstFreeTableEntry != -1)
{
/* there's a free handle entry we can just grab and use */
tli = TLI_FROM_HANDLE(HandleTable->FirstFreeTableEntry);
mli = MLI_FROM_HANDLE(HandleTable->FirstFreeTableEntry);
eli = ELI_FROM_HANDLE(HandleTable->FirstFreeTableEntry);
-
+
/* the pointer should be valid in any way!!! */
ASSERT(HandleTable->Table[tli]);
ASSERT(HandleTable->Table[tli][mli]);
-
+
Entry = &HandleTable->Table[tli][mli][eli];
-
+
*Handle = HandleTable->FirstFreeTableEntry;
-
+
/* save the index to the next free handle (if available) */
HandleTable->FirstFreeTableEntry = Entry->u2.NextFreeTableEntry;
Entry->u2.NextFreeTableEntry = 0;
Entry->u1.Object = NULL;
-
+
HandleTable->HandleCount++;
}
else
BOOLEAN AllocatedMtbl;
ASSERT(HandleTable->NextIndexNeedingPool <= N_MAX_HANDLE);
-
+
/* the index of the next table to be allocated was saved in
NextIndexNeedingPool the last time a handle entry was allocated and
the subhandle entry list was full. the subhandle entry index of
ASSERT(ELI_FROM_HANDLE(HandleTable->NextIndexNeedingPool) == 0);
DPRINT("HandleTable->Table[%d] == 0x%x\n", tli, HandleTable->Table[tli]);
-
+
/* allocate a middle level entry list if required */
nmtbl = HandleTable->Table[tli];
if(nmtbl == NULL)
{
/* FIXME - Charge process quota before allocating the handle table! */
}
-
+
nmtbl = ExAllocatePoolWithTag(PagedPool,
N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY),
TAG('E', 'x', 'H', 't'));
{
/* FIXME - return the quota to the process */
}
-
+
return NULL;
}
-
+
/* clear the middle level entry list */
RtlZeroMemory(nmtbl, N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY));
-
+
/* make sure the table was zeroed before we set one item */
KeMemoryBarrier();
-
+
/* note, don't set the the pointer in the top level list yet because we
might screw up lookups if allocating a subhandle entry table failed
and this newly allocated table might get freed again */
else
{
AllocatedMtbl = FALSE;
-
+
/* allocate a subhandle entry table in any case! */
ASSERT(nmtbl[mli] == NULL);
}
{
/* FIXME - Return process quota charged */
}
-
+
/* free the middle level entry list, if allocated, because it's empty and
unused */
if(AllocatedMtbl)
{
ExFreePool(nmtbl);
-
+
if(HandleTable->QuotaProcess != NULL)
{
/* FIXME - Return process quota charged */
}
}
-
+
return NULL;
}
-
+
/* let's just use the very first entry */
Entry = ntbl;
Entry->u1.ObAttributes = EX_HANDLE_ENTRY_LOCKED;
Entry->u2.NextFreeTableEntry = 0;
-
+
*Handle = HandleTable->NextIndexNeedingPool;
-
+
HandleTable->HandleCount++;
-
+
/* set the FirstFreeTableEntry member to the second entry and chain the
free entries */
HandleTable->FirstFreeTableEntry = HandleTable->NextIndexNeedingPool + 1;
{
InterlockedExchangePointer(&HandleTable->Table[tli], nmtbl);
}
-
+
/* increment the NextIndexNeedingPool to the next index where we need to
allocate new memory */
HandleTable->NextIndexNeedingPool += N_SUBHANDLE_ENTRIES;
{
DPRINT1("Can't allocate any more handles in handle table 0x%x!\n", HandleTable);
}
-
+
return Entry;
}
IN LONG Handle)
{
PAGED_CODE();
-
+
ASSERT(HandleTable);
ASSERT(Entry);
ASSERT(IS_VALID_EX_HANDLE(Handle));
-
+
DPRINT("ExpFreeHandleTableEntry HT:0x%x Entry:0x%x\n", HandleTable, Entry);
-
+
/* automatically unlock the entry if currently locked. We however don't notify
anyone who waited on the handle because we're holding an exclusive lock after
all and these locks will fail then */
InterlockedExchangePointer(&Entry->u1.Object, NULL);
Entry->u2.NextFreeTableEntry = HandleTable->FirstFreeTableEntry;
HandleTable->FirstFreeTableEntry = Handle;
-
+
HandleTable->HandleCount--;
}
IN LONG Handle)
{
PHANDLE_TABLE_ENTRY Entry = NULL;
-
+
PAGED_CODE();
-
+
ASSERT(HandleTable);
-
+
if(IS_VALID_EX_HANDLE(Handle))
{
ULONG tli, mli, eli;
PHANDLE_TABLE_ENTRY *mlp;
-
+
tli = TLI_FROM_HANDLE(Handle);
mli = MLI_FROM_HANDLE(Handle);
eli = ELI_FROM_HANDLE(Handle);
-
+
mlp = HandleTable->Table[tli];
if(Handle < HandleTable->NextIndexNeedingPool &&
mlp != NULL && mlp[mli] != NULL && mlp[mli][eli].u1.Object != NULL)
{
DPRINT("Looking up invalid handle 0x%x\n", Handle);
}
-
+
return Entry;
}
ULONG_PTR Current, New;
PAGED_CODE();
-
+
DPRINT("Entering handle table entry 0x%x lock...\n", Entry);
-
+
ASSERT(HandleTable);
ASSERT(Entry);
-
+
for(;;)
{
Current = (volatile ULONG_PTR)Entry->u1.Object;
-
+
if(!Current || (HandleTable->Flags & EX_HANDLE_TABLE_CLOSING))
{
DPRINT("Attempted to lock empty handle table entry 0x%x or handle table shut down\n", Entry);
break;
}
-
+
if(!(Current & EX_HANDLE_ENTRY_LOCKED))
{
New = Current | EX_HANDLE_ENTRY_LOCKED;
IN PHANDLE_TABLE_ENTRY Entry)
{
ULONG_PTR Current, New;
-
+
PAGED_CODE();
-
+
ASSERT(HandleTable);
ASSERT(Entry);
-
+
DPRINT("ExUnlockHandleTableEntry HT:0x%x Entry:0x%x\n", HandleTable, Entry);
-
+
Current = (volatile ULONG_PTR)Entry->u1.Object;
ASSERT(Current & EX_HANDLE_ENTRY_LOCKED);
-
+
New = Current & ~EX_HANDLE_ENTRY_LOCKED;
-
+
InterlockedExchangePointer(&Entry->u1.Object,
(PVOID)New);
{
PHANDLE_TABLE_ENTRY NewHandleTableEntry;
LONG Handle = EX_INVALID_HANDLE;
-
+
PAGED_CODE();
-
+
ASSERT(HandleTable);
ASSERT(Entry);
-
+
/* The highest bit in Entry->u1.Object has to be 1 so we make sure it's a
pointer to kmode memory. It will cleared though because it also indicates
the lock */
ASSERT((ULONG_PTR)Entry->u1.Object & EX_HANDLE_ENTRY_LOCKED);
-
+
KeEnterCriticalRegion();
ExAcquireHandleTableLockExclusive(HandleTable);
-
+
NewHandleTableEntry = ExpAllocateHandleTableEntry(HandleTable,
&Handle);
if(NewHandleTableEntry != NULL)
{
*NewHandleTableEntry = *Entry;
-
+
ExUnlockHandleTableEntry(HandleTable,
NewHandleTableEntry);
}
{
PHANDLE_TABLE_ENTRY HandleTableEntry;
BOOLEAN Ret = FALSE;
-
+
PAGED_CODE();
-
+
ASSERT(HandleTable);
-
+
KeEnterCriticalRegion();
ExAcquireHandleTableLockExclusive(HandleTable);
-
+
HandleTableEntry = ExpLookupHandleTableEntry(HandleTable,
Handle);
-
+
if(HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry))
{
/* free and automatically unlock the handle. However we don't need to pulse
Handle);
Ret = TRUE;
}
-
+
ExReleaseHandleTableLock(HandleTable);
KeLeaveCriticalRegion();
-
+
return Ret;
}
ASSERT(HandleTable);
ASSERT(Entry);
-
+
/* This routine requires the entry to be locked */
ASSERT((ULONG_PTR)Entry->u1.Object & EX_HANDLE_ENTRY_LOCKED);
-
+
DPRINT("DestroyHandleByEntry HT:0x%x Entry:0x%x\n", HandleTable, Entry);
KeEnterCriticalRegion();
PAGED_CODE();
ASSERT(HandleTable);
-
+
HandleTableEntry = ExpLookupHandleTableEntry(HandleTable,
Handle);
if (HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry))
DPRINT("ExMapHandleToPointer HT:0x%x Entry:0x%x locked\n", HandleTable, HandleTableEntry);
return HandleTableEntry;
}
-
+
return NULL;
}
ASSERT(ChangeHandleCallback);
KeEnterCriticalRegion();
-
+
HandleTableEntry = ExpLookupHandleTableEntry(HandleTable,
Handle);
ExUnlockHandleTableEntry(HandleTable,
HandleTableEntry);
}
-
+
KeLeaveCriticalRegion();
return Ret;
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/i386/interlck.c
#ifdef CONFIG_SMP
#define LOCK lock
#else
-#define LOCK
+#define LOCK
#endif
#endif
LONG FASTCALL
InterlockedIncrement(PLONG Addend);
/*
- * FUNCTION: Increments a caller supplied variable of type LONG as an
+ * FUNCTION: Increments a caller supplied variable of type LONG as an
* atomic operation
* ARGUMENTS:
* Addend = Points to a variable whose value is to be increment
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/init.c
* PURPOSE: Executive initalization
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Added ExpInitializeExecutive
* and optimized/cleaned it.
* Eric Kohl (ekohl@abo.rhein-zeitung.de)
/* FUNCTIONS ****************************************************************/
-static
-VOID
+static
+VOID
INIT_FUNCTION
InitSystemSharedUserPage (PCSZ ParameterLine)
{
* There is NO need to do this again.
*/
Ki386SetProcessorFeatures();
-
+
/* Set the Version Data */
SharedUserData->NtProductType = NtProductWinNt;
SharedUserData->ProductTypeIsValid = TRUE;
SharedUserData->NtMajorVersion = 5;
SharedUserData->NtMinorVersion = 0;
-
+
/*
* Retrieve the current dos system path
* (e.g.: C:\reactos) from the given arc path
/* Extract path */
p = strchr (ParamBuffer, '\\');
if (p) {
-
+
DPRINT("Boot path: %s\n", p);
RtlCreateUnicodeStringFromAsciiz (&BootPath, p);
*p = 0;
-
+
} else {
-
+
DPRINT("Boot path: %s\n", "\\");
RtlCreateUnicodeStringFromAsciiz (&BootPath, "\\");
}
DPRINT("Arc name: %s\n", ParamBuffer);
-
+
/* Only ARC Name left - Build full ARC Name */
ArcNameBuffer = ExAllocatePool (PagedPool, 256 * sizeof(WCHAR));
swprintf (ArcNameBuffer, L"\\ArcName\\%S", ParamBuffer);
Status = NtOpenSymbolicLinkObject(&Handle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes);
-
+
/* Free the String */
ExFreePool(ArcName.Buffer);
-
+
/* Check for Success */
if (!NT_SUCCESS(Status)) {
-
+
/* Free the Strings */
RtlFreeUnicodeString(&BootPath);
ExFreePool(ArcDeviceName.Buffer);
CPRINT("NtOpenSymbolicLinkObject() failed (Status %x)\n", Status);
KEBUGCHECK(0);
}
-
+
/* Query the Link */
Status = NtQuerySymbolicLinkObject(Handle,
&ArcDeviceName,
&Length);
NtClose (Handle);
-
+
/* Check for Success */
if (!NT_SUCCESS(Status)) {
-
+
/* Free the Strings */
RtlFreeUnicodeString(&BootPath);
ExFreePool(ArcDeviceName.Buffer);
/* Loop Drives */
for (i = 0; i < 26; i++) {
-
+
/* Setup the String */
swprintf (DriveNameBuffer, L"\\??\\%C:", 'A' + i);
RtlInitUnicodeString(&DriveName,
DriveNameBuffer);
-
+
/* Open the Symbolic Link */
InitializeObjectAttributes(&ObjectAttributes,
&DriveName,
Status = NtOpenSymbolicLinkObject(&Handle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes);
-
+
/* If it failed, skip to the next drive */
if (!NT_SUCCESS(Status)) {
DPRINT("Failed to open link %wZ\n", &DriveName);
continue;
}
-
+
/* Query it */
Status = NtQuerySymbolicLinkObject(Handle,
&DriveDeviceName,
&Length);
-
+
/* If it failed, skip to the next drive */
if (!NT_SUCCESS(Status)) {
DPRINT("Failed to query link %wZ\n", &DriveName);
/* See if we've found the boot drive */
if (!RtlCompareUnicodeString (&ArcDeviceName, &DriveDeviceName, FALSE)) {
-
+
DPRINT("DOS Boot path: %c:%wZ\n", 'A' + i, &BootPath);
swprintf(SharedUserData->NtSystemRoot, L"%C:%wZ", 'A' + i, &BootPath);
BootDriveFound = TRUE;
/* Close this Link */
NtClose (Handle);
}
-
+
/* Free all the Strings we have in memory */
RtlFreeUnicodeString (&BootPath);
ExFreePool(DriveDeviceName.Buffer);
/* Make sure we found the Boot Drive */
if (BootDriveFound == FALSE) {
-
+
DbgPrint("No system drive found!\n");
KEBUGCHECK (NO_BOOT_DEVICE);
}
ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, orig_ebp) == TF_ORIG_EBP);
ASSERT(FIELD_OFFSET(KPCR, Tib.ExceptionList) == KPCR_EXCEPTION_LIST);
ASSERT(FIELD_OFFSET(KPCR, Self) == KPCR_SELF);
- ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD);
+ ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD);
ASSERT(FIELD_OFFSET(KPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
ASSERT(FIELD_OFFSET(KTSS, Esp0) == KTSS_ESP0);
ASSERT(FIELD_OFFSET(KTSS, Eflags) == KTSS_EFLAGS);
{
ULONG i;
PCHAR Name;
-
+
/* Loop the Module List and get the modules we want */
for (i = 1; i < KeLoaderBlock.ModsCount; i++) {
-
+
/* Get the Name of this Module */
if (!(Name = strrchr((PCHAR)KeLoaderModules[i].String, '\\'))) {
-
+
/* Save the name */
Name = (PCHAR)KeLoaderModules[i].String;
-
+
} else {
-
+
/* No name, skip */
Name++;
}
-
+
/* Now check for any of the modules we will need later */
if (!_stricmp(Name, "ansi.nls")) {
-
+
CachedModules[AnsiCodepage] = &KeLoaderModules[i];
-
+
} else if (!_stricmp(Name, "oem.nls")) {
-
+
CachedModules[OemCodepage] = &KeLoaderModules[i];
-
+
} else if (!_stricmp(Name, "casemap.nls")) {
-
+
CachedModules[UnicodeCasemap] = &KeLoaderModules[i];
-
+
} else if (!_stricmp(Name, "system") || !_stricmp(Name, "system.hiv")) {
-
+
CachedModules[SystemRegistry] = &KeLoaderModules[i];
*SetupBoot = FALSE;
-
+
} else if (!_stricmp(Name, "hardware") || !_stricmp(Name, "hardware.hiv")) {
-
+
CachedModules[HardwareRegistry] = &KeLoaderModules[i];
}
- }
+ }
}
inline
VOID
STDCALL
-ParseCommandLine(PULONG MaxMem,
- PBOOLEAN NoGuiBoot,
- PBOOLEAN BootLog,
+ParseCommandLine(PULONG MaxMem,
+ PBOOLEAN NoGuiBoot,
+ PBOOLEAN BootLog,
PBOOLEAN ForceAcpiDisable)
{
- PCHAR p1, p2;
-
+ PCHAR p1, p2;
+
p1 = (PCHAR)KeLoaderBlock.CommandLine;
while(*p1 && (p2 = strchr(p1, '/'))) {
-
+
p2++;
if (!_strnicmp(p2, "MAXMEM", 6)) {
-
+
p2 += 6;
while (isspace(*p2)) p2++;
-
+
if (*p2 == '=') {
-
+
p2++;
-
+
while(isspace(*p2)) p2++;
-
+
if (isdigit(*p2)) {
while (isdigit(*p2)) {
*MaxMem = *MaxMem * 10 + *p2 - '0';
p2++;
- }
+ }
break;
}
}
} else if (!_strnicmp(p2, "NOGUIBOOT", 9)) {
-
+
p2 += 9;
*NoGuiBoot = TRUE;
-
+
} else if (!_strnicmp(p2, "CRASHDUMP", 9)) {
-
+
p2 += 9;
if (*p2 == ':') {
-
+
p2++;
if (!_strnicmp(p2, "FULL", 4)) {
-
+
MmCoreDumpType = MM_CORE_DUMP_TYPE_FULL;
-
+
} else {
-
+
MmCoreDumpType = MM_CORE_DUMP_TYPE_NONE;
}
}
} else if (!_strnicmp(p2, "BOOTLOG", 7)) {
-
+
p2 += 7;
*BootLog = TRUE;
} else if (!_strnicmp(p2, "NOACPI", 6)) {
-
+
p2 += 6;
*ForceAcpiDisable = TRUE;
}
-
+
p1 = p2;
}
}
-VOID
+VOID
INIT_FUNCTION
STDCALL
ExpInitializeExecutive(VOID)
/* Check if the structures match the ASM offset constants */
ExecuteRuntimeAsserts();
-
+
/* Sets up the Text Sections of the Kernel and HAL for debugging */
LdrInit1();
-
+
/* Lower the IRQL to Dispatch Level */
KeLowerIrql(DISPATCH_LEVEL);
-
+
/* Sets up the VDM Data */
NtEarlyInitVdm();
/* Parse Command Line Settings */
ParseCommandLine(&MaxMem, &NoGuiBoot, &BootLog, &ForceAcpiDisable);
-
+
/* Initialize Kernel Memory Address Space */
MmInit1(FirstKrnlPhysAddr,
LastKrnlPhysAddr,
/* Parse the Loaded Modules (by FreeLoader) and cache the ones we'll need */
ParseAndCacheLoadedModules(&SetupBoot);
-
+
/* Initialize the kernel debugger parameters */
KdInitSystem(0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
+
/* Initialize the Dispatcher, Clock and Bug Check Mechanisms. */
KeInit2();
/* Bring back the IRQL to Passive */
KeLowerIrql(PASSIVE_LEVEL);
-
+
/* Initialize Profiling */
InitializeListHead(&KiProfileListHead);
InitializeListHead(&KiProfileSourceListHead);
KeInitializeSpinLock(&KiProfileLock);
-
+
/* Load basic Security for other Managers */
if (!SeInit1()) KEBUGCHECK(SECURITY_INITIALIZATION_FAILED);
/* Create the Basic Object Manager Types to allow new Object Types */
ObInit();
-
+
/* Initialize Lookaside Lists */
ExInit2();
-
+
/* Set up Region Maps, Sections and the Paging File */
MmInit2();
/* Set 1 CPU for now, we'll increment this later */
KeNumberProcessors = 1;
-
+
/* Initalize the Process Manager */
PiInitProcessManager();
/* Initialize all processors */
while (!HalAllProcessorsStarted()) {
-
+
PVOID ProcessorStack;
/* Set up the Kernel and Process Manager for this CPU */
/* Do Phase 1 HAL Initalization */
HalInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
+
/* Initialize Basic System Objects and Worker Threads */
ExInit3();
-
+
/* Create the system handle table, assign it to the system process, create
the client id table and assign a PID for the system process. This needs
to be done before the worker threads are initialized so the system
/* initialize the worker threads */
ExpInitializeWorkerThreads();
-
+
/* initialize callbacks */
ExpInitializeCallbacks();
-
+
/* Call KD Providers at Phase 1 */
KdInitSystem(1, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
+
/* Initialize I/O Objects, Filesystems, Error Logging and Shutdown */
IoInit();
-
+
/* TBD */
PoInit((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock, ForceAcpiDisable);
-
+
/* Initialize the Registry (Hives are NOT yet loaded!) */
CmInitializeRegistry();
-
+
/* Unmap Low memory, initialize the Page Zeroing and the Balancer Thread */
MmInit3();
-
+
/* Initialize Cache Views */
CcInit();
-
+
/* Initialize File Locking */
FsRtlpInitFileLockingImplementation();
/* Report all resources used by hal */
- HalReportResourceUsage();
+ HalReportResourceUsage();
/* Clear the screen to blue */
HalInitSystem(2, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
HalDisplayString("\n\nReactOS is free software, covered by the GNU General "
"Public License, and you\n");
HalDisplayString("are welcome to change it and/or distribute copies of it "
- "under certain\n");
+ "under certain\n");
HalDisplayString("conditions. There is absolutely no warranty for "
"ReactOS.\n\n");
/* Import and Load Registry Hives */
CmInitHives(SetupBoot);
-
+
/* Initialize the time zone information from the registry */
ExpInitTimeZoneInfo();
-
+
/* Enter the kernel debugger before starting up the boot drivers */
KdbEnter();
/* Display the boot screen image if not disabled */
if (!NoGuiBoot) InbvEnableBootDriver(TRUE);
-
+
/* Create ARC Names, SystemRoot SymLink, Load Drivers and Assign Letters */
IoInit3();
-
+
/* Load the System DLL and its Entrypoints */
LdrpInitializeSystemDll();
-
+
/* Initialize the Default Locale */
PiInitDefaultLocale();
-
+
/* Initialize shared user page. Set dos system path, dos device map, etc. */
InitSystemSharedUserPage ((PCHAR)KeLoaderBlock.CommandLine);
&ObjectAttributes,
SynchronizationEvent,
FALSE);
-
+
/* Check for Success */
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1("Failed to create 'ReactOSInitDone' event (Status 0x%x)\n", Status);
InitDoneEventHandle = INVALID_HANDLE_VALUE;
}
/* Launch initial process */
Status = LdrLoadInitialProcess(&ProcessHandle,
&ThreadHandle);
-
+
/* Check for success, Bugcheck if we failed */
if (!NT_SUCCESS(Status)) {
-
+
KEBUGCHECKEX(SESSION4_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
FALSE,
&Timeout);
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1("NtWaitForMultipleObjects failed with status 0x%x!\n", Status);
-
+
} else if (Status == STATUS_TIMEOUT) {
-
+
DPRINT1("WARNING: System not initialized after 120 seconds.\n");
-
+
} else if (Status == STATUS_WAIT_0 + 1) {
-
+
/* Crash the system if the initial process was terminated. */
KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 0, 0, 0);
}
/* Signal the Event and close the handle */
ZwSetEvent(InitDoneEventHandle, NULL);
ZwClose(InitDoneEventHandle);
-
+
} else {
-
+
/* On failure to create 'ReactOSInitDone' event, go to text mode ASAP */
if (!NoGuiBoot) InbvEnableBootDriver(FALSE);
Status = ZwWaitForSingleObject(ProcessHandle,
FALSE,
&Timeout);
-
+
/* Check for timeout, crash if the initial process didn't initalize */
if (Status != STATUS_TIMEOUT) KEBUGCHECKEX(SESSION5_INITIALIZATION_FAILED, Status, 1, 0, 0);
}
-
+
/* Enable the Clock, close remaining handles */
KiTimerSystemAuditing = 1;
ZwClose(ThreadHandle);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/interlck.c
* PURPOSE: Implements interlocked functions
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/*
* ExInterlockedAddUlong adds an unsigned long value to a given unsigned
* integer as an atomic operation.
- *
+ *
* ADDEND = Points to an unsigned long integer whose value is to be adjusted
* by the Increment value.
- *
+ *
* INCREMENT = Is an unsigned long integer to be added.
- *
+ *
* LOCK = Points to a spinlock to be used to synchronize access to ADDEND.
- *
- * Returns:
- *
+ *
+ * Returns:
+ *
* The original value of the unsigned integer pointed to by ADDEND.
*/
{
PKSPIN_LOCK Lock)
/*
* Adds two large integer values as an atomic operation.
- *
+ *
* ADDEND = Pointer to a large integer value that will have INCREMENT added.
- *
+ *
* INCREMENT = Value to be added.
- *
+ *
* LOCK = Spinlock used to synchronize access to ADDEND.
- *
+ *
* Returns:
- *
+ *
* The original value of the large integer pointed to by ADDEND.
*/
{
/*
* ExInterlockedAddUlong adds an unsigned long value to a given unsigned
* integer as an atomic operation.
- *
+ *
* ADDEND = Points to an unsigned long integer whose value is to be adjusted
* by the Increment value.
- *
+ *
* INCREMENT = Is an unsigned long integer to be added.
- *
+ *
* LOCK = Points to a spinlock to be used to synchronize access to ADDEND.
- *
- * Returns:
- *
+ *
+ * Returns:
+ *
* The original value of the unsigned integer pointed to by ADDEND.
*/
{
{
SLIST_HEADER newslh, oldslh;
PSLIST_ENTRY le;
-
+
do
{
oldslh = *(volatile SLIST_HEADER *)ListHead;
IN PSLIST_ENTRY ListEntry)
{
SLIST_HEADER newslh, oldslh;
-
+
newslh.Next.Next = ListEntry;
-
+
do
{
oldslh = *(volatile SLIST_HEADER *)ListHead;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/lookas.c
* PURPOSE: Lookaside lists
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/mutant.c
* PURPOSE: Executive Management of Mutants
- *
+ *
* PROGRAMMERS: Alex Ionescu - Fix tab/space mismatching, tiny fixes to query function and
* add more debug output.
* David Welch (welch@cwcom.net)
MUTANT_ALL_ACCESS};
static const INFORMATION_CLASS_INFO ExMutantInfoClass[] = {
-
+
/* MutantBasicInformation */
ICI_SQ_SAME( sizeof(MUTANT_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
};
/* FUNCTIONS *****************************************************************/
-VOID
+VOID
STDCALL
ExpDeleteMutant(PVOID ObjectBody)
{
FALSE);
}
-VOID
+VOID
INIT_FUNCTION
ExpInitializeMutantImplementation(VOID)
{
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtCreateMutant(OUT PHANDLE MutantHandle,
IN ACCESS_MASK DesiredAccess,
HANDLE hMutant;
PKMUTANT Mutant;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtCreateMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
-
+
/* Check Output Safety */
if(PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(MutantHandle,
sizeof(HANDLE),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Create the Mutant Object*/
Status = ObCreateObject(PreviousMode,
ExMutantObjectType,
0,
0,
(PVOID*)&Mutant);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
-
+
/* Initalize the Kernel Mutant */
DPRINT("Initializing the Mutant\n");
KeInitializeMutant(Mutant, InitialOwner);
NULL,
&hMutant);
ObDereferenceObject(Mutant);
-
+
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*MutantHandle = hMutant;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtOpenMutant(OUT PHANDLE MutantHandle,
IN ACCESS_MASK DesiredAccess,
HANDLE hMutant;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtOpenMutant(0x%x, 0x%x, 0x%x)\n", MutantHandle, DesiredAccess, ObjectAttributes);
/* Check Output Safety */
if(PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(MutantHandle,
sizeof(HANDLE),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Open the Object */
Status = ObOpenObjectByName(ObjectAttributes,
ExMutantObjectType,
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*MutantHandle = hMutant;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtQueryMutant(IN HANDLE MutantHandle,
IN MUTANT_INFORMATION_CLASS MutantInformationClass,
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
PMUTANT_BASIC_INFORMATION BasicInfo = (PMUTANT_BASIC_INFORMATION)MutantInformation;
-
+
PAGED_CODE();
-
+
/* Check buffers and parameters */
DefaultQueryInfoBufferCheck(MutantInformationClass,
ExMutantInfoClass,
PreviousMode,
&Status);
if(!NT_SUCCESS(Status)) {
-
+
DPRINT("NtQueryMutant() failed, Status: 0x%x\n", Status);
return Status;
}
if(NT_SUCCESS(Status)) {
_SEH_TRY {
-
+
/* Fill out the Basic Information Requested */
DPRINT("Returning Mutant Information\n");
BasicInfo->CurrentCount = KeReadStateMutant(Mutant);
/* Return the Result Length if requested */
if(ResultLength) *ResultLength = sizeof(MUTANT_BASIC_INFORMATION);
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
/* Release the Object */
ObDereferenceObject(Mutant);
}
-
+
/* Return Status */
return Status;
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtReleaseMutant(IN HANDLE MutantHandle,
IN PLONG PreviousCount OPTIONAL)
PKMUTANT Mutant;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
- DPRINT("NtReleaseMutant(MutantHandle 0%x PreviousCount 0%x)\n",
- MutantHandle,
+
+ DPRINT("NtReleaseMutant(MutantHandle 0%x PreviousCount 0%x)\n",
+ MutantHandle,
PreviousCount);
/* Check Output Safety */
if(PreviousMode != KernelMode && PreviousCount) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(PreviousCount,
sizeof(LONG),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
- }
+ }
/* Open the Object */
Status = ObReferenceObjectByHandle(MutantHandle,
PreviousMode,
(PVOID*)&Mutant,
NULL);
-
+
/* Check for Success and release if such */
if(NT_SUCCESS(Status)) {
-
+
LONG Prev = 0;
-
+
/* release the mutant. doing so might raise an exception which we're
required to catch! */
_SEH_TRY {
Status = _SEH_GetExceptionCode();
} _SEH_END;
-
+
ObDereferenceObject(Mutant);
if(NT_SUCCESS(Status)) {
*PreviousCount = Prev;
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
} _SEH_END;
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/power.c
* PURPOSE: Power managment
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
VOID STDCALL
ShutdownThreadMain(PVOID Context)
{
- SHUTDOWN_ACTION Action = (SHUTDOWN_ACTION)Context;
+ SHUTDOWN_ACTION Action = (SHUTDOWN_ACTION)Context;
LARGE_INTEGER Waittime;
/* Run the thread on the boot processor */
PiShutdownProcessManager();
MiShutdownMemoryManager();
-
+
Waittime.QuadPart = (LONGLONG)-10000000; /* 1sec */
KeDelayExecutionThread(KernelMode, FALSE, &Waittime);
}
-NTSTATUS STDCALL
+NTSTATUS STDCALL
NtSetSystemPowerState(IN POWER_ACTION SystemAction,
IN SYSTEM_POWER_STATE MinSystemState,
IN ULONG Flags)
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS STDCALL
NtShutdownSystem(IN SHUTDOWN_ACTION Action)
{
NTSTATUS Status;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/profile.c
* PURPOSE: Support for Executive Profile Objects
- *
+ *
* PROGRAMMERS: Alex Ionescu
*/
STANDARD_RIGHTS_EXECUTE | PROFILE_CONTROL,
STANDARD_RIGHTS_ALL};
-VOID
+VOID
STDCALL
ExpDeleteProfile(PVOID ObjectBody)
{
/* Typecast the Object */
Profile = (PEPROFILE)ObjectBody;
-
+
/* Check if there if the Profile was started */
if (Profile->LockedBuffer) {
-
+
/* Stop the Profile */
KeStopProfile(Profile->KeProfile);
-
+
/* Unmap the Locked Buffer */
MmUnmapLockedPages(Profile->LockedBuffer, Profile->Mdl);
MmUnlockPages(Profile->Mdl);
ExFreePool(Profile->Mdl);
}
-
+
/* Check if a Process is associated */
if (Profile->Process != NULL) {
-
+
/* Dereference it */
ObDereferenceObject(Profile->Process);
Profile->Process = NULL;
}
}
-VOID
+VOID
INIT_FUNCTION
ExpInitializeProfileImplementation(VOID)
{
/* Initialize the Mutex to lock the States */
KeInitializeMutex(&ExpProfileMutex, 0x40);
-
+
/* Create the Object Type */
ExProfileObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
RtlInitUnicodeString(&ExProfileObjectType->TypeName, L"Profile");
ObpCreateTypeObject(ExProfileObjectType);
}
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtCreateProfile(OUT PHANDLE ProfileHandle,
IN HANDLE Process OPTIONAL,
- IN PVOID ImageBase,
- IN ULONG ImageSize,
+ IN PVOID ImageBase,
+ IN ULONG ImageSize,
IN ULONG BucketSize,
IN PVOID Buffer,
IN ULONG BufferSize,
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
/* Easy way out */
/* Check the Parameters for validity */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(ProfileHandle,
sizeof(HANDLE),
sizeof(ULONG));
-
+
ProbeForWrite(Buffer,
BufferSize,
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
/* Check if a process was specified */
if (Process) {
-
+
/* Reference it */
Status = ObReferenceObjectByHandle(Process,
PROCESS_QUERY_INFORMATION,
(PVOID*)&pProcess,
NULL);
if (!NT_SUCCESS(Status)) return(Status);
-
+
} else {
-
+
/* No process was specified, which means a System-Wide Profile */
pProcess = NULL;
-
+
/* For this, we need to check the Privilege */
if(!SeSinglePrivilegeCheck(SeSystemProfilePrivilege, PreviousMode)) {
-
+
DPRINT1("NtCreateProfile: Caller requires the SeSystemProfilePrivilege privilege!\n");
return STATUS_PRIVILEGE_NOT_HELD;
}
Profile->LockedBuffer = NULL;
Profile->Affinity = Affinity;
Profile->Process = pProcess;
-
+
/* Insert into the Object Tree */
Status = ObInsertObject ((PVOID)Profile,
NULL,
NULL,
&hProfile);
ObDereferenceObject(Profile);
-
+
/* Check for Success */
if (!NT_SUCCESS(Status)) {
-
+
/* Dereference Process on failure */
if (pProcess) ObDereferenceObject(pProcess);
return Status;
}
-
+
/* Copy the created handle back to the caller*/
_SEH_TRY {
-
+
*ProfileHandle = hProfile;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
} _SEH_END;
return Status;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtQueryPerformanceCounter(OUT PLARGE_INTEGER PerformanceCounter,
OUT PLARGE_INTEGER PerformanceFrequency OPTIONAL)
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
LARGE_INTEGER PerfFrequency;
NTSTATUS Status = STATUS_SUCCESS;
-
+
/* Check the Parameters for validity */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(PerformanceCounter,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
-
+
ProbeForWrite(PerformanceFrequency,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
_SEH_TRY {
-
+
/* Query the Kernel */
*PerformanceCounter = KeQueryPerformanceCounter(&PerfFrequency);
-
+
/* Return Frequency if requested */
if(PerformanceFrequency) {
-
+
*PerformanceFrequency = PerfFrequency;
}
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
return Status;
}
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtStartProfile(IN HANDLE ProfileHandle)
{
PEPROFILE Profile;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PVOID TempLockedBuffer;
NTSTATUS Status;
-
+
PAGED_CODE();
/* Get the Object */
(PVOID*)&Profile,
NULL);
if (!NT_SUCCESS(Status)) return(Status);
-
+
/* To avoid a Race, wait on the Mutex */
- KeWaitForSingleObject(&ExpProfileMutex,
+ KeWaitForSingleObject(&ExpProfileMutex,
Executive,
KernelMode,
FALSE,
NULL);
-
+
/* The Profile can still be enabled though, so handle that */
if (Profile->LockedBuffer) {
-
+
/* Release our lock, dereference and return */
KeReleaseMutex(&ExpProfileMutex, FALSE);
ObDereferenceObject(Profile);
return STATUS_PROFILING_NOT_STOPPED;
}
-
+
/* Allocate a Kernel Profile Object. */
- KeProfile = ExAllocatePoolWithTag(NonPagedPool,
+ KeProfile = ExAllocatePoolWithTag(NonPagedPool,
sizeof(EPROFILE),
TAG('P', 'r', 'o', 'f'));
-
+
/* Allocate the Mdl Structure */
Profile->Mdl = MmCreateMdl(NULL, Profile->Buffer, Profile->BufferSize);
-
+
/* Probe and Lock for Write Access */
MmProbeAndLockPages(Profile->Mdl, PreviousMode, IoWriteAccess);
-
+
/* Map the pages */
TempLockedBuffer = MmMapLockedPages(Profile->Mdl, KernelMode);
-
+
/* Initialize the Kernel Profile Object */
Profile->KeProfile = KeProfile;
KeInitializeProfile(KeProfile,
Profile->BucketSize,
Profile->ProfileSource,
Profile->Affinity);
-
+
/* Start the Profiling */
KeStartProfile(KeProfile, TempLockedBuffer);
-
+
/* Now it's safe to save this */
Profile->LockedBuffer = TempLockedBuffer;
-
+
/* Release mutex, dereference and return */
KeReleaseMutex(&ExpProfileMutex, FALSE);
ObDereferenceObject(Profile);
}
NTSTATUS
-STDCALL
+STDCALL
NtStopProfile(IN HANDLE ProfileHandle)
{
PEPROFILE Profile;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status;
-
+
PAGED_CODE();
/* Get the Object */
(PVOID*)&Profile,
NULL);
if (!NT_SUCCESS(Status)) return(Status);
-
+
/* Get the Mutex */
- KeWaitForSingleObject(&ExpProfileMutex,
+ KeWaitForSingleObject(&ExpProfileMutex,
Executive,
KernelMode,
FALSE,
NULL);
-
+
/* Make sure the Profile Object is really Started */
if (!Profile->LockedBuffer) {
-
+
Status = STATUS_PROFILING_NOT_STARTED;
goto Exit;
}
-
+
/* Stop the Profile */
KeStopProfile(Profile->KeProfile);
-
+
/* Unlock the Buffer */
MmUnmapLockedPages(Profile->LockedBuffer, Profile->Mdl);
MmUnlockPages(Profile->Mdl);
ExFreePool(Profile->KeProfile);
-
+
/* Clear the Locked Buffer pointer, meaning the Object is Stopped */
Profile->LockedBuffer = NULL;
-
+
Exit:
/* Release Mutex, Dereference and Return */
KeReleaseMutex(&ExpProfileMutex, FALSE);
return Status;
}
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtQueryIntervalProfile(IN KPROFILE_SOURCE ProfileSource,
OUT PULONG Interval)
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
ULONG ReturnInterval;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
/* Check the Parameters for validity */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(Interval,
sizeof(ULONG),
sizeof(ULONG));
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Query the Interval */
ReturnInterval = KeQueryIntervalProfile(ProfileSource);
/* Return the data */
_SEH_TRY {
-
+
*Interval = ReturnInterval;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
- /* Return Success */
+
+ /* Return Success */
return STATUS_SUCCESS;
}
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtSetIntervalProfile(IN ULONG Interval,
IN KPROFILE_SOURCE Source)
{
/* Let the Kernel do the job */
KeSetIntervalProfile(Interval, Source);
-
+
/* Nothing can go wrong */
return STATUS_SUCCESS;
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/resource.c
* PURPOSE: Resource synchronization construct
- *
+ *
* PROGRAMMERS: No programmer listed.
*/
*/
{
KIRQL oldIrql;
-
+
DPRINT("ExAcquireResourceExclusiveLite(Resource %x, Wait %d)\n",
Resource, Wait);
-
+
ASSERT_IRQL_LESS(DISPATCH_LEVEL);
-
+
/* undefed for now, since cdfs must be fixed first */
-#if 0
- /* At least regular kmode APC's must be disabled
+#if 0
+ /* At least regular kmode APC's must be disabled
* Note that this requirement is missing in old DDK's */
ASSERT(KeGetCurrentThread() == NULL || /* <-Early in the boot process the current thread is obseved to be NULL */
- KeGetCurrentThread()->KernelApcDisable ||
+ KeGetCurrentThread()->KernelApcDisable ||
KeGetCurrentIrql() == APC_LEVEL);
#endif
DPRINT("ExAcquireResourceExclusiveLite() = FALSE\n");
return(FALSE);
}
-
- /*
+
+ /*
* This is slightly better than it looks because other exclusive
* threads who are waiting won't be woken up but there is a race
* with new threads trying to grab the resource so we must have
* the spinlock, still normally this loop will only be executed
* once
- * NOTE: We might want to set a timeout to detect deadlock
+ * NOTE: We might want to set a timeout to detect deadlock
* (10 minutes?)
*/
- while (Resource->ActiveCount)
+ while (Resource->ActiveCount)
{
Resource->NumberOfExclusiveWaiters++;
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
*/
{
ULONG i;
-
+
if (Resource->OwnerThreads[1].OwnerThread == ResourceThreadId)
{
Resource->OwnerThreads[1].OwnerCount--;
}
return(TRUE);
}
-
- if (Resource->OwnerThreads[1].OwnerThread)
+
+ if (Resource->OwnerThreads[1].OwnerThread)
{
/* Oh dear, the caller didn't own the resource after all */
- return(FALSE);;
+ return(FALSE);
}
-
+
for (i=0; i<Resource->OwnerThreads[1].TableSize; i++)
{
if (Resource->OwnerTable[i].OwnerThread == ResourceThreadId)
ERESOURCE_THREAD CurrentThread = ExGetCurrentResourceThread();
POWNER_ENTRY freeEntry;
ULONG i = 0;
-
+
DPRINT("EiAddSharedOwner(Resource %x)\n", Resource);
-
- if (Resource->ActiveCount == 0)
+
+ if (Resource->ActiveCount == 0)
{
/* no owner, it's easy */
Resource->OwnerThreads[1].OwnerThread = ExGetCurrentResourceThread();
DPRINT("EiAddSharedOwner() = TRUE\n");
return(TRUE);
}
-
- /*
- * now, we must search if this thread has already acquired this resource
- * then increase ownercount if found, else create new entry or reuse free
+
+ /*
+ * now, we must search if this thread has already acquired this resource
+ * then increase ownercount if found, else create new entry or reuse free
* entry
*/
if (Resource->OwnerTable == NULL)
{
DPRINT("Creating owner table\n");
-
+
/* allocate ownertable,memset to 0, initialize first entry */
- Resource->OwnerTable =
- ExAllocatePoolWithTag(NonPagedPool, sizeof(OWNER_ENTRY)*3,
+ Resource->OwnerTable =
+ ExAllocatePoolWithTag(NonPagedPool, sizeof(OWNER_ENTRY)*3,
TAG_OWNER_TABLE);
if (Resource->OwnerTable == NULL)
{
memset(Resource->OwnerTable,0,sizeof(OWNER_ENTRY)*3);
memcpy(&Resource->OwnerTable[0], &Resource->OwnerThreads[1],
sizeof(OWNER_ENTRY));
-
+
Resource->OwnerThreads[1].OwnerThread = 0;
Resource->OwnerThreads[1].TableSize = 3;
-
+
Resource->OwnerTable[1].OwnerThread = CurrentThread;
Resource->OwnerTable[1].OwnerCount = 1;
Resource->ActiveCount++;
-
+
return(TRUE);
}
-
+
DPRINT("Search free entries\n");
-
- DPRINT("Number of entries %d\n",
+
+ DPRINT("Number of entries %d\n",
Resource->OwnerThreads[1].TableSize);
-
+
freeEntry = NULL;
for (i=0; i<Resource->OwnerThreads[1].TableSize; i++)
{
break;
}
}
-
+
DPRINT("Found free entry %x\n", freeEntry);
-
+
if (!freeEntry)
{
DPRINT("Allocating new entry\n");
-
+
/* reallocate ownertable with one more entry */
- freeEntry =
+ freeEntry =
ExAllocatePoolWithTag(NonPagedPool,
sizeof(OWNER_ENTRY)*
(Resource->OwnerThreads[1].TableSize+1),
*/
{
KIRQL oldIrql;
-
+
DPRINT("ExAcquireResourceSharedLite(Resource %x, Wait %d)\n",
Resource, Wait);
ASSERT_IRQL_LESS(DISPATCH_LEVEL);
-
+
/* undefed for now, since cdfs must be fixed first */
-#if 0
- /* At least regular kmode APC's must be disabled
- * Note that this requirement is missing in old DDK's
+#if 0
+ /* At least regular kmode APC's must be disabled
+ * Note that this requirement is missing in old DDK's
*/
ASSERT(KeGetCurrentThread() == NULL || /* <-Early in the boot process the current thread is obseved to be NULL */
- KeGetCurrentThread()->KernelApcDisable ||
+ KeGetCurrentThread()->KernelApcDisable ||
KeGetCurrentIrql() == APC_LEVEL);
#endif
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
-
+
/* first, resolve trivial cases */
- if (Resource->ActiveCount == 0)
+ if (Resource->ActiveCount == 0)
{
EiAddSharedOwner(Resource);
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExAcquireResourceSharedLite() = TRUE\n");
return(TRUE);
}
-
+
if ((Resource->Flag & ResourceOwnedExclusive)
&& Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread())
{
/* exclusive, but by same thread : it's ok */
- /*
- * NOTE: Is this correct? Seems the same as ExConvertExclusiveToShared
+ /*
+ * NOTE: Is this correct? Seems the same as ExConvertExclusiveToShared
*/
Resource->OwnerThreads[0].OwnerCount++;
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExAcquireResourceSharedLite() = TRUE\n");
return(TRUE);
}
-
+
if ((Resource->Flag & ResourceOwnedExclusive)
|| Resource->NumberOfExclusiveWaiters)
- {
+ {
/* exclusive by another thread , or thread waiting for exclusive */
- if (!Wait)
+ if (!Wait)
{
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExAcquireResourceSharedLite() = FALSE\n");
Resource->NumberOfSharedWaiters--;
}
}
-
+
EiAddSharedOwner(Resource);
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExAcquireResourceSharedLite() = TRUE\n");
{
ULONG oldWaiters;
KIRQL oldIrql;
-
+
DPRINT("ExConvertExclusiveToSharedLite(Resource %x)\n", Resource);
-
+
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
-
+
oldWaiters = Resource->NumberOfSharedWaiters;
-
+
if (!(Resource->Flag & ResourceOwnedExclusive))
{
/* Might not be what the caller expects, better bug check */
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
return;
}
-
+
//transfer infos from entry 0 to entry 1 and erase entry 0
Resource->OwnerThreads[1].OwnerThread=Resource->OwnerThreads[0].OwnerThread;
Resource->OwnerThreads[1].OwnerCount=Resource->OwnerThreads[0].OwnerCount;
/* erase exclusive flag */
Resource->Flag &= (~ResourceOwnedExclusive);
/* if no shared waiters, that's all */
- if (!oldWaiters)
+ if (!oldWaiters)
{
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
return;
*/
{
KIRQL oldIrql;
-
+
DPRINT("ExAcquireSharedStarveExclusive(Resource %x, Wait %d)\n",
Resource, Wait);
-
+
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
-
+
/* no owner, it's easy */
- if (Resource->ActiveCount == 0)
+ if (Resource->ActiveCount == 0)
{
Resource->OwnerThreads[1].OwnerThread=ExGetCurrentResourceThread();
Resource->OwnerThreads[1].OwnerCount=1;
DPRINT("ExAcquireSharedStarveExclusive() = TRUE\n");
return(TRUE);
}
-
+
if ((Resource->Flag & ResourceOwnedExclusive)
&& Resource->OwnerThreads[0].OwnerThread==ExGetCurrentResourceThread())
- {
+ {
/* exclusive, but by same thread : it's ok */
Resource->OwnerThreads[0].OwnerCount++;
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExAcquireSharedStarveExclusive() = TRUE\n");
return(TRUE);
}
-
+
if (Resource->Flag & ResourceOwnedExclusive)
- {
+ {
/* exclusive by another thread */
- if (!Wait)
+ if (!Wait)
{
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExAcquireSharedStarveExclusive() = FALSE\n");
if (Resource->OwnerTable) ExFreePool(Resource->OwnerTable);
if (Resource->SharedWaiters) ExFreePool(Resource->SharedWaiters);
if (Resource->ExclusiveWaiters) ExFreePool(Resource->ExclusiveWaiters);
- return(STATUS_SUCCESS);;
+ return(STATUS_SUCCESS);
}
/*
Resource->NumberOfExclusiveWaiters = 0;
KeInitializeSpinLock(&Resource->SpinLock);
Resource->Flag = 0;
- Resource->ExclusiveWaiters =
+ Resource->ExclusiveWaiters =
ExAllocatePoolWithTag(NonPagedPool, sizeof(KEVENT), TAG_EXCLUSIVE_LOCK);
KeInitializeEvent(Resource->ExclusiveWaiters,
SynchronizationEvent,
FALSE);
- Resource->SharedWaiters =
+ Resource->SharedWaiters =
ExAllocatePoolWithTag(NonPagedPool ,sizeof(KSEMAPHORE), TAG_SHARED_SEM);
KeInitializeSemaphore(Resource->SharedWaiters,0,0x7fffffff);
Resource->ActiveCount = 0;
/*
* @implemented
*/
-
-
+
+
//NTOSAPI
//DDKAPI
USHORT STDCALL
* Resource = Points to the resource to be queried
* RETURNS: The number of times the caller has acquired shared access to the
* given resource
- */
+ */
{
ULONG i;
if (Resource->OwnerThreads[0].OwnerThread == ExGetCurrentResourceThread())
{
return (USHORT)(Resource->OwnerThreads[1].OwnerCount);
}
- if (!Resource->OwnerThreads[1].TableSize)
+ if (!Resource->OwnerThreads[1].TableSize)
{
return(0);
}
FALSE);
KeInitializeSemaphore(Resource->SharedWaiters,0,0x7fffffff);
Resource->ActiveCount = 0;
- if (Resource->OwnerTable)
+ if (Resource->OwnerTable)
{
ExFreePool(Resource->OwnerTable);
}
*/
{
KIRQL oldIrql;
-
+
DPRINT("ExReleaseResourceForThreadLite(Resource %x, ResourceThreadId %x)\n",
Resource, ResourceThreadId);
-
+
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
-
+
KeAcquireSpinLock(&Resource->SpinLock, &oldIrql);
-
+
if (Resource->Flag & ResourceOwnedExclusive)
{
DPRINT("Releasing from exclusive access\n");
-
+
Resource->OwnerThreads[0].OwnerCount--;
if (Resource->OwnerThreads[0].OwnerCount > 0)
{
DPRINT("ExReleaseResourceForThreadLite() finished\n");
return;
}
-
+
Resource->OwnerThreads[0].OwnerThread = 0;
Resource->ActiveCount--;
Resource->Flag &=(~ResourceOwnedExclusive);
if (Resource->NumberOfExclusiveWaiters)
{
/* get resource to first exclusive waiter */
- KeSetEvent(Resource->ExclusiveWaiters,
- IO_NO_INCREMENT,
+ KeSetEvent(Resource->ExclusiveWaiters,
+ IO_NO_INCREMENT,
FALSE);
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExReleaseResourceForThreadLite() finished\n");
DPRINT("ExReleaseResourceForThreadLite() finished\n");
return;
}
-
+
EiRemoveSharedOwner(Resource, ResourceThreadId);
-
+
if (Resource->ActiveCount == 0)
{
if (Resource->NumberOfExclusiveWaiters)
- {
+ {
/* get resource to first exclusive waiter */
KeSetEvent(Resource->ExclusiveWaiters,
IO_NO_INCREMENT,
FALSE);
}
}
-
+
KeReleaseSpinLock(&Resource->SpinLock, oldIrql);
DPRINT("ExReleaseResourceForThreadLite() finished\n");
}
PKTHREAD CurrentThread;
KIRQL OldIrql;
POWNER_ENTRY OwnerEntry;
-
+
CurrentThread = KeGetCurrentThread();
-
+
/* Lock the resource */
KeAcquireSpinLock(&Resource->SpinLock, &OldIrql);
-
+
/* Check if it's exclusive */
if (Resource->Flag & ResourceOwnedExclusive) {
-
+
/* If it's exclusive, set the first entry no matter what */
Resource->OwnerThreads[0].OwnerThread = (ULONG_PTR)OwnerPointer;
-
+
} else {
-
+
/* Check both entries and see which one matches the current thread */
if (Resource->OwnerThreads[0].OwnerThread == (ULONG_PTR)CurrentThread) {
-
+
Resource->OwnerThreads[0].OwnerThread = (ULONG_PTR)OwnerPointer;
-
+
} else if (Resource->OwnerThreads[1].OwnerThread == (ULONG_PTR)CurrentThread) {
-
+
Resource->OwnerThreads[1].OwnerThread = (ULONG_PTR)OwnerPointer;
-
+
} else { /* None of the entries match, so we need to do a lookup */
-
+
/* Get the first Entry */
OwnerEntry = Resource->OwnerTable;
-
+
/* Check if the Current Thread is in the Resource Table Entry */
- if ((CurrentThread->ResourceIndex >= OwnerEntry->TableSize) ||
+ if ((CurrentThread->ResourceIndex >= OwnerEntry->TableSize) ||
(OwnerEntry[CurrentThread->ResourceIndex].OwnerThread != (ULONG_PTR)CurrentThread)) {
-
+
/* Loop until we find the current thread in an entry */
for (;OwnerEntry->OwnerThread == (ULONG_PTR)CurrentThread;OwnerEntry++);
-
+
} else {
-
+
/* It's in the current RTE, so set it */
OwnerEntry = &OwnerEntry[CurrentThread->ResourceIndex];
}
-
- /* Now that we went to the right entry, set the Owner Pointer */
+
+ /* Now that we went to the right entry, set the Owner Pointer */
OwnerEntry->OwnerThread = (ULONG_PTR)OwnerPointer;
}
}
-
+
/* Release the resource */
KeReleaseSpinLock(&Resource->SpinLock, OldIrql);
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/rundown.c
* PURPOSE: Rundown Protection Functions
- *
+ *
* PROGRAMMERS: Alex Ionescu & Thomas Weidenmueller - Implementation
*/
)
{
ULONG_PTR PrevCount, Current;
-
+
PAGED_CODE();
-
+
Count <<= EX_RUNDOWN_COUNT_SHIFT;
-
+
/* Loop until successfully incremented the counter */
do
{
Current = RunRef->Count;
-
+
/* Make sure a rundown is not active */
if (Current & EX_RUNDOWN_ACTIVE)
{
)
{
PAGED_CODE();
-
+
/* Set the count to zero */
RunRef->Count = 0;
}
)
{
PAGED_CODE();
-
+
/* Reset the count */
#ifdef _WIN64
InterlockedExchangeAdd64((LONGLONG*)&RunRef->Count, 0LL);
PAGED_CODE();
Count <<= EX_RUNDOWN_COUNT_SHIFT;
-
+
for (;;)
{
ULONG_PTR Current = RunRef->Count;
-
+
/* Check if Rundown is active */
if (Current & EX_RUNDOWN_ACTIVE)
{
/* Get Pointer */
PRUNDOWN_DESCRIPTOR RundownDescriptor = (PRUNDOWN_DESCRIPTOR)(Current & ~EX_RUNDOWN_ACTIVE);
-
+
if (RundownDescriptor == NULL)
{
/* the rundown was completed and there's no one to notify */
break;
}
-
+
Current = RundownDescriptor->References;
/* Decrease RundownDescriptor->References by Count references */
/* Successfully decremented the counter, so bail! */
break;
}
-
+
Current = PrevCount;
}
-
+
break;
}
else
)
{
PAGED_CODE();
-
+
/* mark the counter as active */
#ifdef _WIN64
InterlockedExchange64((LONGLONG*)&RunRef->Count, (LONGLONG)EX_RUNDOWN_ACTIVE);
{
ULONG_PTR PrevCount, NewPtr, PrevPtr;
RUNDOWN_DESCRIPTOR RundownDescriptor;
-
+
PAGED_CODE();
-
+
PrevCount = RunRef->Count;
-
+
if (PrevCount != 0 && !(PrevCount & EX_RUNDOWN_ACTIVE))
{
/* save the reference counter */
/* Pending references... wait on them to be closed with an event */
KeInitializeEvent(&RundownDescriptor.RundownEvent, NotificationEvent, FALSE);
-
+
ASSERT(!((ULONG_PTR)&RundownDescriptor & EX_RUNDOWN_ACTIVE));
-
+
NewPtr = (ULONG_PTR)&RundownDescriptor | EX_RUNDOWN_ACTIVE;
-
+
for (;;)
{
#ifdef _WIN64
/* some one else was faster, let's just bail */
break;
}
-
+
PrevCount = PrevPtr;
-
+
/* save the changed reference counter and try again */
RundownDescriptor.References = PrevCount >> EX_RUNDOWN_COUNT_SHIFT;
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/sem.c
* PURPOSE: Synchronization primitives
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)- Reformatting, bug fixes.
* David Welch (welch@mcmail.com)
*/
SEMAPHORE_ALL_ACCESS};
static const INFORMATION_CLASS_INFO ExSemaphoreInfoClass[] = {
-
+
/* SemaphoreBasicInformation */
ICI_SQ_SAME( sizeof(SEMAPHORE_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
};
-VOID
+VOID
INIT_FUNCTION
ExpInitializeSemaphoreImplementation(VOID)
{
-
+
/* Create the Semaphore Object */
ExSemaphoreObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
RtlInitUnicodeString(&ExSemaphoreObjectType->TypeName, L"Semaphore");
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtCreateSemaphore(OUT PHANDLE SemaphoreHandle,
IN ACCESS_MASK DesiredAccess,
HANDLE hSemaphore;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
/* Check Output Safety */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(SemaphoreHandle,
sizeof(HANDLE),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Make sure the counts make sense */
if (!MaximumCount || InitialCount < 0 || InitialCount > MaximumCount) {
-
+
DPRINT("Invalid Count Data!\n");
return STATUS_INVALID_PARAMETER;
}
0,
0,
(PVOID*)&Semaphore);
-
+
/* Check for Success */
if (NT_SUCCESS(Status)) {
-
+
/* Initialize it */
KeInitializeSemaphore(Semaphore,
InitialCount,
MaximumCount);
-
+
/* Insert it into the Object Tree */
Status = ObInsertObject((PVOID)Semaphore,
NULL,
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*SemaphoreHandle = hSemaphore;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtOpenSemaphore(OUT PHANDLE SemaphoreHandle,
IN ACCESS_MASK DesiredAccess,
HANDLE hSemaphore;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
/* Check Output Safety */
if(PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(SemaphoreHandle,
sizeof(HANDLE),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Open the Object */
Status = ObOpenObjectByName(ObjectAttributes,
ExSemaphoreObjectType,
DesiredAccess,
NULL,
&hSemaphore);
-
+
/* Check for success and return handle */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*SemaphoreHandle = hSemaphore;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
PreviousMode,
&Status);
if(!NT_SUCCESS(Status)) {
-
+
/* Invalid buffers */
DPRINT("NtQuerySemaphore() failed, Status: 0x%x\n", Status);
return Status;
}
-
+
/* Get the Object */
Status = ObReferenceObjectByHandle(SemaphoreHandle,
SEMAPHORE_QUERY_STATE,
PreviousMode,
(PVOID*)&Semaphore,
NULL);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
PSEMAPHORE_BASIC_INFORMATION BasicInfo = (PSEMAPHORE_BASIC_INFORMATION)SemaphoreInformation;
-
+
/* Return the basic information */
BasicInfo->CurrentCount = KeReadStateSemaphore(Semaphore);
BasicInfo->MaximumCount = Semaphore->Limit;
/* Return length */
if(ReturnLength) *ReturnLength = sizeof(SEMAPHORE_BASIC_INFORMATION);
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
/* Dereference the Object */
ObDereferenceObject(Semaphore);
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtReleaseSemaphore(IN HANDLE SemaphoreHandle,
IN LONG ReleaseCount,
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PKSEMAPHORE Semaphore;
- NTSTATUS Status = STATUS_SUCCESS;
-
+ NTSTATUS Status = STATUS_SUCCESS;
+
PAGED_CODE();
-
+
/* Check buffer validity */
if(PreviousCount != NULL && PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(PreviousCount,
sizeof(LONG),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Make sure count makes sense */
if (!ReleaseCount) {
-
+
DPRINT("Invalid Release Count\n");
return STATUS_INVALID_PARAMETER;
}
-
+
/* Get the Object */
Status = ObReferenceObjectByHandle(SemaphoreHandle,
SEMAPHORE_MODIFY_STATE,
PreviousMode,
(PVOID*)&Semaphore,
NULL);
-
+
/* Check for success */
if (NT_SUCCESS(Status)) {
-
+
/* Release the semaphore */
LONG PrevCount = KeReleaseSemaphore(Semaphore,
IO_NO_INCREMENT,
ReleaseCount,
FALSE);
ObDereferenceObject(Semaphore);
-
- /* Return it */
+
+ /* Return it */
if(PreviousCount) {
-
+
_SEH_TRY {
-
+
*PreviousCount = PrevCount;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/synch.c
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/sysinfo.c
* PURPOSE: System information functions
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Aleksey Bragin (aleksey@studiocerebral.com)
*/
/*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
ExIsProcessorFeaturePresent(IN ULONG ProcessorFeature)
{
UNICODE_STRING WValue;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
DPRINT1("NtQuerySystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
return STATUS_PRIVILEGE_NOT_HELD;
}
-
+
/*
* convert the value name to ansi
*/
{
return Status;
}
-
+
/*
* Create a temporary buffer for the value
*/
RtlFreeAnsiString(&AName);
return STATUS_INSUFFICIENT_RESOURCES;
}
-
+
/*
* Get the environment variable
*/
ExFreePool(Value);
return STATUS_UNSUCCESSFUL;
}
-
+
/*
* Convert the result to UNICODE, protect with SEH in case the value buffer
* isn't NULL-terminated!
}
_SEH_END;
}
-
+
/*
* Cleanup allocated resources.
*/
ANSI_STRING AName, AValue;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
-
+
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
-
+
/*
* Copy the strings to kernel space if necessary
*/
DPRINT1("NtSetSystemEnvironmentValue: Caller requires the SeSystemEnvironmentPrivilege privilege!\n");
Status = STATUS_PRIVILEGE_NOT_HELD;
}
-
+
RtlReleaseCapturedUnicodeString(&CapturedValue,
PreviousMode,
FALSE);
PreviousMode,
FALSE);
}
-
+
return Status;
}
/* Class 0 - Basic Information */
QSI_DEF(SystemBasicInformation)
{
- PSYSTEM_BASIC_INFORMATION Sbi
+ PSYSTEM_BASIC_INFORMATION Sbi
= (PSYSTEM_BASIC_INFORMATION) Buffer;
*ReqSize = sizeof (SYSTEM_BASIC_INFORMATION);
/*
- * Check user buffer's size
+ * Check user buffer's size
*/
if (Size < sizeof (SYSTEM_BASIC_INFORMATION))
{
Sbi->MaximumIncrement = KeMaximumIncrement;
Sbi->PhysicalPageSize = PAGE_SIZE;
Sbi->NumberOfPhysicalPages = MmStats.NrTotalPages;
- Sbi->LowestPhysicalPage = 0; /* FIXME */
+ Sbi->LowestPhysicalPage = 0; /* FIXME */
Sbi->HighestPhysicalPage = MmStats.NrTotalPages; /* FIXME */
Sbi->AllocationGranularity = MM_VIRTMEM_GRANULARITY; /* hard coded on Intel? */
Sbi->LowestUserAddress = 0x10000; /* Top of 64k */
/* Class 1 - Processor Information */
QSI_DEF(SystemProcessorInformation)
{
- PSYSTEM_PROCESSOR_INFORMATION Spi
+ PSYSTEM_PROCESSOR_INFORMATION Spi
= (PSYSTEM_PROCESSOR_INFORMATION) Buffer;
PKPRCB Prcb;
*ReqSize = sizeof (SYSTEM_PROCESSOR_INFORMATION);
/*
- * Check user buffer's size
+ * Check user buffer's size
*/
if (Size < sizeof (SYSTEM_PROCESSOR_INFORMATION))
{
/* Class 2 - Performance Information */
QSI_DEF(SystemPerformanceInformation)
{
- PSYSTEM_PERFORMANCE_INFORMATION Spi
+ PSYSTEM_PERFORMANCE_INFORMATION Spi
= (PSYSTEM_PERFORMANCE_INFORMATION) Buffer;
PEPROCESS TheIdleProcess;
-
+
*ReqSize = sizeof (SYSTEM_PERFORMANCE_INFORMATION);
/*
- * Check user buffer's size
+ * Check user buffer's size
*/
if (Size < sizeof (SYSTEM_PERFORMANCE_INFORMATION))
{
return (STATUS_INFO_LENGTH_MISMATCH);
}
-
+
TheIdleProcess = PsIdleProcess;
-
+
Spi->IdleTime.QuadPart = TheIdleProcess->Pcb.KernelTime * 100000LL;
Spi->ReadTransferCount.QuadPart = IoReadTransferCount;
Spi->NonPagedPoolFrees = 0; /* FIXME */
Spi->TotalFreeSystemPtes = 0; /* FIXME */
-
+
Spi->SystemCodePage = MmStats.NrSystemPages; /* FIXME */
-
+
Spi->TotalSystemDriverPages = 0; /* FIXME */
Spi->TotalSystemCodePages = 0; /* FIXME */
Spi->SmallNonPagedLookasideListAllocateHits = 0; /* FIXME */
{
return (STATUS_INFO_LENGTH_MISMATCH); // in case buffer size is too small
}
-
+
syspr = PsGetNextProcess(NULL);
pr = syspr;
pCur = (unsigned char *)Spi;
SpiCur->NextEntryOffset = curSize+inLen; // relative offset to the beginnnig of the next structure
SpiCur->NumberOfThreads = nThreads;
SpiCur->CreateTime = pr->CreateTime;
- SpiCur->UserTime.QuadPart = pr->Pcb.UserTime * 100000LL;
+ SpiCur->UserTime.QuadPart = pr->Pcb.UserTime * 100000LL;
SpiCur->KernelTime.QuadPart = pr->Pcb.KernelTime * 100000LL;
SpiCur->ImageName.Length = strlen(pr->ImageFileName) * sizeof(WCHAR);
SpiCur->ImageName.MaximumLength = inLen;
i++;
current_entry = current_entry->Flink;
}
-
+
pr = PsGetNextProcess(pr);
nThreads = 0;
if ((pr == syspr) || (pr == NULL))
else
pCur = pCur + curSize + inLen;
} while ((pr != syspr) && (pr != NULL));
-
+
if(pr != NULL)
{
ObDereferenceObject(pr);
/* Class 7 - Device Information */
QSI_DEF(SystemDeviceInformation)
{
- PSYSTEM_DEVICE_INFORMATION Sdi
+ PSYSTEM_DEVICE_INFORMATION Sdi
= (PSYSTEM_DEVICE_INFORMATION) Buffer;
PCONFIGURATION_INFORMATION ConfigInfo;
*ReqSize = sizeof (SYSTEM_DEVICE_INFORMATION);
/*
- * Check user buffer's size
+ * Check user buffer's size
*/
if (Size < sizeof (SYSTEM_DEVICE_INFORMATION))
{
*ReqSize = KeNumberProcessors * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
/*
- * Check user buffer's size
+ * Check user buffer's size
*/
if (Size < KeNumberProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION))
{
Spi++;
Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
}
-
+
return (STATUS_SUCCESS);
}
/* Class 16 - Handle Information */
QSI_DEF(SystemHandleInformation)
{
- PSYSTEM_HANDLE_INFORMATION Shi =
+ PSYSTEM_HANDLE_INFORMATION Shi =
(PSYSTEM_HANDLE_INFORMATION) Buffer;
DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
PEPROCESS pr, syspr;
int curSize, i = 0;
ULONG hCount = 0;
-
+
/* First Calc Size from Count. */
syspr = PsGetNextProcess(NULL);
pr = syspr;
if ((pr == syspr) || (pr == NULL))
break;
} while ((pr != syspr) && (pr != NULL));
-
+
if(pr != NULL)
{
ObDereferenceObject(pr);
DPRINT("SystemHandleInformation 2\n");
curSize = sizeof(SYSTEM_HANDLE_INFORMATION)+
- ( (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * hCount) -
+ ( (sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * hCount) -
(sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) ));
Shi->NumberOfHandles = hCount;
/*
SSI_DEF(SystemHandleInformation)
{
-
+
return (STATUS_SUCCESS);
}
*/
return (STATUS_INFO_LENGTH_MISMATCH);
}
/* Return the Byte size not the page size. */
- Sci->CurrentSize =
+ Sci->CurrentSize =
MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE;
- Sci->PeakSize =
+ Sci->PeakSize =
MiMemoryConsumers[MC_CACHE].PagesUsed * PAGE_SIZE; /* FIXME */
Sci->PageFaultCount = 0; /* FIXME */
UINT i;
ULONG ti;
PSYSTEM_INTERRUPT_INFORMATION sii = (PSYSTEM_INTERRUPT_INFORMATION)Buffer;
-
+
if(Size < KeNumberProcessors * sizeof(SYSTEM_INTERRUPT_INFORMATION))
{
return (STATUS_INFO_LENGTH_MISMATCH);
}
-
+
ti = KeQueryTimeIncrement();
-
+
Prcb = ((PKPCR)KPCR_BASE)->Prcb;
for (i = 0; i < KeNumberProcessors; i++)
{
sii++;
Prcb = (PKPRCB)((ULONG_PTR)Prcb + PAGE_SIZE);
}
-
+
return STATUS_SUCCESS;
}
#ifndef NDEBUG
MmPrintMemoryStatistic();
#endif
-
+
*Spi = MiMemoryConsumers[MC_USER].PagesUsed;
return (STATUS_SUCCESS);
PVOID SystemInformation;
NTSTATUS Status;
NTSTATUS FStatus;
-
+
PAGED_CODE();
/* DPRINT("NtQuerySystemInformation Start. Class:%d\n",
return(STATUS_NO_MEMORY);
}
}*/
-
+
/* Clear user buffer. */
RtlZeroMemory(SystemInformation, Length);
/*
* Check the request is valid.
*/
- if ((SystemInformationClass >= SystemInformationClassMin) &&
+ if ((SystemInformationClass >= SystemInformationClassMin) &&
(SystemInformationClass < SystemInformationClassMax))
{
if (NULL != CallQS [SystemInformationClass].Query)
&ResultLength);
/*if (ExGetPreviousMode() != KernelMode)
{
- Status = MmCopyToCaller(UnsafeSystemInformation,
+ Status = MmCopyToCaller(UnsafeSystemInformation,
SystemInformation,
Length);
ExFreePool(SystemInformation);
)
{
PAGED_CODE();
-
+
/*
- * If called from user mode, check
+ * If called from user mode, check
* possible unsafe arguments.
*/
#if 0
)
{
PAGED_CODE();
-
+
__asm__("wbinvd\n");
return STATUS_SUCCESS;
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/time.c
* PURPOSE: Time
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
TIME_FIELDS TimeFields;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
{
NewSystemTime = *SystemTime;
}
-
+
if(!SeSinglePrivilegeCheck(SeSystemtimePrivilege,
PreviousMode))
{
DPRINT1("NtSetSystemTime: Caller requires the SeSystemtimePrivilege privilege!\n");
return STATUS_PRIVILEGE_NOT_HELD;
}
-
+
if(PreviousTime != NULL)
{
KeQuerySystemTime(&OldSystemTime);
{
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
{
KeQuerySystemTime(SystemTime);
}
-
+
return Status;
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/timer.c
* PURPOSE: User-mode timers
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Reimplemented
* David Welch (welch@mcmail.com)
*/
/* Timer Information Classes */
static const INFORMATION_CLASS_INFO ExTimerInfoClass[] = {
-
+
/* TimerBasicInformation */
ICI_SQ_SAME( sizeof(TIMER_BASIC_INFORMATION), sizeof(ULONG), ICIF_QUERY ),
};
KIRQL OldIrql;
PLIST_ENTRY CurrentEntry;
PETIMER Timer;
-
+
/* Lock the Thread's Active Timer List*/
KeAcquireSpinLock(&Thread->ActiveTimerListLock, &OldIrql);
-
- while (!IsListEmpty(&Thread->ActiveTimerListHead))
+
+ while (!IsListEmpty(&Thread->ActiveTimerListHead))
{
-
+
/* Remove a Timer */
CurrentEntry = RemoveTailList(&Thread->ActiveTimerListHead);
/* Get the Timer */
Timer = CONTAINING_RECORD(CurrentEntry, ETIMER, ActiveTimerListEntry);
-
+
ASSERT (Timer->ApcAssociated);
- Timer->ApcAssociated = FALSE;
-
+ Timer->ApcAssociated = FALSE;
+
DPRINT("Timer, ThreadList: %x, %x\n", Timer, Thread);
-
+
/* Unlock the list */
KeReleaseSpinLockFromDpcLevel(&Thread->ActiveTimerListLock);
-
+
/* Lock the Timer */
KeAcquireSpinLockAtDpcLevel(&Timer->Lock);
-
+
ASSERT (&Thread->Tcb == Timer->TimerApc.Thread);
-
+
KeCancelTimer(&Timer->KeTimer);
KeRemoveQueueDpc(&Timer->TimerDpc);
- KeRemoveQueueApc(&Timer->TimerApc);
-
-
+ KeRemoveQueueApc(&Timer->TimerApc);
+
+
/* Unlock the Timer */
KeReleaseSpinLock(&Timer->Lock, OldIrql);
-
+
/* Dereference it, if needed */
ObDereferenceObject(Timer);
-
+
/* Loop again */
KeAcquireSpinLock(&Thread->ActiveTimerListLock, &OldIrql);
- }
-
+ }
+
KeReleaseSpinLock(&Thread->ActiveTimerListLock, OldIrql);
}
/* Lock the Wake List */
KeAcquireSpinLock(&ExpWakeListLock, &OldIrql);
-
+
/* Check if it has a Wait List */
if (Timer->WakeTimer) {
-
+
/* Remove it from the Wait List */
DPRINT("Removing wake list\n");
RemoveEntryList(&Timer->WakeTimerListEntry);
Timer->WakeTimer = FALSE;
}
-
+
/* Release the Wake List */
KeReleaseSpinLock(&ExpWakeListLock, OldIrql);
KeCancelTimer(&Timer->KeTimer);
}
-VOID
+VOID
STDCALL
ExpTimerDpcRoutine(PKDPC Dpc,
PVOID DeferredContext,
/* Lock the Timer */
KeAcquireSpinLock(&Timer->Lock, &OldIrql);
-
+
/* Queue the APC */
if(Timer->ApcAssociated) {
-
+
DPRINT("Queuing APC\n");
KeInsertQueueApc(&Timer->TimerApc,
SystemArgument1,
SystemArgument2,
IO_NO_INCREMENT);
}
-
+
/* Release the Timer */
KeReleaseSpinLock(&Timer->Lock, OldIrql);
}
/* We need to find out which Timer we are */
Timer = CONTAINING_RECORD(Apc, ETIMER, TimerApc);
DPRINT("ExpTimerApcKernelRoutine(Apc: %x. Timer: %x)\n", Apc, Timer);
-
+
/* Lock the Timer */
KeAcquireSpinLock(&Timer->Lock, &OldIrql);
-
+
/* Lock the Thread's Active Timer List*/
KeAcquireSpinLockAtDpcLevel(&CurrentThread->ActiveTimerListLock);
-
- /*
- * Make sure that the Timer is still valid, and that it belongs to this thread
+
+ /*
+ * Make sure that the Timer is still valid, and that it belongs to this thread
* Remove it if it's not periodic
*/
- if ((Timer->ApcAssociated) &&
- (&CurrentThread->Tcb == Timer->TimerApc.Thread) &&
+ if ((Timer->ApcAssociated) &&
+ (&CurrentThread->Tcb == Timer->TimerApc.Thread) &&
(!Timer->KeTimer.Period)) {
/* Remove it from the Active Timers List */
DPRINT("Removing Timer\n");
RemoveEntryList(&Timer->ActiveTimerListEntry);
-
+
/* Disable it */
Timer->ApcAssociated = FALSE;
-
+
/* Release spinlocks */
KeReleaseSpinLockFromDpcLevel(&CurrentThread->ActiveTimerListLock);
KeReleaseSpinLock(&Timer->Lock, OldIrql);
-
+
/* Dereference the Timer Object */
ObDereferenceObject(Timer);
return;
}
-
+
/* Release spinlocks */
KeReleaseSpinLockFromDpcLevel(&CurrentThread->ActiveTimerListLock);
KeReleaseSpinLock(&Timer->Lock, OldIrql);
ExpInitializeTimerImplementation(VOID)
{
DPRINT("ExpInitializeTimerImplementation()\n");
-
+
/* Allocate Memory for the Timer */
ExTimerType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
ExTimerType->Create = NULL;
ExTimerType->DuplicationNotify = NULL;
ObpCreateTypeObject(ExTimerType);
-
+
/* Initialize the Wait List and Lock */
KeInitializeSpinLock(&ExpWakeListLock);
InitializeListHead(&ExpWakeList);
}
-NTSTATUS
+NTSTATUS
STDCALL
NtCancelTimer(IN HANDLE TimerHandle,
OUT PBOOLEAN CurrentState OPTIONAL)
PETHREAD TimerThread;
BOOLEAN KillTimer = FALSE;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtCancelTimer(0x%x, 0x%x)\n", TimerHandle, CurrentState);
-
+
/* Check Parameter Validity */
if(CurrentState != NULL && PreviousMode != KernelMode) {
_SEH_TRY {
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
Status = _SEH_GetExceptionCode();
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) {
return Status;
}
PreviousMode,
(PVOID*)&Timer,
NULL);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
-
+
DPRINT("Timer Referencced: %x\n", Timer);
-
+
/* Lock the Timer */
KeAcquireSpinLock(&Timer->Lock, &OldIrql);
-
+
/* Check if it's enabled */
if (Timer->ApcAssociated) {
-
- /*
- * First, remove it from the Thread's Active List
+
+ /*
+ * First, remove it from the Thread's Active List
* Get the Thread.
*/
TimerThread = CONTAINING_RECORD(Timer->TimerApc.Thread, ETHREAD, Tcb);
DPRINT("Removing from Thread: %x\n", TimerThread);
-
+
/* Lock its active list */
KeAcquireSpinLockAtDpcLevel(&TimerThread->ActiveTimerListLock);
-
+
/* Remove it */
RemoveEntryList(&TimerThread->ActiveTimerListHead);
-
+
/* Unlock the list */
KeReleaseSpinLockFromDpcLevel(&TimerThread->ActiveTimerListLock);
-
+
/* Cancel the Timer */
KeCancelTimer(&Timer->KeTimer);
KeRemoveQueueDpc(&Timer->TimerDpc);
KeRemoveQueueApc(&Timer->TimerApc);
Timer->ApcAssociated = FALSE;
KillTimer = TRUE;
-
+
} else {
-
+
/* If timer was disabled, we still need to cancel it */
DPRINT("APC was not Associated. Cancelling Timer\n");
KeCancelTimer(&Timer->KeTimer);
}
-
+
/* Read the old State */
State = KeReadStateTimer(&Timer->KeTimer);
-
+
/* Dereference the Object */
ObDereferenceObject(Timer);
-
+
/* Unlock the Timer */
KeReleaseSpinLock(&Timer->Lock, OldIrql);
-
+
/* Dereference if it was previously enabled */
if (KillTimer) ObDereferenceObject(Timer);
DPRINT1("Timer disabled\n");
/* Make sure it's safe to write to the handle */
if(CurrentState != NULL) {
-
+
_SEH_TRY {
-
+
*CurrentState = State;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
}
-NTSTATUS
+NTSTATUS
STDCALL
NtCreateTimer(OUT PHANDLE TimerHandle,
IN ACCESS_MASK DesiredAccess,
HANDLE hTimer;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtCreateTimer(Handle: %x, Type: %d)\n", TimerHandle, TimerType);
/* Check Parameter Validity */
if (PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(TimerHandle,
sizeof(HANDLE),
sizeof(ULONG));
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
-
- /* Create the Object */
+
+ /* Create the Object */
Status = ObCreateObject(PreviousMode,
ExTimerType,
ObjectAttributes,
0,
0,
(PVOID*)&Timer);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
-
+
/* Initialize the Kernel Timer */
DPRINT("Initializing Timer: %x\n", Timer);
KeInitializeTimerEx(&Timer->KeTimer, TimerType);
/* Initialize the Timer Lock */
KeInitializeSpinLock(&Timer->Lock);
-
+
/* Initialize the DPC */
KeInitializeDpc(&Timer->TimerDpc, ExpTimerDpcRoutine, Timer);
/* Set Initial State */
Timer->ApcAssociated = FALSE;
Timer->WakeTimer = FALSE;
-
+
/* Insert the Timer */
Status = ObInsertObject((PVOID)Timer,
NULL,
&hTimer);
DPRINT("Timer Inserted\n");
-
+
/* Make sure it's safe to write to the handle */
_SEH_TRY {
-
+
*TimerHandle = hTimer;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
-NTSTATUS
+NTSTATUS
STDCALL
NtOpenTimer(OUT PHANDLE TimerHandle,
IN ACCESS_MASK DesiredAccess,
HANDLE hTimer;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtOpenTimer(TimerHandle: %x)\n", TimerHandle);
/* Check Parameter Validity */
if (PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(TimerHandle,
sizeof(HANDLE),
sizeof(ULONG));
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
DesiredAccess,
NULL,
&hTimer);
-
+
/* Check for success */
if(NT_SUCCESS(Status)) {
-
+
/* Make sure it's safe to write to the handle */
_SEH_TRY {
-
+
*TimerHandle = hTimer;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
-NTSTATUS
+NTSTATUS
STDCALL
NtQueryTimer(IN HANDLE TimerHandle,
IN TIMER_INFORMATION_CLASS TimerInformationClass,
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
PTIMER_BASIC_INFORMATION BasicInfo = (PTIMER_BASIC_INFORMATION)TimerInformation;
-
+
PAGED_CODE();
DPRINT("NtQueryTimer(TimerHandle: %x, Class: %d)\n", TimerHandle, TimerInformationClass);
PreviousMode,
&Status);
if(!NT_SUCCESS(Status)) {
-
+
DPRINT1("NtQueryTimer() failed, Status: 0x%x\n", Status);
return Status;
}
Status = ObReferenceObjectByHandle(TimerHandle,
TIMER_QUERY_STATE,
ExTimerType,
- PreviousMode,
+ PreviousMode,
(PVOID*)&Timer,
NULL);
-
+
/* Check for Success */
if(NT_SUCCESS(Status)) {
/* Return the Basic Information */
_SEH_TRY {
-
+
/* FIXME: Interrupt correction based on Interrupt Time */
DPRINT("Returning Information for Timer: %x. Time Remaining: %d\n", Timer, Timer->KeTimer.DueTime.QuadPart);
BasicInfo->TimeRemaining.QuadPart = Timer->KeTimer.DueTime.QuadPart;
if(ReturnLength != NULL) *ReturnLength = sizeof(TIMER_BASIC_INFORMATION);
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
+
/* Dereference Object */
ObDereferenceObject(Timer);
}
-
+
/* Return Status */
return Status;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtSetTimer(IN HANDLE TimerHandle,
IN PLARGE_INTEGER DueTime,
PETHREAD TimerThread;
BOOLEAN KillTimer = FALSE;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
DPRINT("NtSetTimer(TimerHandle: %x, DueTime: %d, Apc: %x, Period: %d)\n", TimerHandle, DueTime->QuadPart, TimerApcRoutine, Period);
/* Check Parameter Validity */
if (PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForRead(DueTime,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
TimerDueTime = *DueTime;
-
+
if(PreviousState != NULL) {
-
+
ProbeForWrite(PreviousState,
sizeof(BOOLEAN),
sizeof(BOOLEAN));
}
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
-
- if(!NT_SUCCESS(Status)) return Status;
+
+ if(!NT_SUCCESS(Status)) return Status;
}
-
- /* Get the Timer Object */
+
+ /* Get the Timer Object */
Status = ObReferenceObjectByHandle(TimerHandle,
TIMER_ALL_ACCESS,
ExTimerType,
PreviousMode,
(PVOID*)&Timer,
NULL);
-
+
/* Check status */
if (NT_SUCCESS(Status)) {
-
+
/* Lock the Timer */
DPRINT("Timer Referencced: %x\n", Timer);
KeAcquireSpinLock(&Timer->Lock, &OldIrql);
-
+
/* Cancel Running Timer */
if (Timer->ApcAssociated) {
-
- /*
- * First, remove it from the Thread's Active List
+
+ /*
+ * First, remove it from the Thread's Active List
* Get the Thread.
*/
TimerThread = CONTAINING_RECORD(Timer->TimerApc.Thread, ETHREAD, Tcb);
DPRINT("Thread already running. Removing from Thread: %x\n", TimerThread);
-
+
/* Lock its active list */
KeAcquireSpinLockAtDpcLevel(&TimerThread->ActiveTimerListLock);
-
+
/* Remove it */
RemoveEntryList(&TimerThread->ActiveTimerListHead);
-
+
/* Unlock the list */
KeReleaseSpinLockFromDpcLevel(&TimerThread->ActiveTimerListLock);
-
+
/* Cancel the Timer */
KeCancelTimer(&Timer->KeTimer);
KeRemoveQueueDpc(&Timer->TimerDpc);
KeRemoveQueueApc(&Timer->TimerApc);
Timer->ApcAssociated = FALSE;
KillTimer = TRUE;
-
+
} else {
-
+
/* If timer was disabled, we still need to cancel it */
DPRINT("No APCs. Simply cancelling\n");
KeCancelTimer(&Timer->KeTimer);
}
-
+
/* Read the State */
State = KeReadStateTimer(&Timer->KeTimer);
DPRINT("Doing Wake Semantics\n");
KeAcquireSpinLockAtDpcLevel(&ExpWakeListLock);
if (WakeTimer && !Timer->WakeTimer) {
-
+
/* Insert it into the list */
Timer->WakeTimer = TRUE;
InsertTailList(&ExpWakeList, &Timer->WakeTimerListEntry);
} else if (!WakeTimer && Timer->WakeTimer) {
-
+
/* Remove it from the list */
RemoveEntryList(&Timer->WakeTimerListEntry);
Timer->WakeTimer = FALSE;
}
KeReleaseSpinLockFromDpcLevel(&ExpWakeListLock);
-
+
/* Set up the APC Routine if specified */
if (TimerApcRoutine) {
-
+
/* Initialize the APC */
DPRINT("Initializing APC: %x\n", Timer->TimerApc);
KeInitializeApc(&Timer->TimerApc,
(PKNORMAL_ROUTINE)TimerApcRoutine,
PreviousMode,
TimerContext);
-
+
/* Lock the Thread's Active List and Insert */
KeAcquireSpinLockAtDpcLevel(&CurrentThread->ActiveTimerListLock);
InsertTailList(&CurrentThread->ActiveTimerListHead,
&Timer->ActiveTimerListEntry);
KeReleaseSpinLockFromDpcLevel(&CurrentThread->ActiveTimerListLock);
-
+
}
/* Enable and Set the Timer */
Period,
TimerApcRoutine ? &Timer->TimerDpc : 0);
Timer->ApcAssociated = TimerApcRoutine ? TRUE : FALSE;
-
+
/* Unlock the Timer */
KeReleaseSpinLock(&Timer->Lock, OldIrql);
/* Dereference the Object */
ObDereferenceObject(Timer);
-
+
/* Dereference if it was previously enabled */
if (!TimerApcRoutine) ObDereferenceObject(Timer);
if (KillTimer) ObDereferenceObject(Timer);
/* Make sure it's safe to write to the handle */
if(PreviousState != NULL) {
-
+
_SEH_TRY {
-
+
*PreviousState = State;
-
+
} _SEH_EXCEPT(_SEH_ExSystemExceptionFilter) {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/misc.c
ULARGE_INTEGER IntTime;
ULONG IntRange;
NTSTATUS Status;
-
+
PAGED_CODE();
ExAcquireFastMutex(&UuidMutex);
NtSetUuidSeed(IN PUCHAR Seed)
{
PAGED_CODE();
-
+
RtlCopyMemory(UuidSeed,
Seed,
SEED_BUFFER_SIZE);
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/win32k.c
* PURPOSE: Executive Win32 subsystem support
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Moved callbacks to win32k and cleanup.
* Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
POBJECT_TYPE EXPORTED ExDesktopObjectType = NULL;
static GENERIC_MAPPING ExpWindowStationMapping = {
-
+
STANDARD_RIGHTS_READ | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_READATTRIBUTES | WINSTA_READSCREEN,
STANDARD_RIGHTS_WRITE | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES,
STANDARD_RIGHTS_EXECUTE | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS,
};
static GENERIC_MAPPING ExpDesktopMapping = {
-
+
STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE | DESKTOP_READOBJECTS,
STANDARD_RIGHTS_WRITE | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL |
DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_WRITEOBJECTS,
/* FUNCTIONS ****************************************************************/
-NTSTATUS
+NTSTATUS
STDCALL
ExpWinStaObjectCreate(PVOID ObjectBody,
PVOID Parent,
struct _OBJECT_ATTRIBUTES* ObjectAttributes)
{
/* Call the Registered Callback */
- return ExpWindowStationObjectCreate(ObjectBody,
- Parent,
- RemainingPath,
+ return ExpWindowStationObjectCreate(ObjectBody,
+ Parent,
+ RemainingPath,
ObjectAttributes);
}
-VOID
+VOID
STDCALL
ExpWinStaObjectDelete(PVOID DeletedObject)
{
ULONG Attributes)
{
/* Call the Registered Callback */
- return ExpWindowStationObjectFind(WinStaObject,
- Name,
+ return ExpWindowStationObjectFind(WinStaObject,
+ Name,
Attributes);
}
-NTSTATUS
+NTSTATUS
STDCALL
ExpWinStaObjectParse(PVOID Object,
PVOID *NextObject,
ULONG Attributes)
{
/* Call the Registered Callback */
- return ExpWindowStationObjectParse(Object,
- NextObject,
- FullPath,
+ return ExpWindowStationObjectParse(Object,
+ NextObject,
+ FullPath,
Path,
Attributes);
}
-NTSTATUS
+NTSTATUS
STDCALL
ExpDesktopCreate(PVOID ObjectBody,
PVOID Parent,
struct _OBJECT_ATTRIBUTES* ObjectAttributes)
{
/* Call the Registered Callback */
- return ExpDesktopObjectCreate(ObjectBody,
- Parent,
- RemainingPath,
+ return ExpDesktopObjectCreate(ObjectBody,
+ Parent,
+ RemainingPath,
ObjectAttributes);
}
-VOID
+VOID
STDCALL
ExpDesktopDelete(PVOID DeletedObject)
{
ExpDesktopObjectDelete(DeletedObject);
}
-VOID
+VOID
INIT_FUNCTION
ExpWin32kInit(VOID)
{
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ex/work.c
* PURPOSE: Manage system work queues
- *
+ *
* PROGRAMMERS: Alex Ionescu - Used correct work queue array and added some fixes and checks.
* Gunnar Dalsnes - Implemented
*/
* calls PsTerminateSystemThread
*/
static
-VOID
+VOID
STDCALL
ExpWorkerThreadEntryPoint(IN PVOID Context)
{
PLIST_ENTRY QueueEntry;
WORK_QUEUE_TYPE WorkQueueType;
PEX_WORK_QUEUE WorkQueue;
-
+
/* Get Queue Type and Worker Queue */
WorkQueueType = (WORK_QUEUE_TYPE)Context;
WorkQueue = &ExWorkerQueue[WorkQueueType];
-
+
/* Loop forever */
while (TRUE) {
-
+
/* Wait for Something to Happen on the Queue */
QueueEntry = KeRemoveQueue(&WorkQueue->WorkerQueue, KernelMode, NULL);
-
+
/* Can't happen since we do a KernelMode wait (and we're a system thread) */
ASSERT((NTSTATUS)QueueEntry != STATUS_USER_APC);
-
+
/* this should never happen either, since we wait with NULL timeout,
* but there's a slight possibility that STATUS_TIMEOUT is returned
* at queue rundown in NT (unlikely) -Gunnar
*/
ASSERT((NTSTATUS)QueueEntry != STATUS_TIMEOUT);
-
+
/* Increment Processed Work Items */
InterlockedIncrement((PLONG)&WorkQueue->WorkItemsProcessed);
/* Get the Work Item */
WorkItem = CONTAINING_RECORD(QueueEntry, WORK_QUEUE_ITEM, List);
-
+
/* Call the Worker Routine */
WorkItem->WorkerRoutine(WorkItem->Parameter);
-
+
/* Make sure it returned at right IRQL */
if (KeGetCurrentIrql() != PASSIVE_LEVEL) {
-
+
/* FIXME: Make this an Ex */
KEBUGCHECK(WORKER_THREAD_RETURNED_AT_BAD_IRQL);
}
-
+
/* Make sure it returned with Impersionation Disabled */
if (PsGetCurrentThread()->ActiveImpersonationInfo) {
-
+
/* FIXME: Make this an Ex */
KEBUGCHECK(IMPERSONATING_WORKER_THREAD);
}
}
}
-static
-VOID
+static
+VOID
STDCALL
ExpInitializeWorkQueue(WORK_QUEUE_TYPE WorkQueueType,
KPRIORITY Priority)
ULONG i;
PETHREAD Thread;
HANDLE hThread;
-
+
/* Loop through how many threads we need to create */
for (i = 0; i < NUMBER_OF_WORKER_THREADS; i++) {
-
+
/* Create the System Thread */
PsCreateSystemThread(&hThread,
THREAD_ALL_ACCESS,
NULL,
ExpWorkerThreadEntryPoint,
(PVOID)WorkQueueType);
-
+
/* Get the Thread */
ObReferenceObjectByHandle(hThread,
THREAD_SET_INFORMATION,
KernelMode,
(PVOID*)&Thread,
NULL);
-
+
/* Set the Priority */
KeSetPriorityThread(&Thread->Tcb, Priority);
-
+
/* Dereference and close handle */
ObDereferenceObject(Thread);
ZwClose(hThread);
}
}
-VOID
+VOID
INIT_FUNCTION
ExpInitializeWorkerThreads(VOID)
{
ULONG WorkQueueType;
-
+
/* Initialize the Array */
for (WorkQueueType = 0; WorkQueueType < MaximumWorkQueue; WorkQueueType++) {
-
+
RtlZeroMemory(&ExWorkerQueue[WorkQueueType], sizeof(EX_WORK_QUEUE));
KeInitializeQueue(&ExWorkerQueue[WorkQueueType].WorkerQueue, 0);
}
-
+
/* Create the built-in worker threads for each work queue */
ExpInitializeWorkQueue(CriticalWorkQueue, LOW_REALTIME_PRIORITY);
ExpInitializeWorkQueue(DelayedWorkQueue, LOW_PRIORITY);
* WorkItem = Item to insert
* QueueType = Queue to insert it in
*/
-VOID
+VOID
STDCALL
ExQueueWorkItem(PWORK_QUEUE_ITEM WorkItem,
WORK_QUEUE_TYPE QueueType)
ASSERT(WorkItem!=NULL);
ASSERT_IRQL(DISPATCH_LEVEL);
ASSERT(WorkItem->List.Flink == NULL);
-
+
/* Insert the Queue */
KeInsertQueue(&ExWorkerQueue[QueueType].WorkerQueue, &WorkItem->List);
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/zone.c
* PURPOSE: Implements zone buffers
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
PZONE_SEGMENT_HEADER entry;
PZONE_SEGMENT_HEADER seg;
unsigned int i;
-
+
seg = (PZONE_SEGMENT_HEADER)Segment;
seg->Reserved = (PVOID) SegmentSize;
-
+
PushEntryList(&Zone->SegmentList,&seg->SegmentList);
-
+
entry = (PZONE_SEGMENT_HEADER)( ((char*)seg) + sizeof(ZONE_SEGMENT_HEADER) );
-
+
for (i=0;i<(SegmentSize / Zone->BlockSize);i++)
{
PushEntryList(&Zone->FreeList,&entry->SegmentList);
- entry = (PZONE_SEGMENT_HEADER)(((char*)entry) + sizeof(PZONE_SEGMENT_HEADER) +
+ entry = (PZONE_SEGMENT_HEADER)(((char*)entry) + sizeof(PZONE_SEGMENT_HEADER) +
Zone->BlockSize);
}
return(STATUS_SUCCESS);
{
NTSTATUS ret;
KIRQL oldlvl;
-
+
KeAcquireSpinLock(Lock,&oldlvl);
ret = ExExtendZone(Zone,Segment,SegmentSize);
KeReleaseSpinLock(Lock,oldlvl);
* ARGUMENTS:
* Zone = zone header to be initialized
* BlockSize = Size (in bytes) of the allocation size of the zone
- * InitialSegment = Initial segment of storage allocated by the
+ * InitialSegment = Initial segment of storage allocated by the
* caller
* InitialSegmentSize = Initial size of the segment
*/
unsigned int i;
PZONE_SEGMENT_HEADER seg;
PZONE_SEGMENT_HEADER entry;
-
+
Zone->FreeList.Next=NULL;
Zone->SegmentList.Next=NULL;
Zone->BlockSize=BlockSize;
Zone->TotalSegmentSize = InitialSegmentSize;
-
+
seg = (PZONE_SEGMENT_HEADER)InitialSegment;
seg->Reserved = (PVOID*) InitialSegmentSize;
-
+
PushEntryList(&Zone->SegmentList,&seg->SegmentList);
-
+
entry = (PZONE_SEGMENT_HEADER)( ((char*)seg) + sizeof(ZONE_SEGMENT_HEADER) );
-
+
for (i=0;i<(InitialSegmentSize / BlockSize);i++)
{
PushEntryList(&Zone->FreeList,&entry->SegmentList);
*
* NOTE
* From Bo Branten's ntifs.h v12.
- *
+ *
* @unimplemented
*/
BOOLEAN
* ARGUMENTS
*
* RETURN VALUE
- *
+ *
* NOTE
* From Bo Branten's ntifs.h v12.
*
* ARGUMENTS
*
* RETURN VALUE
- *
+ *
* @implemented
*/
NTSTATUS
ULONG Length;
PDEVICE_OBJECT DeviceObject;
PFAST_IO_DISPATCH FastDispatch;
-
+
/* Get Device Object and Fast Calls */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
-
+
/* Check if we support Fast Calls, and check this one */
- if (FastDispatch && FastDispatch->FastIoQueryStandardInfo)
+ if (FastDispatch && FastDispatch->FastIoQueryStandardInfo)
{
/* Fast Path */
- FastDispatch->FastIoQueryStandardInfo(FileObject,
+ FastDispatch->FastIoQueryStandardInfo(FileObject,
TRUE,
&Info,
&IoStatusBlock,
&Info,
&Length);
}
-
+
/* Check success */
if (NT_SUCCESS(Status))
{
{
PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
PFAST_IO_DISPATCH FastDispatch;
-
+
/* Get Device Object and Fast Calls */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
-
+
/* Check if we support Fast Calls, and check this one */
if (FastDispatch && FastDispatch->MdlRead)
{
IoStatus,
DeviceObject);
}
-
+
/* Get the Base File System (Volume) and Fast Calls */
BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
-
+
/* If the Base Device Object has its own FastDispatch Routine, fail */
- if (FastDispatch && FastDispatch->MdlRead &&
+ if (FastDispatch && FastDispatch->MdlRead &&
BaseDeviceObject != DeviceObject)
{
return FALSE;
}
-
+
/* No fast path, use slow path */
return FsRtlMdlReadDev(FileObject,
FileOffset,
*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
FsRtlMdlReadComplete(IN PFILE_OBJECT FileObject,
IN OUT PMDL MdlChain)
{
PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
PFAST_IO_DISPATCH FastDispatch;
-
+
/* Get Device Object and Fast Calls */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
-
+
/* Check if we support Fast Calls, and check this one */
if (FastDispatch && FastDispatch->MdlReadComplete)
{
MdlChain,
DeviceObject);
}
-
+
/* Get the Base File System (Volume) and Fast Calls */
BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
-
+
/* If the Base Device Object has its own FastDispatch Routine, fail */
- if (FastDispatch && FastDispatch->MdlReadComplete &&
+ if (FastDispatch && FastDispatch->MdlReadComplete &&
BaseDeviceObject != DeviceObject)
{
return FALSE;
}
-
+
/* No fast path, use slow path */
return FsRtlMdlReadCompleteDev(FileObject, MdlChain, DeviceObject);
}
{
PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
PFAST_IO_DISPATCH FastDispatch;
-
+
/* Get Device Object and Fast Calls */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
-
+
/* Check if we support Fast Calls, and check this one */
if (FastDispatch && FastDispatch->MdlWriteComplete)
{
MdlChain,
DeviceObject);
}
-
+
/* Get the Base File System (Volume) and Fast Calls */
BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
-
+
/* If the Base Device Object has its own FastDispatch Routine, fail */
- if (FastDispatch && FastDispatch->MdlWriteComplete &&
+ if (FastDispatch && FastDispatch->MdlWriteComplete &&
BaseDeviceObject != DeviceObject)
{
return FALSE;
}
-
+
/* No fast path, use slow path */
- return FsRtlMdlWriteCompleteDev(FileObject,
- FileOffset,
- MdlChain,
+ return FsRtlMdlWriteCompleteDev(FileObject,
+ FileOffset,
+ MdlChain,
DeviceObject);
}
* FsRtlMdlWriteCompleteDev@16
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
{
PDEVICE_OBJECT DeviceObject, BaseDeviceObject;
PFAST_IO_DISPATCH FastDispatch;
-
+
/* Get Device Object and Fast Calls */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
FastDispatch = DeviceObject->DriverObject->FastIoDispatch;
-
+
/* Check if we support Fast Calls, and check this one */
if (FastDispatch && FastDispatch->PrepareMdlWrite)
{
IoStatus,
DeviceObject);
}
-
+
/* Get the Base File System (Volume) and Fast Calls */
BaseDeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
FastDispatch = BaseDeviceObject->DriverObject->FastIoDispatch;
-
+
/* If the Base Device Object has its own FastDispatch Routine, fail */
- if (FastDispatch && FastDispatch->PrepareMdlWrite &&
+ if (FastDispatch && FastDispatch->PrepareMdlWrite &&
BaseDeviceObject != DeviceObject)
{
return FALSE;
}
-
+
/* No fast path, use slow path */
return FsRtlPrepareMdlWriteDev(FileObject,
FileOffset,
* FsRtlPrepareMdlWriteDev@28
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
-inline BOOLEAN
+inline BOOLEAN
IsOverlappingLock(
PFILE_LOCK_INFO Lock,
PLARGE_INTEGER StartOffset,
{
if ((ULONGLONG)StartOffset->QuadPart > (ULONGLONG)Lock->EndingByte.QuadPart)
{
- return FALSE;
+ return FALSE;
}
-
+
if ((ULONGLONG)EndOffset->QuadPart < (ULONGLONG)Lock->StartingByte.QuadPart)
{
- return FALSE;
+ return FALSE;
}
-
- return TRUE;
+
+ return TRUE;
}
-inline BOOLEAN
+inline BOOLEAN
IsSurroundingLock(
PFILE_LOCK_INFO Lock,
PLARGE_INTEGER StartOffset,
PLARGE_INTEGER EndOffset
)
{
- if ((ULONGLONG)StartOffset->QuadPart >= (ULONGLONG)Lock->StartingByte.QuadPart &&
+ if ((ULONGLONG)StartOffset->QuadPart >= (ULONGLONG)Lock->StartingByte.QuadPart &&
(ULONGLONG)EndOffset->QuadPart <= (ULONGLONG)Lock->EndingByte.QuadPart)
{
- return TRUE;
+ return TRUE;
}
-
- return FALSE;
+
+ return FALSE;
}
);
ExInitializeFastMutex(&LockTocMutex);
-
+
}
/**********************************************************************
*
*/
VOID
-STDCALL
+STDCALL
FsRtlpFileLockCancelRoutine(
- IN PDEVICE_OBJECT DeviceObject,
+ IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PKSPIN_LOCK SpinLock;
//don't need this since we have our own sync. protecting irp cancellation
- IoReleaseCancelSpinLock(Irp->CancelIrql);
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
SpinLock = Irp->Tail.Overlay.DriverContext[3];
KeAcquireSpinLock(SpinLock, &oldIrql);
-
+
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
-
+
KeReleaseSpinLock(SpinLock, oldIrql);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+
}
/**********************************************************************
* NAME PRIVATE
* FsRtlpCheckLockForReadOrWriteAccess
*
- * Return:
+ * Return:
* TRUE: can read/write
* FALSE: can't read/write
*/
PFILE_LOCK_GRANTED Granted;
PLIST_ENTRY EnumEntry;
LARGE_INTEGER EndOffset;
-
+
ASSERT(FileLock);
-
+
LockToc = FileLock->LockInformation;
- if (LockToc == NULL || Length->QuadPart == 0)
+ if (LockToc == NULL || Length->QuadPart == 0)
{
return TRUE;
}
LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
{
Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED, ListEntry);
-
+
//if overlapping
- if(IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset))
+ if(IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset))
{
//No read conflict if (shared lock) OR (exclusive + our lock)
//No write conflict if exclusive lock AND our lock
if ((Read && !Granted->Lock.ExclusiveLock) ||
- (Granted->Lock.ExclusiveLock &&
+ (Granted->Lock.ExclusiveLock &&
Granted->Lock.Process == Process &&
Granted->Lock.FileObject == FileObject &&
- Granted->Lock.Key == Key ) )
+ Granted->Lock.Key == Key ) )
{
//AND if lock surround request region, stop searching and grant
if (IsSurroundingLock(&Granted->Lock, FileOffset, &EndOffset) )
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
return TRUE;
}
-
+
//else continue searching for conflicts
continue;
}
InitializeListHead(&UnlockedListHead);
GotUnlockRoutine = FileLock->UnlockRoutine != NULL;
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
-
+
LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted, FILE_LOCK_GRANTED, ListEntry)
{
-
+
if (Granted->Lock.Process == Process &&
Granted->Lock.FileObject == FileObject &&
(!UseKey || (UseKey && Granted->Lock.Key == Key)) )
RemoveEntryList(&Granted->ListEntry);
Unlock = TRUE;
- if (GotUnlockRoutine)
+ if (GotUnlockRoutine)
{
/*
Put on unlocked list and call unlock routine for them afterwards.
*/
InsertHeadList(&UnlockedListHead,&Granted->ListEntry);
}
- else
+ else
{
- ExFreeToNPagedLookasideList(&GrantedLookaside,Granted);
+ ExFreeToNPagedLookasideList(&GrantedLookaside,Granted);
}
}
}
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
-
+
if (Unlock)
{
//call unlock routine for each unlocked lock (if any)
- while (!IsListEmpty(&UnlockedListHead))
+ while (!IsListEmpty(&UnlockedListHead))
{
EnumEntry = RemoveTailList(&UnlockedListHead);
Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry);
-
+
FileLock->UnlockRoutine(Granted->UnlockContext, &Granted->Lock);
ExFreeToNPagedLookasideList(&GrantedLookaside,Granted);
}
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql, Context);
- if (IsListEmpty(&LockToc->GrantedListHead))
+ if (IsListEmpty(&LockToc->GrantedListHead))
{
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
FsRtlAreThereCurrentFileLocks(FileLock) = FALSE;
{
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
}
-
+
return STATUS_SUCCESS;
}
Process,
0, /* Key is ignored */
FALSE, /* Do NOT use Key */
- Context
+ Context
);
}
Process,
Key,
TRUE, /* Use Key */
- Context
+ Context
);
}
PLIST_ENTRY EnumEntry;
PFILE_LOCK_GRANTED Granted;
LARGE_INTEGER EndOffset;
-
+
EndOffset.QuadPart = FileOffset->QuadPart + Length->QuadPart - 1;
//loop and try to find conflicking locks
LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
{
Granted = CONTAINING_RECORD(EnumEntry,FILE_LOCK_GRANTED, ListEntry);
-
+
if (IsOverlappingLock(&Granted->Lock, FileOffset, &EndOffset))
{
//we found a locks that overlap with the new lock
-
+
//if both locks are shared, we might have a fast path outa here...
- if (!Granted->Lock.ExclusiveLock && !ExclusiveLock)
+ if (!Granted->Lock.ExclusiveLock && !ExclusiveLock)
{
//if existing lock surround new lock, we know that no other exclusive lock
//may overlap with our new lock;-D
{
break;
}
-
+
//else keep locking for conflicts
continue;
}
-
- //we found a conflict:
+
+ //we found a conflict:
//we want shared access to an excl. lock OR exlc. access to a shared lock
return FALSE;
}
PIRP Irp;
PIO_STACK_LOCATION Stack;
LIST_ENTRY CompletedListHead;
-
+
InitializeListHead(&CompletedListHead);
-
- LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->PendingListHead, Irp, IRP, Tail.Overlay.ListEntry)
+
+ LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->PendingListHead, Irp, IRP, Tail.Overlay.ListEntry)
{
Stack = IoGetCurrentIrpStackLocation(Irp);
if (FsRtlpAddLock(LockToc,
Stack->Parameters.LockControl.Key,
Stack->Flags & SL_EXCLUSIVE_LOCK,
Irp->Tail.Overlay.DriverContext[2] //Context
- ) )
+ ) )
{
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
}
KeReleaseSpinLock(&LockToc->SpinLock, *oldirql);
-
+
//complete irp's (if any)
- while (!IsListEmpty(&CompletedListHead))
+ while (!IsListEmpty(&CompletedListHead))
{
EnumEntry = RemoveTailList(&CompletedListHead);
-
+
Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry);
Irp->IoStatus.Status = STATUS_SUCCESS;
if (FileLock->CompleteLockIrpRoutine(Context, Irp)!=STATUS_SUCCESS)
{
Stack = IoGetCurrentIrpStackLocation(Irp);
-
- //revert
+
+ //revert
FsRtlpUnlockSingle ( FileLock,
Stack->FileObject,
&Stack->Parameters.LockControl.ByteOffset,
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql );
- LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted,FILE_LOCK_GRANTED,ListEntry)
+ LIST_FOR_EACH_SAFE(EnumEntry, &LockToc->GrantedListHead, Granted,FILE_LOCK_GRANTED,ListEntry)
{
-
+
//must be exact match
if (FileOffset->QuadPart == Granted->Lock.StartingByte.QuadPart &&
Length->QuadPart == Granted->Lock.Length.QuadPart &&
Granted->Lock.Process == Process &&
Granted->Lock.FileObject == FileObject &&
- Granted->Lock.Key == Key)
+ Granted->Lock.Key == Key)
{
RemoveEntryList(&Granted->ListEntry);
FsRtlpCompletePendingLocks(FileLock, LockToc, &oldirql, Context);
if (IsListEmpty(&LockToc->GrantedListHead))
{
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
-
+
FsRtlAreThereCurrentFileLocks(FileLock) = FALSE; //paged data
}
else
ASSERT(FileLock);
LockToc = FileLock->LockInformation;
- if (LockToc == NULL)
+ if (LockToc == NULL)
{
DPRINT1("No file locks\n");
return;
LIST_FOR_EACH(EnumEntry, &LockToc->GrantedListHead)
{
Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED , ListEntry);
-
+
DPRINT1("%s, start: %i, len: %i, end: %i, key: %i, proc: 0x%X, fob: 0x%X\n",
Granted->Lock.ExclusiveLock ? "EXCL" : "SHRD",
Granted->Lock.StartingByte.QuadPart,
{
/*
Messy enumeration of granted locks.
- What our last ptr. in LastReturnedLock points at, might have been freed between
+ What our last ptr. in LastReturnedLock points at, might have been freed between
calls, so we have to scan thru the list every time, searching for our last lock.
If it's not there anymore, restart the enumeration...
*/
FileLock->LastReturnedLock = EnumEntry;
return &FileLock->LastReturnedLockInfo;
}
- else
+ else
{
KeReleaseSpinLock(&LockToc->SpinLock,oldirql);
return NULL;
}
//else: continue enum
- while (EnumEntry != &LockToc->GrantedListHead)
+ while (EnumEntry != &LockToc->GrantedListHead)
{
//found previous lock?
- if (EnumEntry == LocalLastReturnedLock)
+ if (EnumEntry == LocalLastReturnedLock)
{
FoundPrevious = TRUE;
//get next
EnumEntry = EnumEntry->Flink;
}
- if (!FoundPrevious)
+ if (!FoundPrevious)
{
//got here? uh no, didn't find our last lock..must have been freed...restart
Restart = TRUE;
KIRQL oldirql;
ASSERT(FileLock);
- if (FileLock->LockInformation == NULL)
+ if (FileLock->LockInformation == NULL)
{
ExAcquireFastMutex(&LockTocMutex);
//still NULL?
Process,
Key,
ExclusiveLock,
- Context
- ) )
+ Context
+ ) )
{
IoStatus->Status = STATUS_SUCCESS;
}
- else if (Irp && !FailImmediately)
- {
+ else if (Irp && !FailImmediately)
+ {
//failed + irp + no fail = make. pending
Irp->Tail.Overlay.DriverContext[3] = &LockToc->SpinLock;
Irp->Tail.Overlay.DriverContext[2] = Context;
-
+
IoSetCancelRoutine(Irp, FsRtlpFileLockCancelRoutine);
if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
- {
+ {
//irp was canceled
KeReleaseSpinLock(&LockToc->SpinLock, oldirql);
-
+
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
InsertHeadList(&LockToc->PendingListHead,&Irp->Tail.Overlay.ListEntry);
}
- else
+ else
{
IoStatus->Status = STATUS_LOCK_NOT_GRANTED;
}
//never pending if no irp;-)
ASSERT(!(IoStatus->Status == STATUS_PENDING && !Irp));
- if (IoStatus->Status != STATUS_PENDING)
+ if (IoStatus->Status != STATUS_PENDING)
{
- if (IoStatus->Status == STATUS_SUCCESS)
+ if (IoStatus->Status == STATUS_SUCCESS)
{
FsRtlAreThereCurrentFileLocks(FileLock) = TRUE;
}
- if (Irp)
+ if (Irp)
{
Irp->IoStatus.Status = IoStatus->Status;
Irp->IoStatus.Information = 0;
- if (FileLock->CompleteLockIrpRoutine)
+ if (FileLock->CompleteLockIrpRoutine)
{
- if (FileLock->CompleteLockIrpRoutine(Context,Irp)!=STATUS_SUCCESS)
+ if (FileLock->CompleteLockIrpRoutine(Context,Irp)!=STATUS_SUCCESS)
{
//CompleteLockIrpRoutine complain: revert changes
FsRtlpUnlockSingle( FileLock,
);
}
}
- else
+ else
{
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
Stack->Parameters.LockControl.Length,
IoGetRequestorProcess(Irp),
Stack->Parameters.LockControl.Key,
- Context,
+ Context,
FALSE);
break;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
-
+
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return Status;
KeAcquireSpinLock(&LockToc->SpinLock, &oldirql);
//remove and free granted locks
- while (!IsListEmpty(&LockToc->GrantedListHead))
+ while (!IsListEmpty(&LockToc->GrantedListHead))
{
EnumEntry = RemoveTailList(&LockToc->GrantedListHead);
Granted = CONTAINING_RECORD(EnumEntry, FILE_LOCK_GRANTED, ListEntry);
}
//remove, complete and free all pending locks
- while (!IsListEmpty(&LockToc->PendingListHead))
+ while (!IsListEmpty(&LockToc->PendingListHead))
{
EnumEntry = RemoveTailList(&LockToc->PendingListHead);
Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry);
if (!IoSetCancelRoutine(Irp, NULL))
- {
+ {
//The cancel routine will be called. When we release the lock it will complete the irp.
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
continue;
PFAST_IO_DISPATCH FastDispatch;
PDEVICE_OBJECT DeviceObject;
PFSRTL_COMMON_FCB_HEADER FcbHeader;
-
+
/* Get the Device Object */
DeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
-
+
/* Check if we have to do a Fast I/O Dispatch */
if ((FastDispatch = DeviceObject->DriverObject->FastIoDispatch)) {
if (FastDispatch->AcquireFileForNtCreateSection) {
FastDispatch->AcquireFileForNtCreateSection(FileObject);
}
-
+
return;
}
-
+
/* Do a normal acquire */
if ((FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)) {
-
+
/* Use a Resource Acquire */
ExAcquireResourceExclusive(FcbHeader->Resource, TRUE);
-
+
return;
}
-
+
/* Return...is there some kind of failure we should raise?? */
return;
}
PFAST_IO_DISPATCH FastDispatch;
PDEVICE_OBJECT DeviceObject;
PFSRTL_COMMON_FCB_HEADER FcbHeader;
-
+
/* Get the Device Object */
DeviceObject = IoGetBaseFileSystemDeviceObject(FileObject);
-
+
/* Check if we have to do a Fast I/O Dispatch */
if ((FastDispatch = DeviceObject->DriverObject->FastIoDispatch)) {
-
+
/* Use Fast I/O */
if (FastDispatch->ReleaseFileForNtCreateSection) {
FastDispatch->ReleaseFileForNtCreateSection(FileObject);
}
-
+
return;
}
-
+
/* Do a normal acquire */
if ((FcbHeader = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext)) {
-
+
/* Use a Resource Release */
ExReleaseResource(FcbHeader->Resource);
-
+
return;
}
-
+
/* Return...is there some kind of failure we should raise?? */
return;
}
* NAME EXPORTED
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
&llVbn,
&llLbn,
&llSectorCount);
-
+
/* Return everything typecasted */
*Vbn = (ULONG)llVbn;
*Lbn = (ULONG)llLbn;
*SectorCount = (ULONG)llSectorCount;
-
+
/* And return the original value */
return(Return);
}
Return = FsRtlLookupLastLargeMcbEntry(&Mcb->LargeMcb,
&llVbn,
&llLbn);
-
+
/* Return everything typecasted */
*Vbn = (ULONG)llVbn;
*Lbn = (ULONG)llLbn;
-
+
/* And return the original value */
return(Return);
}
NULL,
NULL,
Index);
-
+
/* Return everything typecasted */
*Lbn = (ULONG)llLbn;
if (SectorCount) *SectorCount = (ULONG)llSectorCount;
-
+
/* And return the original value */
return(Return);
}
*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
FsRtlAreNamesEqual(IN PUNICODE_STRING Name1,
IN PUNICODE_STRING Name2,
UNICODE_STRING UpcaseName1;
UNICODE_STRING UpcaseName2;
BOOLEAN StringsAreEqual;
-
+
/* Well, first check their size */
if (Name1->Length != Name2->Length) {
/* Not equal! */
return FALSE;
}
-
+
/* Turn them into Upcase if we don't have a table */
if (IgnoreCase && !UpcaseTable) {
RtlUpcaseUnicodeString(&UpcaseName1, Name1, TRUE);
Name1 = &UpcaseName1;
Name2 = &UpcaseName2;
- goto ManualCase;
+ goto ManualCase;
}
-
+
/* Do a case-sensitive search */
if (!IgnoreCase) {
-
+
ManualCase:
/* Use a raw memory compare */
StringsAreEqual = RtlEqualMemory(Name1->Buffer,
Name2->Buffer,
Name1->Length);
-
+
/* Clear the strings if we need to */
if (IgnoreCase) {
RtlFreeUnicodeString(&UpcaseName1);
RtlFreeUnicodeString(&UpcaseName2);
}
-
+
/* Return the equality */
return StringsAreEqual;
-
+
} else {
-
+
/* Case in-sensitive search */
-
+
LONG i;
-
+
for (i = Name1->Length / sizeof(WCHAR) - 1; i >= 0; i--) {
-
+
if (UpcaseTable[Name1->Buffer[i]] != UpcaseTable[Name2->Buffer[i]]) {
-
+
/* Non-match found! */
return FALSE;
}
- }
-
+ }
+
/* We finished the loop so we are equal */
return TRUE;
}
*
* @implemented
*/
-VOID
+VOID
STDCALL
FsRtlDissectDbcs(IN ANSI_STRING Name,
OUT PANSI_STRING FirstPart,
{
ULONG i;
ULONG FirstLoop;
-
+
/* Initialize the Outputs */
RtlZeroMemory(&FirstPart, sizeof(ANSI_STRING));
RtlZeroMemory(&RemainingPart, sizeof(ANSI_STRING));
-
+
/* Bail out if empty */
if (!Name.Length) return;
-
+
/* Ignore backslash */
if (Name.Buffer[0] == '\\') {
i = 1;
} else {
i = 0;
}
-
+
/* Loop until we find a backslash */
for (FirstLoop = i;i < Name.Length;i++) {
if (Name.Buffer[i] != '\\') break;
if (FsRtlIsLeadDbcsCharacter(Name.Buffer[i])) i++;
}
-
+
/* Now we have the First Part */
FirstPart->Length = (i-FirstLoop);
FirstPart->MaximumLength = FirstPart->Length; /* +2?? */
FirstPart->Buffer = &Name.Buffer[FirstLoop];
-
+
/* Make the second part if something is still left */
if (i<Name.Length) {
RemainingPart->Length = (Name.Length - (i+1));
RemainingPart->MaximumLength = RemainingPart->Length; /* +2?? */
RemainingPart->Buffer = &Name.Buffer[i+1];
}
-
+
return;
}
*
* @implemented
*/
-VOID
+VOID
STDCALL
FsRtlDissectName(IN UNICODE_STRING Name,
OUT PUNICODE_STRING FirstPart,
NameLength++;
}
- FirstPart->Length =
+ FirstPart->Length =
FirstPart->MaximumLength = NameLength * sizeof(WCHAR);
FirstPart->Buffer = &Name.Buffer[NameOffset];
*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
FsRtlDoesDbcsContainWildCards(IN PANSI_STRING Name)
{
ULONG i;
-
+
/* Check every character */
for (i=0;i < Name->Length;i++) {
-
+
/* First make sure it's not the Lead DBCS */
if (FsRtlIsLeadDbcsCharacter(Name->Buffer[i])) {
i++;
return TRUE;
}
}
-
+
/* We didn't return above...so none found */
return FALSE;
}
*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
{
* FsRtlIsDbcsInExpression@8
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
*
* @unimplemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
FsRtlIsDbcsInExpression(IN PANSI_STRING Expression,
IN PANSI_STRING Name)
*/
BOOLEAN
STDCALL
-FsRtlIsFatDbcsLegal(IN ANSI_STRING DbcsName,
- IN BOOLEAN WildCardsPermissible,
- IN BOOLEAN PathNamePermissible,
- IN BOOLEAN LeadingBackslashPermissible)
+FsRtlIsFatDbcsLegal(IN ANSI_STRING DbcsName,
+ IN BOOLEAN WildCardsPermissible,
+ IN BOOLEAN PathNamePermissible,
+ IN BOOLEAN LeadingBackslashPermissible)
{
return FALSE;
}
* FsRtlIsHpfsDbcsLegal@20
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
*
* @unimplemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
-FsRtlIsHpfsDbcsLegal(IN ANSI_STRING DbcsName,
- IN BOOLEAN WildCardsPermissible,
- IN BOOLEAN PathNamePermissible,
- IN BOOLEAN LeadingBackslashPermissible)
+FsRtlIsHpfsDbcsLegal(IN ANSI_STRING DbcsName,
+ IN BOOLEAN WildCardsPermissible,
+ IN BOOLEAN PathNamePermissible,
+ IN BOOLEAN LeadingBackslashPermissible)
{
return FALSE;
}
*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
FsRtlIsNameInExpression(IN PUNICODE_STRING Expression,
IN PUNICODE_STRING Name,
BOOLEAN Unicode;
BOOLEAN BufferExhausted;
PVOID Buffer; /* Buffer == NULL equals IgnoreBuffer == TRUE */
- ULONG BufferSize;
- ULONG NextEntryOffset;
+ ULONG BufferSize;
+ ULONG NextEntryOffset;
PFILE_NOTIFY_INFORMATION PrevEntry;
} NOTIFY_ENTRY, *PNOTIFY_ENTRY;
0
);
-
+
}
)
{
ASSERT(Path->Length);
-
- if (Path->Length == 1) return FALSE;
-
+
+ if (Path->Length == 1) return FALSE;
+
if (*(WCHAR*)Path->Buffer == '\\') return TRUE;
-
+
return FALSE;
}
*/
static
VOID
-STDCALL
+STDCALL
FsRtlpNotifyCancelRoutine(
- IN PDEVICE_OBJECT DeviceObject,
+ IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PFAST_MUTEX Lock;
//don't need this since we have our own sync. protecting irp cancellation
- IoReleaseCancelSpinLock(Irp->CancelIrql);
+ IoReleaseCancelSpinLock(Irp->CancelIrql);
Lock = (PFAST_MUTEX)Irp->Tail.Overlay.DriverContext[3];
ExAcquireFastMutex(Lock );
-
+
RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
-
+
ExReleaseFastMutex(Lock);
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+
}
{
PLIST_ENTRY EnumEntry;
PNOTIFY_ENTRY NotifyEntry;
-
+
LIST_FOR_EACH(EnumEntry, NotifyList)
{
NotifyEntry = CONTAINING_RECORD(EnumEntry, NOTIFY_ENTRY, ListEntry);
-
+
if (NotifyEntry->FsContext == FsContext)
{
return NotifyEntry;
}
}
- return NULL;
+ return NULL;
}
/**********************************************************************
* FsRtlNotifyChangeDirectory@28
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
LIST_ENTRY CompletedListHead;
PLIST_ENTRY TmpEntry;
PIRP Irp;
-
+
InitializeListHead(&CompletedListHead);
-
- ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
-
+
+ ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
+
NotifyEntry = FsRtlpFindNotifyEntry(NotifyList, FsContext);
-
+
if (NotifyEntry)
{
/* free buffered changes */
/* irp cancelation bolilerplate */
if (!IoSetCancelRoutine(Irp, NULL))
- {
+ {
//The cancel routine will be called. When we release the lock it will complete the irp.
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
continue;
/* avoid holding lock while completing irp */
InsertTailList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry);
}
-
+
/* Unlink and free the NotifyStruct */
RemoveEntryList(&NotifyEntry->ListEntry);
ExFreeToPagedLookasideList(&NotifyEntryLookaside, NotifyEntry);
}
-
+
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
-
+
/* complete defered irps */
- while (!IsListEmpty(&CompletedListHead))
+ while (!IsListEmpty(&CompletedListHead))
{
TmpEntry = RemoveHeadList(&CompletedListHead);
Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
-
+
}
PLIST_ENTRY EnumEntry, TmpEntry;
PNOTIFY_ENTRY NotifyEntry;
PIRP Irp;
-
+
InitializeListHead(&CompletedListHead);
-
+
ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
LIST_FOR_EACH_SAFE(EnumEntry, NotifyList, NotifyEntry, NOTIFY_ENTRY, ListEntry )
{
if (NotifyEntry->Fcb == Fcb)
{
- RemoveEntryList(&NotifyEntry->ListEntry);
-
+ RemoveEntryList(&NotifyEntry->ListEntry);
+
/* free buffered changes */
if (NotifyEntry->Buffer)
{
ExFreePool(NotifyEntry->Buffer);
}
-
+
/* cleanup pending irps */
while (!IsListEmpty(&NotifyEntry->IrpQueue))
{
/* irp cancelation bolilerplate */
if (!IoSetCancelRoutine(Irp, NULL))
- {
+ {
//The cancel routine will be called. When we release the lock it will complete the irp.
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
continue;
}
-
+
Irp->IoStatus.Status = STATUS_DELETE_PENDING;
Irp->IoStatus.Information = 0;
-
+
/* avoid holding lock while completing irp */
InsertTailList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry);
}
}
}
-
- ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
-
+
+ ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
+
/* complete defered irps */
- while (!IsListEmpty(&CompletedListHead))
+ while (!IsListEmpty(&CompletedListHead))
{
TmpEntry = RemoveHeadList(&CompletedListHead);
Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry);
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
-
+
}
* FsRtlNotifyFullChangeDirectory@40
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL
)
{
- PIO_STACK_LOCATION IrpStack;
+ PIO_STACK_LOCATION IrpStack;
PNOTIFY_ENTRY NotifyEntry;
ULONG IrpBuffLen;
-
+
if (!Irp)
{
/* all other params are ignored if NotifyIrp == NULL */
FsRtlpWatchedDirectoryWasDeleted(NotifySync, NotifyList, FsContext);
return;
}
-
+
DPRINT("FullDirectoryName: %wZ\n", FullDirectoryName);
-
+
ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
-
+
IrpStack = IoGetCurrentIrpStackLocation(Irp);
if (IrpStack->FileObject->Flags & FO_CLEANUP_COMPLETE)
{
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
-
+
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_NOTIFY_CLEANUP;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return;
+ return;
}
-
+
IrpBuffLen = IrpStack->Parameters.NotifyDirectory.Length;
-
+
NotifyEntry = FsRtlpFindNotifyEntry(NotifyList, FsContext);
if (!NotifyEntry)
{
/* No NotifyStruct for this FileObject existed */
-
+
/* The first request for this FileObject set the standards.
* For subsequent requests, these params will be ignored.
* Ref: Windows NT File System Internals page 516
*/
-
+
NotifyEntry = ExAllocateFromPagedLookasideList(&NotifyEntryLookaside);
-
+
RtlZeroMemory(NotifyEntry, sizeof(NOTIFY_ENTRY));
-
+
NotifyEntry->FsContext = FsContext;
NotifyEntry->FullDirectoryName = FullDirectoryName;
NotifyEntry->WatchTree = WatchTree;
IrpBuffLen,
FSRTL_NOTIFY_TAG
);
-
+
NotifyEntry->BufferSize = IrpBuffLen;
}
_SEH_HANDLE
}
InitializeListHead(&NotifyEntry->IrpQueue);
-
+
InsertTailList(NotifyList, &NotifyEntry->ListEntry);
}
-
-
-
+
+
+
if (!NotifyEntry->PendingChanges)
{
/* No changes are pending. Queue the irp */
/* Irp cancelation boilerplate */
-
+
/* save NotifySych for use in the cancel routine */
Irp->Tail.Overlay.DriverContext[3] = NotifySync;
IoSetCancelRoutine(Irp, FsRtlpNotifyCancelRoutine);
if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
- {
+ {
//irp was canceled
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
//FIXME: any point in setting irp status/information before queueing?
Irp->IoStatus.Status = STATUS_PENDING;
-
+
InsertTailList(&NotifyEntry->IrpQueue, &Irp->Tail.Overlay.ListEntry);
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
return;
}
-
+
/* Pending changes exist */
-
- if (NotifyEntry->Buffer == NULL ||
+
+ if (NotifyEntry->Buffer == NULL ||
NotifyEntry->BufferExhausted ||
IrpBuffLen < NotifyEntry->NextEntryOffset)
{
-Buffer were overflowed, OR
-Current irp buff was not large enough
*/
-
+
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_NOTIFY_ENUM_DIR;
Irp->IoStatus.Status = STATUS_SUCCESS;
}
-
+
/* reset buffer */
NotifyEntry->PrevEntry = NULL;
NotifyEntry->NextEntryOffset = 0;
NotifyEntry->BufferExhausted = FALSE;
-
+
NotifyEntry->PendingChanges = FALSE;
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
-
+
IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
+
/* caller must return STATUS_PENDING */
}
FsRtlpGetNextIrp(PNOTIFY_ENTRY NotifyEntry)
{
PIRP Irp;
- PLIST_ENTRY TmpEntry;
-
+ PLIST_ENTRY TmpEntry;
+
/* Loop to get a non-canceled irp */
while (!IsListEmpty(&NotifyEntry->IrpQueue))
{
/* If we have queued irp(s) we can't possibly have pending changes too */
ASSERT(!NotifyEntry->PendingChanges);
-
+
TmpEntry = RemoveHeadList(&NotifyEntry->IrpQueue);
Irp = CONTAINING_RECORD(TmpEntry , IRP, Tail.Overlay.ListEntry);
/* irp cancelation bolilerplate */
if (!IoSetCancelRoutine(Irp, NULL))
- {
+ {
//The cancel routine will be called. When we release the lock it will complete the irp.
InitializeListHead(&Irp->Tail.Overlay.ListEntry);
continue;
}
/* Finally we got a non-canceled irp */
- return Irp;
+ return Irp;
}
-
+
return NULL;
}
-
-
+
+
static
inline
VOID
if (StreamName)
{
CurrentEntry->Name[RelativeName->Length/sizeof(WCHAR)] = ':';
- memcpy(&CurrentEntry ->Name[(RelativeName->Length/sizeof(WCHAR))+1],
+ memcpy(&CurrentEntry ->Name[(RelativeName->Length/sizeof(WCHAR))+1],
StreamName->Buffer,
StreamName->Length);
}
* FsRtlNotifyFullReportChange@36
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
USHORT NameLenU;
ULONG RecordLen;
PFILE_NOTIFY_INFORMATION CurrentEntry;
-
+
InitializeListHead(&CompletedListHead);
DPRINT("FullTargetName: %wZ\n", FullTargetName);
I think FullTargetName can include/be a short file name! What the heck do i do with this?
Dont think this apply to FsRtlNotifyFullChangeDirectory's FullDirectoryName.
*/
-
-
- ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
+
+
+ ExAcquireFastMutex((PFAST_MUTEX)NotifySync);
LIST_FOR_EACH_SAFE(EnumEntry, NotifyList, NotifyEntry, NOTIFY_ENTRY, ListEntry )
{
ASSERT(NotifyEntry->Unicode == FsRtlpIsUnicodePath(FullTargetName));
-
+
/* rule out some easy cases */
/* FIXME: short vs. long names??? lower case/upper case/mixed case? */
if (!(FilterMatch & NotifyEntry->CompletionFilter)) continue;
-
+
FullDirLen = TargetNameOffset - (NotifyEntry->Unicode ? sizeof(WCHAR) : sizeof(char));
if (FullDirLen == 0)
{
/* special case for root dir */
FullDirLen = (NotifyEntry->Unicode ? sizeof(WCHAR) : sizeof(char));
}
-
+
if (FullDirLen < NotifyEntry->FullDirectoryName->Length) continue;
-
+
if (!NotifyEntry->WatchTree && FullDirLen != NotifyEntry->FullDirectoryName->Length) continue;
DPRINT("NotifyEntry->FullDirectoryName: %wZ\n", NotifyEntry->FullDirectoryName);
-
+
/* FIXME: short vs. long names??? lower case/upper case/mixed case? */
- if (memcmp(NotifyEntry->FullDirectoryName->Buffer,
- FullTargetName->Buffer,
+ if (memcmp(NotifyEntry->FullDirectoryName->Buffer,
+ FullTargetName->Buffer,
NotifyEntry->FullDirectoryName->Length) != 0) continue;
-
- if (NotifyEntry->WatchTree &&
+
+ if (NotifyEntry->WatchTree &&
NotifyEntry->TraverseCallback &&
FullDirLen != NotifyEntry->FullDirectoryName->Length)
{
NTSTATUS Status = NotifyEntry->TraverseCallback(NotifyEntry->FsContext,
TargetContext,
NotifyEntry->SubjectContext);
-
+
if (!NT_SUCCESS(Status)) continue;
-
+
/*
FIXME: notify-dir impl. should release and free the SubjectContext
*/
}
DPRINT("Found match\n");
-
+
/* Found a valid change */
RelativeName.Buffer = FullTargetName->Buffer + TargetNameOffset;
- RelativeName.MaximumLength =
- RelativeName.Length =
+ RelativeName.MaximumLength =
+ RelativeName.Length =
FullTargetName->Length - TargetNameOffset;
-
+
DPRINT("RelativeName: %wZ\n",&RelativeName);
-
+
/* calculate unicode bytes of relative-name + stream-name */
if (NotifyEntry->Unicode)
{
}
else
{
- NameLenU = RelativeName.Length * sizeof(WCHAR) +
+ NameLenU = RelativeName.Length * sizeof(WCHAR) +
(StreamName ? ((StreamName->Length * sizeof(WCHAR)) + sizeof(WCHAR)) : 0);
}
-
+
RecordLen = FIELD_OFFSET(FILE_NOTIFY_INFORMATION, Name) + NameLenU;
-
+
if ((Irp = FsRtlpGetNextIrp(NotifyEntry)))
{
PIO_STACK_LOCATION IrpStack;
ULONG IrpBuffLen;
-
+
IrpStack = IoGetCurrentIrpStackLocation(Irp);
IrpBuffLen = IrpStack->Parameters.NotifyDirectory.Length;
-
+
DPRINT("Got pending irp\n");
-
+
ASSERT(!NotifyEntry->PendingChanges);
-
- if (NotifyEntry->Buffer == NULL || /* aka. IgnoreBuffer */
+
+ if (NotifyEntry->Buffer == NULL || /* aka. IgnoreBuffer */
RecordLen > IrpBuffLen)
{
/* ignore buffer / buffer not large enough */
}
else
{
- CurrentEntry = (PFILE_NOTIFY_INFORMATION)
+ CurrentEntry = (PFILE_NOTIFY_INFORMATION)
MmGetSystemAddressForMdlSafe(Irp->MdlAddress, LowPagePriority);
-
+
if (CurrentEntry)
{
- CurrentEntry->Action = Action;
+ CurrentEntry->Action = Action;
CurrentEntry->NameLength = NameLenU;
CurrentEntry->NextEntryOffset = 0;
&RelativeName,
StreamName
);
-
+
Irp->IoStatus.Information = RecordLen;
}
else
{
Irp->IoStatus.Information = 0;
}
-
+
Irp->IoStatus.Status = STATUS_SUCCESS;
}
-
+
/* avoid holding lock while completing irp */
InsertTailList(&CompletedListHead, &Irp->Tail.Overlay.ListEntry);
}
else
{
DPRINT("No irp\n");
-
+
NotifyEntry->PendingChanges = TRUE;
if (NotifyEntry->Buffer == NULL || NotifyEntry->BufferExhausted) continue;
-
+
if (RecordLen > NotifyEntry->BufferSize - NotifyEntry->NextEntryOffset)
{
/* overflow. drop these changes and stop buffering any other changes too */
/* The buffer has enough room for the changes.
* Copy data to buffer.
*/
-
+
CurrentEntry = (PFILE_NOTIFY_INFORMATION)NotifyEntry->Buffer;
-
- CurrentEntry->Action = Action;
+
+ CurrentEntry->Action = Action;
CurrentEntry->NameLength = NameLenU;
CurrentEntry->NextEntryOffset = 0;
&RelativeName,
StreamName
);
-
+
if (NotifyEntry->PrevEntry)
{
NotifyEntry->PrevEntry->NextEntryOffset = (char*)CurrentEntry - (char*)NotifyEntry->PrevEntry;
}
NotifyEntry->PrevEntry = CurrentEntry;
NotifyEntry->NextEntryOffset += RecordLen;
-
+
// {
// UNICODE_STRING TmpStr;
// TmpStr.MaximumLength = TmpStr.Length = BufferedChange->NameLen;
// DPRINT("BufferedChange->RelativeName: %wZ\n", &TmpStr);
// }
-
+
}
}
ExReleaseFastMutex((PFAST_MUTEX)NotifySync);
-
+
/* complete defered irps */
- while (!IsListEmpty(&CompletedListHead))
+ while (!IsListEmpty(&CompletedListHead))
{
EnumEntry = RemoveHeadList(&CompletedListHead);
Irp = CONTAINING_RECORD(EnumEntry, IRP, Tail.Overlay.ListEntry);
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
-
+
}
* FsRtlNotifyInitializeSync@4
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlNotifyReportChange@20
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
*
* PROGRAMMERS: No programmer listed.
*/
-
+
#include <ntoskrnl.h>
* FsRtlCheckOplock@20
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlCurrentBatchOplock@4
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlInitializeOplock@4
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlOplockFsctrl@12
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlOplockIsFastIoPossible@4
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlUninitializeOplock@4
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlAllocatePool@8
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlAllocatePoolWithQuota@8
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlAllocatePoolWithQuotaTag@12
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlAllocatePoolWithTag@12
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlAddToTunnelCache@32
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlDeleteKeyFromTunnelCache@12
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlDeleteTunnelCache@4
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlFindInTunnelCache@32
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlInitializeTunnelCache@4
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlDeregisterUncProvider@4
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
* FsRtlRegisterUncProvider@12
*
* DESCRIPTION
- *
+ *
* ARGUMENTS
*
* RETURN VALUE
#define FSRTL_MAX_RESOURCES 16
-#define FTTYPE ((ULONG)'f')
+#define FTTYPE ((ULONG)'f')
#define FT_BALANCED_READ_MODE \
CTL_CODE(FTTYPE, 6, METHOD_NEITHER, FILE_ANY_ACCESS)
RtlpInitializeResources(VOID)
{
ULONG i;
-
+
/* Allocate the Resource Buffer */
- FsRtlpResources = FsRtlAllocatePool(NonPagedPool,
+ FsRtlpResources = FsRtlAllocatePool(NonPagedPool,
FSRTL_MAX_RESOURCES*sizeof(ERESOURCE));
-
+
/* Initialize the Resources */
for (i = 0; i < FSRTL_MAX_RESOURCES; i++)
{
/* FUNCTIONS *****************************************************************/
/*++
- * @name FsRtlIsTotalDeviceFailure
+ * @name FsRtlIsTotalDeviceFailure
* @implemented NT 4.0
*
* The FsRtlIsTotalDeviceFailure routine checks if an NTSTATUS error code
STDCALL
FsRtlIsTotalDeviceFailure(IN NTSTATUS NtStatus)
{
- return((NT_SUCCESS(NtStatus)) ||
+ return((NT_SUCCESS(NtStatus)) ||
(STATUS_CRC_ERROR == NtStatus) ||
(STATUS_DEVICE_DATA_ERROR == NtStatus) ? FALSE : TRUE);
}
/*++
- * @name FsRtlIsNtstatusExpected
+ * @name FsRtlIsNtstatusExpected
* @implemented NT 4.0
*
* The FsRtlIsNtstatusExpected routine checks if an NTSTATUS error code
FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
{
return((STATUS_DATATYPE_MISALIGNMENT == NtStatus) ||
- (STATUS_ACCESS_VIOLATION == NtStatus) ||
- (STATUS_ILLEGAL_INSTRUCTION == NtStatus) ||
+ (STATUS_ACCESS_VIOLATION == NtStatus) ||
+ (STATUS_ILLEGAL_INSTRUCTION == NtStatus) ||
(STATUS_INSTRUCTION_MISALIGNMENT == NtStatus)) ? FALSE : TRUE;
}
/*++
- * @name FsRtlIsPagingFile
+ * @name FsRtlIsPagingFile
* @implemented NT 4.0
*
* The FsRtlIsPagingFile routine checks if the FileObject is a Paging File.
}
/*++
- * @name FsRtlNormalizeNtstatus
+ * @name FsRtlNormalizeNtstatus
* @implemented NT 4.0
*
* The FsRtlNormalizeNtstatus routine normalizes an NTSTATUS error code.
* The NTSTATUS error code to return if the NtStatusToNormalize is not
* a proper expected error code by the File System Library.
*
- * @return NtStatusToNormalize if it is an expected value, otherwise
+ * @return NtStatusToNormalize if it is an expected value, otherwise
* NormalizedNtStatus.
*
* @remarks None.
FsRtlNormalizeNtstatus(IN NTSTATUS NtStatusToNormalize,
IN NTSTATUS NormalizedNtStatus)
{
- return(TRUE == FsRtlIsNtstatusExpected(NtStatusToNormalize)) ?
+ return(TRUE == FsRtlIsNtstatusExpected(NtStatusToNormalize)) ?
NtStatusToNormalize : NormalizedNtStatus;
}
/*++
- * @name FsRtlAllocateResource
+ * @name FsRtlAllocateResource
* @implemented NT 4.0
*
* The FsRtlAllocateResource routine returns a pre-initialized ERESOURCE
}
/*++
- * @name FsRtlBalanceReads
+ * @name FsRtlBalanceReads
* @implemented NT 4.0
*
* The FsRtlBalanceReads routine sends an IRP to an FTDISK Driver
- * requesting the driver to balance read requests across a mirror set.
+ * requesting the driver to balance read requests across a mirror set.
*
* @param TargetDevice
* A pointer to an FTDISK Device Object.
KEVENT Event;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
-
+
/* Initialize the Local Event */
KeInitializeEvent(&Event, NotificationEvent, FALSE);
-
+
/* Build the special IOCTL */
Irp = IoBuildDeviceIoControlRequest(FT_BALANCED_READ_MODE,
TargetDevice,
FALSE,
&Event,
&IoStatusBlock);
-
+
/* Send it */
Status = IoCallDriver(TargetDevice, Irp);
-
+
/* Wait if needed */
if (Status == STATUS_PENDING)
{
/* Return Status */
Status = IoStatusBlock.Status;
}
-
+
return Status;
}
/*++
- * @name FsRtlPostPagingFileStackOverflow
+ * @name FsRtlPostPagingFileStackOverflow
* @unimplemented NT 4.0
*
* The FsRtlPostPagingFileStackOverflow routine
*
- * @param Context
+ * @param Context
*
* @param Event
- *
- * @param StackOverflowRoutine
*
- * @return
+ * @param StackOverflowRoutine
+ *
+ * @return
*
* @remarks None.
*
*--*/
VOID
STDCALL
-FsRtlPostPagingFileStackOverflow(IN PVOID Context,
- IN PKEVENT Event,
- IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
+FsRtlPostPagingFileStackOverflow(IN PVOID Context,
+ IN PKEVENT Event,
+ IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
{
UNIMPLEMENTED;
}
/*++
- * @name FsRtlPostStackOverflow
+ * @name FsRtlPostStackOverflow
* @unimplemented NT 4.0
*
* The FsRtlPostStackOverflow routine
* @param Context
*
* @param Event
- *
- * @param StackOverflowRoutine
*
- * @return
+ * @param StackOverflowRoutine
+ *
+ * @return
*
* @remarks None.
*
*--*/
VOID
STDCALL
-FsRtlPostStackOverflow(IN PVOID Context,
- IN PKEVENT Event,
- IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
+FsRtlPostStackOverflow(IN PVOID Context,
+ IN PKEVENT Event,
+ IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
{
UNIMPLEMENTED;
}
/*++
- * @name FsRtlSyncVolumes
+ * @name FsRtlSyncVolumes
* @implemented NT 4.0
*
- * The FsRtlSyncVolumes routine is deprecated.
+ * The FsRtlSyncVolumes routine is deprecated.
*
* @return Always returns STATUS_SUCCESS.
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/inbv/inbv.c
* PURPOSE: Boot video support
- *
+ *
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
/* Tag */
#define CALLBACK_TAG TAG('C','L','B','K')
-
+
/* ROS Callback Object */
typedef struct _INT_CALLBACK_OBJECT {
KSPIN_LOCK Lock;
#define CALLBACK_READ (STANDARD_RIGHTS_READ|SYNCHRONIZE|0x0001)
/* Mapping for Callback Object */
-GENERIC_MAPPING ExpCallbackMapping =
+GENERIC_MAPPING ExpCallbackMapping =
{
CALLBACK_READ,
CALLBACK_WRITE,
{
/* Base address of the region where the cache segment data is mapped. */
PVOID BaseAddress;
- /*
- * Memory area representing the region where the cache segment data is
- * mapped.
+ /*
+ * Memory area representing the region where the cache segment data is
+ * mapped.
*/
struct _MEMORY_AREA* MemoryArea;
/* Are the contents of the cache segment data valid. */
BOOLEAN Valid;
/* Are the contents of the cache segment data newer than those on disk. */
BOOLEAN Dirty;
- /* Page out in progress */
+ /* Page out in progress */
BOOLEAN PageOut;
ULONG MappedCount;
/* Entry in the list of segments for this BCB. */
CSHORT RefCount; /* (At offset 0x34 on WinNT4) */
} INTERNAL_BCB, *PINTERNAL_BCB;
-VOID
+VOID
STDCALL
CcMdlReadCompleteDev(IN PMDL MdlChain,
IN PFILE_OBJECT FileObject);
-
-VOID
+
+VOID
STDCALL
CcMdlWriteCompleteDev(IN PLARGE_INTEGER FileOffset,
IN PMDL MdlChain,
VOID
CcInitView(VOID);
-NTSTATUS
+NTSTATUS
CcRosFreeCacheSegment(PBCB, PCACHE_SEGMENT);
-NTSTATUS
+NTSTATUS
ReadCacheSegment(PCACHE_SEGMENT CacheSeg);
-NTSTATUS
+NTSTATUS
WriteCacheSegment(PCACHE_SEGMENT CacheSeg);
VOID CcInit(VOID);
NTSTATUS
CcRosUnmapCacheSegment(PBCB Bcb, ULONG FileOffset, BOOLEAN NowDirty);
-PCACHE_SEGMENT
+PCACHE_SEGMENT
CcRosLookupCacheSegment(PBCB Bcb, ULONG FileOffset);
NTSTATUS
ULONG Length,
PCACHE_SEGMENT* CacheSeg);
-VOID
+VOID
CcInitCacheZeroPage(VOID);
NTSTATUS
NTSTATUS
CcRosFlushDirtyPages(ULONG Target, PULONG Count);
-VOID
+VOID
CcRosDereferenceCache(PFILE_OBJECT FileObject);
-VOID
+VOID
CcRosReferenceCache(PFILE_OBJECT FileObject);
-VOID
+VOID
CcRosSetRemoveOnClose(PSECTION_OBJECT_POINTERS SectionObjectPointer);
NTSTATUS
PBOOLEAN UptoDate,
CACHE_SEGMENT** CacheSeg);
-NTSTATUS
+NTSTATUS
CcTryToInitializeFileCache(PFILE_OBJECT FileObject);
/*
* FILE: include/internal/debug.h
* PURPOSE: Useful debugging macros
* PROGRAMMER: David Welch (welch@mcmail.com)
- * UPDATE HISTORY:
+ * UPDATE HISTORY:
* 28/05/98: Created
*/
/* OTHER FUNCTIONS **********************************************************/
-LONGLONG
+LONGLONG
FASTCALL
ExfpInterlockedExchange64(LONGLONG volatile * Destination,
PLONGLONG Exchange);
/*
- *
+ *
*/
#ifndef __INTERNAL_HAL_HAL_H
NtEarlyInitVdm(VOID);
VOID
KeApplicationProcessorInitDispatcher(VOID);
-VOID
+VOID
KeCreateApplicationProcessorIdleThread(ULONG Id);
-typedef
-VOID
+typedef
+VOID
STDCALL
-(*PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine,
+(*PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine,
PVOID StartContext);
VOID
STDCALL
-Ke386InitThreadWithContext(PKTHREAD Thread,
+Ke386InitThreadWithContext(PKTHREAD Thread,
PKSYSTEM_ROUTINE SystemRoutine,
PKSTART_ROUTINE StartRoutine,
PVOID StartContext,
PCONTEXT Context);
-
+
VOID
STDCALL
-KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
- PKSTART_ROUTINE StartRoutine,
- PVOID StartContext,
+KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
+ PKSTART_ROUTINE StartRoutine,
+ PVOID StartContext,
BOOLEAN UserThread,
KTRAP_FRAME TrapFrame);
-
+
#ifdef CONFIG_SMP
#define LOCK "lock ; "
#else
#define Ke386SetLocalDescriptorTable(X) \
__asm__("lldt %0\n\t" \
: /* no outputs */ \
- : "m" (X));
+ : "m" (X));
#define Ke386SetGlobalDescriptorTable(X) \
__asm__("lgdt %0\n\t" \
: /* no outputs */ \
{
LONG OldBit;
- __asm__ __volatile__(LOCK
+ __asm__ __volatile__(LOCK
"btrl %2,%1\n\t"
"sbbl %0,%0\n\t"
:"=r" (OldBit),"=m" (*Addr)
- :"Ir" (BitPos)
+ :"Ir" (BitPos)
: "memory");
return OldBit;
}
"btsl %2,%1\n\t"
"sbbl %0,%0\n\t"
:"=r" (OldBit),"=m" (*Addr)
- :"Ir" (BitPos)
+ :"Ir" (BitPos)
: "memory");
return OldBit;
}
* Page access attributes (or these together)
*/
#define PA_READ (1<<0)
-#define PA_WRITE ((1<<0)+(1<<1))
+#define PA_WRITE ((1<<0)+(1<<1))
#define PA_EXECUTE PA_READ
#define PA_PCD (1<<4)
#define PA_PWT (1<<3)
#define KPCR_SELF 0x1C
#define KPCR_GDT 0x3C
#define KPCR_TSS 0x40
-#define KPCR_CURRENT_THREAD 0x124
+#define KPCR_CURRENT_THREAD 0x124
#define KPCR_NPX_THREAD 0x2A4
#ifndef __ASM__
PVOID SpecialRegisters;
} KPROCESSOR_STATE;
-/* ProcessoR Control Block */
+/* ProcessoR Control Block */
typedef struct _KPRCB {
USHORT MinorVersion;
USHORT MajorVersion;
VOID STDCALL
FsRtlpFileLockCancelRoutine(
- IN PDEVICE_OBJECT DeviceObject,
+ IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
IN ULONG Key,
IN PFILE_OBJECT FileObject,
IN PEPROCESS Process,
- IN BOOLEAN Read
+ IN BOOLEAN Read
);
NTSTATUS FASTCALL
ULONG StartIoFlags;
struct _VPB *Vpb;
} DEVOBJ_EXTENSION, *PDEVOBJ_EXTENSION;
-
+
typedef struct _PRIVATE_DRIVER_EXTENSIONS {
struct _PRIVATE_DRIVER_EXTENSIONS *Link;
PVOID ClientIdentificationAddress;
PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes);
-NTSTATUS
+NTSTATUS
STDCALL
IopAttachVpb(PDEVICE_OBJECT DeviceObject);
/* file.c */
-NTSTATUS
+NTSTATUS
STDCALL
IopCreateFile(PVOID ObjectBody,
PVOID Parent,
PWSTR RemainingPath,
POBJECT_ATTRIBUTES ObjectAttributes);
-
-VOID
+
+VOID
STDCALL
IopDeleteFile(PVOID ObjectBody);
SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
PULONG BufferLength);
-
+
NTSTATUS
STDCALL
IopQueryNameFile(PVOID ObjectBody,
POBJECT_NAME_INFORMATION ObjectNameInfo,
ULONG Length,
PULONG ReturnLength);
-
-VOID
+
+VOID
STDCALL
IopCloseFile(PVOID ObjectBody,
ULONG HandleCount);
-
+
/* plugplay.c */
NTSTATUS INIT_FUNCTION
WORD wMaxModBits;
BYTE ModNumber[1];
} MODIFIERS, *PMODIFIERS;
-
+
#define TYPEDEF_VK_TO_WCHARS(i) \
typedef struct _VK_TO_WCHARS ## i { \
BYTE VirtualKey; \
WCHAR wchComposed;
USHORT uFlags;
} DEADKEY, *PDEADKEY;
-
+
typedef WCHAR *DEADKEY_LPWSTR;
#define DKF_DEAD 1
#define CAPLOKALTGR 4
#define KANALOK 8
#define GRPSELTAP 0x80
-
+
#ifdef __cplusplus
};
KdbSymInit(IN PMODULE_TEXT_SECTION NtoskrnlTextSection,
IN PMODULE_TEXT_SECTION LdrHalTextSection);
-BOOLEAN
+BOOLEAN
KdbSymPrintAddress(IN PVOID Address);
VOID
STDCALL
KdpScreenInit(struct _KD_DISPATCH_TABLE *DispatchTable,
ULONG BootPhase);
-
+
VOID
STDCALL
KdpSerialInit(struct _KD_DISPATCH_TABLE *DispatchTable,
ULONG BootPhase);
-
+
VOID
STDCALL
KdpInitDebugLog(struct _KD_DISPATCH_TABLE *DispatchTable,
ULONG BootPhase);
-
+
/* KD ROUTINES ***************************************************************/
KD_CONTINUE_TYPE
PKTRAP_FRAME TrapFrame,
BOOLEAN FirstChance,
BOOLEAN Gdb);
-
+
ULONG
STDCALL
KdpPrintString(PANSI_STRING String);
BOOLEAN
STDCALL
KdpDetectConflicts(PCM_RESOURCE_LIST DriverList);
-
+
/* KD GLOBALS ***************************************************************/
/* serial debug connection */
UCHAR Screen :1;
UCHAR Serial :1;
UCHAR File :1;
-
+
/* Currently Supported Wrappers */
UCHAR Pice :1;
UCHAR Gdb :1;
UCHAR Bochs :1;
};
-
+
/* Generic Value */
ULONG Value;
};
LIST_ENTRY KdProvidersList;
PKDP_INIT_ROUTINE KdpInitRoutine;
PKDP_PRINT_ROUTINE KdpPrintRoutine;
- PKDP_PROMPT_ROUTINE KdpPromptRoutine;
+ PKDP_PROMPT_ROUTINE KdpPromptRoutine;
PKDP_EXCEPTION_ROUTINE KdpExceptionRoutine;
} KD_DISPATCH_TABLE, *PKD_DISPATCH_TABLE;
/* Wrapper Init Function */
extern PKDP_INIT_ROUTINE WrapperInitRoutine;
-
+
/* Dispatch Tables for Native Providers */
extern KD_DISPATCH_TABLE DispatchTable[KdMax];
/* Dispatch Table for the Wrapper */
extern KD_DISPATCH_TABLE WrapperTable;
-
+
/* The KD Native Provider List */
extern LIST_ENTRY KdProviders;
KdbpDisassemble(
IN ULONG Address,
IN ULONG IntelSyntax);
-
+
LONG
KdbpGetInstLength(
IN ULONG Address);
IN PCHAR ConditionExpression OPTIONAL,
IN BOOLEAN Global,
OUT PULONG BreakPointNumber OPTIONAL);
-
+
BOOLEAN
KdbpDeleteBreakPoint(
IN LONG BreakPointNr OPTIONAL,
STDCALL
KdpBochsInit(struct _KD_DISPATCH_TABLE *DispatchTable,
ULONG BootPhase);
-
+
#endif /* __INCLUDE_INTERNAL_KD_BOCHS_H */
ULONG BootPhase);
extern KD_PORT_INFORMATION GdbPortInfo;
-
+
#endif /* __INCLUDE_INTERNAL_KD_BOCHS_H */
{
/* For waiting on thread exit */
DISPATCHER_HEADER DispatcherHeader; /* 00 */
-
+
/* List of mutants owned by the thread */
LIST_ENTRY MutantListHead; /* 10 */
PVOID InitialStack; /* 18 */
ULONG_PTR StackLimit; /* 1C */
-
+
/* Pointer to the thread's environment block in user memory */
struct _TEB *Teb; /* 20 */
-
+
/* Pointer to the thread's TLS array */
PVOID TlsArray; /* 24 */
PVOID KernelStack; /* 28 */
UCHAR DebugActive; /* 2C */
-
+
/* Thread state (one of THREAD_STATE_xxx constants below) */
UCHAR State; /* 2D */
BOOLEAN Alerted[2]; /* 2E */
} KTHREAD;
#include <poppack.h>
-
+
typedef struct _KEXECUTE_OPTIONS
{
UCHAR ExecuteDisable:1;
* KERNEL VERSION: 5.2
* DOCUMENTATION: http://reactos.com/wiki/index.php/KPROCESS
*/
-typedef struct _KPROCESS
+typedef struct _KPROCESS
{
DISPATCHER_HEADER Header; /* 000 */
LIST_ENTRY ProfileListHead; /* 010 */
UCHAR Iopl; /* 032 */
UCHAR Unused; /* 033 */
ULONG ActiveProcessors; /* 034 */
- ULONG KernelTime; /* 038 */
+ ULONG KernelTime; /* 038 */
ULONG UserTime; /* 03C */
LIST_ENTRY ReadyListHead; /* 040 */
LIST_ENTRY SwapListEntry; /* 048 */
LIST_ENTRY ThreadListHead; /* 050 */
KSPIN_LOCK ProcessLock; /* 058 */
KAFFINITY Affinity; /* 05C */
- union {
+ union {
struct {
ULONG AutoAlignment:1; /* 060.0 */
ULONG DisableBoost:1; /* 060.1 */
Ready,
Running,
Standby,
- Terminated,
+ Terminated,
Waiting,
Transition,
DeferredReady,
PKTHREAD _Thread = KeGetCurrentThread(); \
if (_Thread) _Thread->KernelApcDisable--; \
}
-
+
#define KeLeaveCriticalRegion(X) \
{ \
PKTHREAD _Thread = KeGetCurrentThread(); \
/* Thread Scheduler Functions */
/* Readies a Thread for Execution. */
-VOID
+VOID
STDCALL
KiDispatchThreadNoLock(ULONG NewThreadStatus);
/* Readies a Thread for Execution. */
-VOID
+VOID
STDCALL
KiDispatchThread(ULONG NewThreadStatus);
/* Puts a Thread into a block state. */
VOID
STDCALL
-KiBlockThread(PNTSTATUS Status,
- UCHAR Alertable,
+KiBlockThread(PNTSTATUS Status,
+ UCHAR Alertable,
ULONG WaitMode,
UCHAR WaitReason);
-
-/* Removes a thread out of a block state. */
+
+/* Removes a thread out of a block state. */
VOID
STDCALL
-KiUnblockThread(PKTHREAD Thread,
- PNTSTATUS WaitStatus,
+KiUnblockThread(PKTHREAD Thread,
+ PNTSTATUS WaitStatus,
KPRIORITY Increment);
-
+
NTSTATUS
STDCALL
KeSuspendThread(PKTHREAD Thread);
NTSTATUS
FASTCALL
KiSwapContext(PKTHREAD NewThread);
-
+
/* gmutex.c ********************************************************************/
VOID
KiAcquireGuardedMutexContented(PKGUARDED_MUTEX GuardedMutex);
/* gate.c **********************************************************************/
-
-VOID
+
+VOID
FASTCALL
KeInitializeGate(PKGATE Gate);
/* ipi.c ********************************************************************/
-BOOLEAN STDCALL
-KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
+BOOLEAN STDCALL
+KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
IN struct _KEXCEPTION_FRAME* ExceptionFrame);
-VOID
-KiIpiSendRequest(ULONG TargetSet,
+VOID
+KiIpiSendRequest(ULONG TargetSet,
ULONG IpiRequest);
-VOID
-KeIpiGenericCall(VOID (STDCALL *WorkerRoutine)(PVOID),
+VOID
+KeIpiGenericCall(VOID (STDCALL *WorkerRoutine)(PVOID),
PVOID Argument);
/* next file ***************************************************************/
} CACHED_MODULE_TYPE, *PCACHED_MODULE_TYPE;
extern PLOADER_MODULE CachedModules[MaximumCachedModuleType];
-VOID STDCALL
+VOID STDCALL
DbgBreakPointNoBugCheck(VOID);
STDCALL
IN KPROFILE_SOURCE Source
);
-BOOLEAN
+BOOLEAN
STDCALL
KiRosPrintAddress(PVOID Address);
VOID
STDCALL
-KeInitializeThread(struct _KPROCESS* Process,
- PKTHREAD Thread,
+KeInitializeThread(struct _KPROCESS* Process,
+ PKTHREAD Thread,
PKSYSTEM_ROUTINE SystemRoutine,
PKSTART_ROUTINE StartRoutine,
PVOID StartContext,
BOOLEAN KiTestAlert(VOID);
VOID
-FASTCALL
-KiAbortWaitThread(PKTHREAD Thread,
+FASTCALL
+KiAbortWaitThread(PKTHREAD Thread,
NTSTATUS WaitStatus,
KPRIORITY Increment);
-
+
VOID
STDCALL
KeInitializeProcess(struct _KPROCESS *Process,
KPRIORITY Priority,
KAFFINITY Affinity,
LARGE_INTEGER DirectoryTableBase);
-
+
ULONG
STDCALL
KeForceResumeThread(IN PKTHREAD Thread);
-
+
BOOLEAN STDCALL KiInsertTimer(PKTIMER Timer, LARGE_INTEGER DueTime);
VOID inline FASTCALL KiSatisfyObjectWait(PDISPATCHER_HEADER Object, PKTHREAD Thread);
VOID
STDCALL
KiKernelApcDeliveryCheck(VOID);
-LONG
-STDCALL
-KiInsertQueue(IN PKQUEUE Queue,
- IN PLIST_ENTRY Entry,
+LONG
+STDCALL
+KiInsertQueue(IN PKQUEUE Queue,
+ IN PLIST_ENTRY Entry,
BOOLEAN Head);
-
+
ULONG
STDCALL
-KeSetProcess(struct _KPROCESS* Process,
+KeSetProcess(struct _KPROCESS* Process,
KPRIORITY Increment);
-
-
+
+
VOID STDCALL KeInitializeEventPair(PKEVENT_PAIR EventPair);
VOID STDCALL KiInitializeUserApc(IN PVOID Reserved,
VOID
KiAddProfileEvent(KPROFILE_SOURCE Source, ULONG Pc);
-VOID
+VOID
KiDispatchException(PEXCEPTION_RECORD ExceptionRecord,
PCONTEXT Context,
PKTRAP_FRAME Tf,
NTSTATUS
STDCALL
-LdrpMapSystemDll(PEPROCESS Process,
+LdrpMapSystemDll(PEPROCESS Process,
PVOID *DllBase);
NTSTATUS
PVOID
LdrpGetSystemDllEntryPoint (VOID);
-PVOID
+PVOID
LdrpGetSystemDllApcDispatcher(VOID);
-PVOID
+PVOID
LdrpGetSystemDllExceptionDispatcher(VOID);
-PVOID
+PVOID
LdrpGetSystemDllCallbackDispatcher(VOID);
PVOID
LdrpGetSystemDllRaiseExceptionDispatcher(VOID);
typedef struct _MM_PAGEOP
{
/* Type of operation. */
- ULONG OpType;
+ ULONG OpType;
/* Number of threads interested in this operation. */
ULONG ReferenceCount;
/* Event that will be set when the operation is completed. */
ULONG Hash;
struct _MM_PAGEOP* Next;
struct _ETHREAD* Thread;
- /*
+ /*
* These fields are used to identify the operation if it is against a
* virtual memory area.
*/
LIST_ENTRY RegionListEntry;
} MM_REGION, *PMM_REGION;
-typedef VOID (*PMM_FREE_PAGE_FUNC)(PVOID Context, PMEMORY_AREA MemoryArea,
+typedef VOID (*PMM_FREE_PAGE_FUNC)(PVOID Context, PMEMORY_AREA MemoryArea,
PVOID Address, PFN_TYPE Page,
SWAPENTRY SwapEntry, BOOLEAN Dirty);
PMEMORY_AREA STDCALL
MmLocateMemoryAreaByAddress(
- PMADDRESS_SPACE AddressSpace,
+ PMADDRESS_SPACE AddressSpace,
PVOID Address);
ULONG_PTR STDCALL
MmFindGapAtAddress(
- PMADDRESS_SPACE AddressSpace,
+ PMADDRESS_SPACE AddressSpace,
PVOID Address);
NTSTATUS STDCALL
PMEMORY_AREA STDCALL
MmLocateMemoryAreaByRegion(
- PMADDRESS_SPACE AddressSpace,
+ PMADDRESS_SPACE AddressSpace,
PVOID Address,
ULONG_PTR Length);
VOID MiShutdownMemoryManager(VOID);
-VOID MmInit1(ULONG_PTR FirstKernelPhysAddress,
+VOID MmInit1(ULONG_PTR FirstKernelPhysAddress,
ULONG_PTR LastKernelPhysAddress,
ULONG_PTR LastKernelAddress,
PADDRESS_RANGE BIOSMemoryMap,
NTSTATUS MmWriteToSwapPage(SWAPENTRY SwapEntry, PFN_TYPE Page);
-NTSTATUS STDCALL
+NTSTATUS STDCALL
MmDumpToPagingFile(ULONG BugCode,
ULONG BugCodeParameter1,
ULONG BugCodeParameter2,
STDCALL
MmCreateProcessAddressSpace(IN struct _EPROCESS* Process,
IN PSECTION_OBJECT Section OPTIONAL);
-
+
NTSTATUS
STDCALL
MmCreatePeb(PEPROCESS Process);
MmCreateTeb(PEPROCESS Process,
PCLIENT_ID ClientId,
PINITIAL_TEB InitialTeb);
-
+
VOID
STDCALL
MmDeleteTeb(PEPROCESS Process,
/* anonmem.c *****************************************************************/
NTSTATUS MmNotPresentFaultVirtualMemory(PMADDRESS_SPACE AddressSpace,
- MEMORY_AREA* MemoryArea,
+ MEMORY_AREA* MemoryArea,
PVOID Address,
BOOLEAN Locked);
VOID
STDCALL
-MmDeleteKernelStack(PVOID Stack,
+MmDeleteKernelStack(PVOID Stack,
BOOLEAN GuiStack);
-
+
/* balace.c ******************************************************************/
-VOID MmInitializeMemoryConsumer(ULONG Consumer,
+VOID MmInitializeMemoryConsumer(ULONG Consumer,
NTSTATUS (*Trim)(ULONG Target, ULONG Priority, PULONG NrFreed));
VOID MmInitializeBalancer(ULONG NrAvailablePages, ULONG NrSystemPages);
VOID MmInsertRmap(PFN_TYPE Page, PEPROCESS Process, PVOID Address);
-VOID MmDeleteAllRmaps(PFN_TYPE Page, PVOID Context,
+VOID MmDeleteAllRmaps(PFN_TYPE Page, PVOID Context,
VOID (*DeleteMapping)(PVOID Context, PEPROCESS Process, PVOID Address));
VOID MmDeleteRmap(PFN_TYPE Page, PEPROCESS Process, PVOID Address);
PFN_TYPE MmDeleteHyperspaceMapping(PVOID Address);
-NTSTATUS MmCreateVirtualMappingForKernel(PVOID Address,
+NTSTATUS MmCreateVirtualMappingForKernel(PVOID Address,
ULONG flProtect,
PPFN_TYPE Pages,
ULONG PageCount);
NTSTATUS MmCommitPagedPoolAddress(PVOID Address, BOOLEAN Locked);
NTSTATUS MmCreateVirtualMapping(struct _EPROCESS* Process,
- PVOID Address,
+ PVOID Address,
ULONG flProtect,
PPFN_TYPE Pages,
ULONG PageCount);
NTSTATUS MmCreateVirtualMappingUnsafe(struct _EPROCESS* Process,
- PVOID Address,
+ PVOID Address,
ULONG flProtect,
PPFN_TYPE Pages,
ULONG PageCount);
PVOID Address,
ULONG flProtect);
-BOOLEAN MmIsPagePresent(struct _EPROCESS* Process,
+BOOLEAN MmIsPagePresent(struct _EPROCESS* Process,
PVOID Address);
VOID MmInitGlobalKernelPageDirectory(VOID);
PFN_TYPE MmGetPfnForProcess(struct _EPROCESS* Process, PVOID Address);
-NTSTATUS
+NTSTATUS
STDCALL
-MmCopyMmInfo(struct _EPROCESS* Src,
- struct _EPROCESS* Dest,
+MmCopyMmInfo(struct _EPROCESS* Src,
+ struct _EPROCESS* Dest,
PPHYSICAL_ADDRESS DirectoryTableBase);
NTSTATUS MmReleaseMmInfo(struct _EPROCESS* Process);
NTSTATUS Mmi386ReleaseMmInfo(struct _EPROCESS* Process);
VOID MmDeleteVirtualMapping(struct _EPROCESS* Process,
- PVOID Address,
+ PVOID Address,
BOOL FreePage,
BOOL* WasDirty,
PPFN_TYPE Page);
/* region.c ************************************************************/
-NTSTATUS MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress,
- PLIST_ENTRY RegionListHead, PVOID StartAddress, ULONG Length,
- ULONG NewType, ULONG NewProtect,
+NTSTATUS MmAlterRegion(PMADDRESS_SPACE AddressSpace, PVOID BaseAddress,
+ PLIST_ENTRY RegionListHead, PVOID StartAddress, ULONG Length,
+ ULONG NewType, ULONG NewProtect,
PMM_ALTER_REGION_FUNC AlterFunc);
VOID MmInitialiseRegion(PLIST_ENTRY RegionListHead, ULONG Length, ULONG Type,
/* section.c *****************************************************************/
-PVOID STDCALL
+PVOID STDCALL
MmAllocateSection (IN ULONG Length, PVOID BaseAddress);
NTSTATUS STDCALL
PMEMORY_BASIC_INFORMATION Info,
PULONG ResultLength);
-NTSTATUS
+NTSTATUS
MmProtectSectionView(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID BaseAddress,
ULONG Protect,
PULONG OldProtect);
-NTSTATUS
+NTSTATUS
MmWritePageSectionView(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MArea,
PVOID Address,
IN HANDLE FileHandle OPTIONAL,
IN PFILE_OBJECT File OPTIONAL);
-NTSTATUS
+NTSTATUS
MmNotPresentFaultSectionView(PMADDRESS_SPACE AddressSpace,
- MEMORY_AREA* MemoryArea,
+ MEMORY_AREA* MemoryArea,
PVOID Address,
BOOLEAN Locked);
-NTSTATUS
+NTSTATUS
MmPageOutSectionView(PMADDRESS_SPACE AddressSpace,
PMEMORY_AREA MemoryArea,
PVOID Address,
struct _MM_PAGEOP* PageOp);
-NTSTATUS
+NTSTATUS
MmCreatePhysicalMemorySection(VOID);
-NTSTATUS
+NTSTATUS
MmAccessFaultSectionView(PMADDRESS_SPACE AddressSpace,
- MEMORY_AREA* MemoryArea,
+ MEMORY_AREA* MemoryArea,
PVOID Address,
BOOLEAN Locked);
#endif /* __ASM__ */
/*
- *
+ *
*/
#define MM_STACK_SIZE (3*4096)
* PURPOSE: Name of the type
*/
UNICODE_STRING TypeName;
-
+
/*
* PURPOSE: Total number of objects of this type
*/
ULONG TotalObjects;
-
+
/*
* PURPOSE: Total number of handles of this type
*/
ULONG TotalHandles;
-
+
/*
* PURPOSE: Peak objects of this type
*/
ULONG PeakObjects;
-
+
/*
* PURPOSE: Peak handles of this type
*/
ULONG PeakHandles;
-
+
/*
* PURPOSE: Paged pool charge
*/
ULONG PagedPoolCharge;
-
+
/*
* PURPOSE: Nonpaged pool charge
*/
ULONG NonpagedPoolCharge;
-
+
/*
* PURPOSE: Mapping of generic access rights
*/
PGENERIC_MAPPING Mapping;
-
+
/*
* PURPOSE: Dumps the object
* NOTE: To be defined
*/
VOID STDCALL_FUNC (*Dump)(VOID);
-
+
/*
* PURPOSE: Opens the object
* NOTE: To be defined
*/
VOID STDCALL_FUNC (*Open)(VOID);
-
+
/*
* PURPOSE: Called to close an object if OkayToClose returns true
*/
VOID STDCALL_FUNC (*Close)(PVOID ObjectBody,
ULONG HandleCount);
-
+
/*
* PURPOSE: Called to delete an object when the last reference is removed
*/
VOID STDCALL_FUNC (*Delete)(PVOID ObjectBody);
-
+
/*
* PURPOSE: Called when an open attempts to open a file apparently
* residing within the object
struct _DIRECTORY_OBJECT* Parent;
POBJECT_TYPE ObjectType;
PSECURITY_DESCRIPTOR SecurityDescriptor;
-
+
/*
* PURPOSE: Object type
* NOTE: This overlaps the first member of the object body
*/
CSHORT Type;
-
+
/*
* PURPOSE: Object size
* NOTE: This overlaps the second member of the object body
*/
CSHORT Size;
-
-
+
+
} OBJECT_HEADER, *POBJECT_HEADER;
{
CSHORT Type;
CSHORT Size;
-
+
/*
* PURPOSE: Head of the list of our subdirectories
*/
{
CSHORT Type;
CSHORT Size;
-
+
/* pointer to object type data */
POBJECT_TYPE ObjectType;
} TYPE_OBJECT, *PTYPE_OBJECT;
VOID
FASTCALL
-ObInitializeFastReference(IN PEX_FAST_REF FastRef,
+ObInitializeFastReference(IN PEX_FAST_REF FastRef,
PVOID Object);
PVOID
FASTCALL
ObFastReplaceObject(IN PEX_FAST_REF FastRef,
PVOID Object);
-
+
PVOID
FASTCALL
ObFastReferenceObject(IN PEX_FAST_REF FastRef);
FASTCALL
ObFastDereferenceObject(IN PEX_FAST_REF FastRef,
PVOID Object);
-
+
/* Secure object information functions */
typedef struct _CAPTURED_OBJECT_ATTRIBUTES
#ifndef __INTERNAL_POOL_H
#define __INTERNAL_POOL_H
-PVOID STDCALL ExAllocateNonPagedPoolWithTag (POOL_TYPE type,
- ULONG size,
+PVOID STDCALL ExAllocateNonPagedPoolWithTag (POOL_TYPE type,
+ ULONG size,
ULONG Tag,
PVOID Caller);
{
KSPIN_LOCK Lock;
KSEMAPHORE Semaphore;
-
+
USHORT Type;
USHORT State;
-
+
struct _EPORT * RequestPort;
struct _EPORT * OtherPort;
-
+
ULONG QueueLength;
LIST_ENTRY QueueListHead;
-
+
ULONG ConnectQueueLength;
LIST_ENTRY ConnectQueueListHead;
-
+
ULONG MaxDataLength;
ULONG MaxConnectInfoLength;
ULONG MaxPoolUsage; /* size of NP zone */
/* Code in ntoskrnl/lpc/reply.c */
NTSTATUS STDCALL
-EiReplyOrRequestPort (IN PEPORT Port,
- IN PLPC_MESSAGE LpcReply,
+EiReplyOrRequestPort (IN PEPORT Port,
+ IN PLPC_MESSAGE LpcReply,
IN ULONG MessageType,
IN PEPORT Sender);
{
ULONG OldValue, NewValue;
- __asm__ __volatile__ ("lwarx %0,0,%1"
+ __asm__ __volatile__ ("lwarx %0,0,%1"
: "=r" (OldValue), "=r" (*Addr)
- :
+ :
: "memory");
NewValue = OldValue & ~(1<<BitPos);
{
ULONG OldValue, NewValue;
- __asm__ __volatile__ ("lwarx %0,0,%1"
+ __asm__ __volatile__ ("lwarx %0,0,%1"
: "=r" (OldValue), "=r" (*Addr)
- :
+ :
: "memory");
NewValue = OldValue | (1<<BitPos);
ULONG ApcNeeded:1;
};
ULONG SameThreadPassiveFlags; /* 248 */
- };
+ };
UCHAR ForwardClusterOnly; /* 24C */
UCHAR DisablePageFaultClustering; /* 24D */
UCHAR ActiveFaultCount; /* 24E */
typedef struct _ETHREAD *PETHREAD;
#endif /* __USE_W32API */
-
+
#include <pshpack4.h>
/*
* NAME: EPROCESS
KPROCESS Pcb; /* 000 */
EX_PUSH_LOCK ProcessLock; /* 078 */
LARGE_INTEGER CreateTime; /* 080 */
- LARGE_INTEGER ExitTime; /* 088 */
+ LARGE_INTEGER ExitTime; /* 088 */
EX_RUNDOWN_REF RundownProtect; /* 090 */
- HANDLE UniqueProcessId; /* 094 */
- LIST_ENTRY ActiveProcessLinks; /* 098 */
+ HANDLE UniqueProcessId; /* 094 */
+ LIST_ENTRY ActiveProcessLinks; /* 098 */
ULONG QuotaUsage[3]; /* 0A0 */
ULONG QuotaPeak[3]; /* 0AC */
- ULONG CommitCharge; /* 0B8 */
- ULONG PeakVirtualSize; /* 0BC */
- ULONG VirtualSize; /* 0C0 */
+ ULONG CommitCharge; /* 0B8 */
+ ULONG PeakVirtualSize; /* 0BC */
+ ULONG VirtualSize; /* 0C0 */
LIST_ENTRY SessionProcessLinks; /* 0C4 */
PVOID DebugPort; /* 0CC */
PVOID ExceptionPort; /* 0D0 */
};
ULONG Flags; /* 240 */
};
-
+
NTSTATUS ExitStatus; /* 244 */
USHORT NextPageColor; /* 248 */
union {
ULONG Cookie; /* 270 */
/***************************************************************
- * REACTOS SPECIFIC START
- ***************************************************************/
+ * REACTOS SPECIFIC START
+ ***************************************************************/
/* FIXME WILL BE DEPRECATED WITH PUSHLOCK SUPPORT IN 0.3.0 */
KEVENT LockEvent; /* 274 */
ULONG LockCount; /* 284 */
struct _KTHREAD *LockOwner; /* 288 */
-
+
/* FIXME MOVE TO AVL TREES */
MADDRESS_SPACE AddressSpace; /* 28C */
};
VOID PsReapThreads(VOID);
VOID PsInitializeThreadReaper(VOID);
VOID PsQueueThreadReap(PETHREAD Thread);
-NTSTATUS
+NTSTATUS
PsInitializeThread(PEPROCESS Process,
PETHREAD* ThreadPtr,
POBJECT_ATTRIBUTES ObjectAttributes,
STDCALL
PspAssignPrimaryToken(PEPROCESS Process,
HANDLE TokenHandle);
-VOID STDCALL PsExitSpecialApc(PKAPC Apc,
+VOID STDCALL PsExitSpecialApc(PKAPC Apc,
PKNORMAL_ROUTINE *NormalRoutine,
PVOID *NormalContext,
PVOID *SystemArgument1,
PVOID *SystemArgument2);
-
+
NTSTATUS
STDCALL
PspInitializeProcessSecurity(PEPROCESS Process,
STDCALL
PspSystemThreadStartup(PKSTART_ROUTINE StartRoutine,
PVOID StartContext);
-
+
NTSTATUS
PsInitializeIdleOrFirstThread (
PEPROCESS Process,
BOOLEAN First);
/*
* Internal thread priorities, added by Phillip Susi
- * TODO: rebalence these to make use of all priorities... the ones above 16
+ * TODO: rebalence these to make use of all priorities... the ones above 16
* can not all be used right now
*/
#define PROCESS_PRIO_IDLE 3
VOID STDCALL PiDeleteProcess(PVOID ObjectBody);
-VOID
-STDCALL
+VOID
+STDCALL
PspReapRoutine(PVOID Context);
VOID
PVOID SystemArgument2);
VOID
PsInitialiseSuspendImplementation(VOID);
-NTSTATUS
+NTSTATUS
STDCALL
PspExitProcess(PEPROCESS Process);
-VOID
-STDCALL
+VOID
+STDCALL
PspDeleteProcess(PVOID ObjectBody);
-VOID
+VOID
STDCALL
PspDeleteThread(PVOID ObjectBody);
VOID SeDeassignPrimaryToken(struct _EPROCESS *Process);
-NTSTATUS STDCALL
-SepCreateImpersonationTokenDacl(PTOKEN Token,
+NTSTATUS STDCALL
+SepCreateImpersonationTokenDacl(PTOKEN Token,
PTOKEN PrimaryToken,
PACL *Dacl);
SECURITY_IMPERSONATION_LEVEL Level,
KPROCESSOR_MODE PreviousMode,
PTOKEN* NewAccessToken);
-
+
NTSTATUS
SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
typedef struct _KV86M_TRAP_FRAME
{
KTRAP_FRAME Tf;
-
+
ULONG SavedExceptionStack;
/*
* These are put on the top of the stack by the routine that entered
* v86 mode so the exception handlers can find the control information
*/
- struct _KV86M_REGISTERS* regs;
+ struct _KV86M_REGISTERS* regs;
ULONG orig_ebp;
} KV86M_TRAP_FRAME, *PKV86M_TRAP_FRAME;
ULONG Gs;
/*
- * Control registers
+ * Control registers
*/
ULONG Eip;
ULONG Cs;
*/
ULONG RecoveryAddress;
UCHAR RecoveryInstruction[4];
- ULONG Vif;
+ ULONG Vif;
ULONG Flags;
PNTSTATUS PStatus;
} KV86M_REGISTERS, *PKV86M_REGISTERS;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/adapter.c
* PURPOSE: DMA handling
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/arcname.c
* PURPOSE: Creates ARC names for boot devices
- *
+ *
* PROGRAMMERS: Eric Kohl (ekohl@rz-online.de)
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/bootlog.c
* PURPOSE: Boot log file support
- *
+ *
* PROGRAMMERS: Eric Kohl
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/contrller.c
* PURPOSE: Implements the controller object
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* Initialize the Wait Context Block */
DeviceObject->Queue.Wcb.DeviceContext = Context;
DeviceObject->Queue.Wcb.DeviceRoutine = ExecutionRoutine;
-
+
/* Insert the Device Queue */
if (!KeInsertDeviceQueue(&ControllerObject->DeviceWaitQueue,
&DeviceObject->Queue.Wcb.WaitQueueEntry));
Result = ExecutionRoutine(DeviceObject,
DeviceObject->CurrentIrp,
NULL,
- Context);
+ Context);
}
-
+
if (Result == DeallocateObject)
{
IoFreeController(ControllerObject);
/* Initialize an empty OBA */
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
-
+
/* Create the Object */
Status = ObCreateObject(KernelMode,
IoControllerObjectType,
0,
(PVOID*)&Controller);
if (!NT_SUCCESS(Status)) return NULL;
-
+
/* Insert it */
Status = ObInsertObject(Controller,
NULL,
NULL,
&Handle);
if (!NT_SUCCESS(Status)) return NULL;
-
+
/* Close the dummy handle */
NtClose(Handle);
-
+
/* Zero the Object and set its data */
RtlZeroMemory(Controller, sizeof(CONTROLLER_OBJECT) + Size);
Controller->Type = IO_TYPE_CONTROLLER;
Controller->Size = sizeof(CONTROLLER_OBJECT) + Size;
Controller->ControllerExtension = (Controller + 1);
-
+
/* Initialize its Queue */
KeInitializeDeviceQueue(&Controller->DeviceWaitQueue);
/*
* @implemented
*
- * FUNCTION: Releases a previously allocated controller object when a
+ * FUNCTION: Releases a previously allocated controller object when a
* device has finished an I/O request
* ARGUMENTS:
* ControllerObject = Controller object to be released
if ((QueueEntry = KeRemoveDeviceQueue(&ControllerObject->DeviceWaitQueue)))
{
/* Get the Device Object */
- DeviceObject = CONTAINING_RECORD(QueueEntry,
- DEVICE_OBJECT,
+ DeviceObject = CONTAINING_RECORD(QueueEntry,
+ DEVICE_OBJECT,
Queue.Wcb.WaitQueueEntry);
/* Call the routine */
Result = DeviceObject->Queue.Wcb.DeviceRoutine(DeviceObject,
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/io/device.c
* PURPOSE: Device Object Management, including Notifications and Queues.
- *
+ *
* PROGRAMMERS: Alex Ionescu
* David Welch (welch@cwcom.net)
*/
/* PRIVATE FUNCTIONS **********************************************************/
-VOID
+VOID
IoShutdownRegisteredDevices(VOID)
{
PSHUTDOWN_ENTRY ShutdownEntry;
}
}
-NTSTATUS
+NTSTATUS
FASTCALL
IopInitializeDevice(PDEVICE_NODE DeviceNode,
PDRIVER_OBJECT DriverObject)
HANDLE FileHandle;
NTSTATUS Status;
- DPRINT("IoGetDeviceObjectPointer(ObjectName %wZ, DesiredAccess %x,"
+ DPRINT("IoGetDeviceObjectPointer(ObjectName %wZ, DesiredAccess %x,"
"FileObject %p DeviceObject %p)\n",
ObjectName, DesiredAccess, FileObject, DeviceObject);
*DeviceObject = IoGetRelatedDeviceObject(LocalFileObject);
*FileObject = LocalFileObject;
}
-
+
/* Close the handle */
ZwClose(FileHandle);
return Status;
* Status
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
IoAttachDevice(PDEVICE_OBJECT SourceDevice,
PUNICODE_STRING TargetDeviceName,
NTSTATUS Status;
PFILE_OBJECT FileObject;
PDEVICE_OBJECT TargetDevice;
-
+
/* Call the helper routine for an attach operation */
DPRINT("IoAttachDevice\n");
- Status = IopGetDeviceObjectPointer(TargetDeviceName,
- FILE_READ_ATTRIBUTES,
+ Status = IopGetDeviceObjectPointer(TargetDeviceName,
+ FILE_READ_ATTRIBUTES,
&FileObject,
&TargetDevice,
IO_ATTACH_DEVICE_API);
-
+
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get Device Object\n");
return Status;
}
-
+
/* Attach the device */
IoAttachDeviceToDeviceStackSafe(SourceDevice, TargetDevice, AttachedDevice);
* Status
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
IoAttachDeviceByPointer(IN PDEVICE_OBJECT SourceDevice,
IN PDEVICE_OBJECT TargetDevice)
* Status
* @implemented
*/
-PDEVICE_OBJECT
+PDEVICE_OBJECT
STDCALL
IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice,
PDEVICE_OBJECT TargetDevice)
{
NTSTATUS Status;
PDEVICE_OBJECT LocalAttach;
-
+
/* Attach it safely */
DPRINT("IoAttachDeviceToDeviceStack\n");
Status = IoAttachDeviceToDeviceStackSafe(SourceDevice,
TargetDevice,
&LocalAttach);
-
+
/* Return it */
DPRINT("IoAttachDeviceToDeviceStack DONE: %x\n", LocalAttach);
return LocalAttach;
{
PDEVICE_OBJECT AttachedDevice;
PDEVOBJ_EXTENSION SourceDeviceExtension;
-
+
DPRINT("IoAttachDeviceToDeviceStack(SourceDevice %x, TargetDevice %x)\n",
SourceDevice, TargetDevice);
/* Get the Attached Device and source extension */
AttachedDevice = IoGetAttachedDevice(TargetDevice);
SourceDeviceExtension = SourceDevice->DeviceObjectExtension;
-
+
/* Make sure that it's in a correct state */
- if (!(AttachedDevice->DeviceObjectExtension->ExtensionFlags &
- (DOE_UNLOAD_PENDING | DOE_DELETE_PENDING |
+ if (!(AttachedDevice->DeviceObjectExtension->ExtensionFlags &
+ (DOE_UNLOAD_PENDING | DOE_DELETE_PENDING |
DOE_REMOVE_PENDING | DOE_REMOVE_PROCESSED)))
{
/* Update fields */
SourceDevice->AlignmentRequirement = AttachedDevice->AlignmentRequirement;
SourceDevice->SectorSize = AttachedDevice->SectorSize;
SourceDevice->Vpb = AttachedDevice->Vpb;
-
+
/* Set the attachment in the device extension */
SourceDeviceExtension->AttachedTo = AttachedDevice;
}
- else
+ else
{
/* Device was unloading or being removed */
AttachedDevice = NULL;
}
-
+
/* Return the attached device */
*AttachedToDeviceObject = AttachedDevice;
return STATUS_SUCCESS;
* Status
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
IoCreateDevice(PDRIVER_OBJECT DriverObject,
ULONG DeviceExtensionSize,
ULONG AlignedDeviceExtensionSize;
ULONG TotalSize;
HANDLE TempHandle;
-
+
ASSERT_IRQL(PASSIVE_LEVEL);
DPRINT("IoCreateDevice(DriverObject %x)\n",DriverObject);
-
+
/* Generate a name if we have to */
if (DeviceCharacteristics & FILE_AUTOGENERATED_DEVICE_NAME)
{
swprintf(AutoNameBuffer,
L"\\Device\\%08lx",
- InterlockedIncrementUL(&IopDeviceObjectNumber));
+ InterlockedIncrementUL(&IopDeviceObjectNumber));
RtlInitUnicodeString(&AutoName, AutoNameBuffer);
DeviceName = &AutoName;
}
-
+
/* Initialize the Object Attributes */
InitializeObjectAttributes(&ObjectAttributes, DeviceName, 0, NULL, NULL);
-
+
/* Honor exclusive flag */
ObjectAttributes.Attributes |= OBJ_EXCLUSIVE;
-
+
/* Create a permanent object for named devices */
if (DeviceName != NULL)
{
ObjectAttributes.Attributes |= OBJ_PERMANENT;
}
-
+
/* Align the Extension Size to 8-bytes */
AlignedDeviceExtensionSize = (DeviceExtensionSize + 7) &~ 7;
DPRINT("AlignedDeviceExtensionSize %x\n", AlignedDeviceExtensionSize);
-
+
/* Total Size */
- TotalSize = AlignedDeviceExtensionSize +
+ TotalSize = AlignedDeviceExtensionSize +
sizeof(DEVICE_OBJECT) + sizeof(DEVOBJ_EXTENSION);
DPRINT("TotalSize %x\n", TotalSize);
0,
0,
(PVOID*)&CreatedDeviceObject);
-
+
if (!NT_SUCCESS(Status))
{
DPRINT1("IoCreateDevice() ObCreateObject failed, status: 0x%08X\n", Status);
return Status;
}
-
+
/* Clear the whole Object and extension so we don't null stuff manually */
RtlZeroMemory(CreatedDeviceObject, TotalSize);
DPRINT("CreatedDeviceObject %x\n", CreatedDeviceObject);
-
- /*
+
+ /*
* Setup the Type and Size. Note that we don't use the aligned size,
* because that's only padding for the DevObjExt and not part of the Object.
*/
CreatedDeviceObject->Type = IO_TYPE_DEVICE;
CreatedDeviceObject->Size = sizeof(DEVICE_OBJECT) + DeviceExtensionSize;
-
+
/* The kernel extension is after the driver internal extension */
DeviceObjectExtension = (PDEVOBJ_EXTENSION)
- ((ULONG_PTR)(CreatedDeviceObject + 1) +
+ ((ULONG_PTR)(CreatedDeviceObject + 1) +
AlignedDeviceExtensionSize);
-
+
/* Set the Type and Size. Question: why is Size 0 on Windows? */
DPRINT("DeviceObjectExtension %x\n", DeviceObjectExtension);
DeviceObjectExtension->Type = IO_TYPE_DEVICE_OBJECT_EXTENSION;
DeviceObjectExtension->Size = 0;
-
+
/* Link the Object and Extension */
DeviceObjectExtension->DeviceObject = CreatedDeviceObject;
CreatedDeviceObject->DeviceObjectExtension = DeviceObjectExtension;
-
- /* Set Device Object Data */
+
+ /* Set Device Object Data */
CreatedDeviceObject->DeviceType = DeviceType;
CreatedDeviceObject->Characteristics = DeviceCharacteristics;
CreatedDeviceObject->DeviceExtension = CreatedDeviceObject + 1;
CreatedDeviceObject->StackSize = 1;
CreatedDeviceObject->AlignmentRequirement = 1; /* FIXME */
-
+
/* Set the Flags */
/* FIXME: After the Driver is Loaded, the flag below should be removed */
CreatedDeviceObject->Flags = DO_DEVICE_INITIALIZING;
if (Exclusive) CreatedDeviceObject->Flags |= DO_EXCLUSIVE;
if (DeviceName) CreatedDeviceObject->Flags |= DO_DEVICE_HAS_NAME;
-
+
/* Attach a Vpb for Disks and Tapes, and create the Device Lock */
if (CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK ||
CreatedDeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK ||
{
/* Create Vpb */
IopAttachVpb(CreatedDeviceObject);
-
+
/* Initialize Lock Event */
KeInitializeEvent(&CreatedDeviceObject->DeviceLock,
SynchronizationEvent,
TRUE);
}
-
+
/* Set the right Sector Size */
switch (DeviceType)
{
CreatedDeviceObject->SectorSize = 2048;
break;
}
-
+
/* Create the Device Queue */
KeInitializeDeviceQueue(&CreatedDeviceObject->DeviceQueue);
0,
NULL,
&TempHandle);
-
+
if (!NT_SUCCESS(Status))
{
DPRINT1("Cannot insert Device Object into Handle Table\n");
*DeviceObject = NULL;
return Status;
}
-
+
/* Now do the final linking */
ObReferenceObject(DriverObject);
CreatedDeviceObject->DriverObject = DriverObject;
CreatedDeviceObject->NextDevice = DriverObject->DeviceObject;
DriverObject->DeviceObject = CreatedDeviceObject;
-
+
NtClose(TempHandle);
-
+
/* Return to caller */
*DeviceObject = CreatedDeviceObject;
return STATUS_SUCCESS;
* Status
* @implemented
*/
-VOID
+VOID
STDCALL
IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
{
Previous = Previous->NextDevice;
Previous->NextDevice = DeviceObject->NextDevice;
}
-
+
/* I guess this should be removed later... but it shouldn't cause problems */
DeviceObject->DeviceObjectExtension->ExtensionFlags |= DOE_DELETE_PENDING;
-
+
/* Make the object temporary. This should automatically remove the device
from the namespace */
ObMakeTemporaryObject(DeviceObject);
-
+
/* Dereference the driver object */
ObDereferenceObject(DeviceObject->DriverObject);
-
+
/* Remove the keep-alive reference */
ObDereferenceObject(DeviceObject);
}
VOID
STDCALL
IoDetachDevice(PDEVICE_OBJECT TargetDevice)
-{
- DPRINT("IoDetachDevice(TargetDevice %x)\n", TargetDevice);
-
+{
+ DPRINT("IoDetachDevice(TargetDevice %x)\n", TargetDevice);
+
/* Remove the attachment */
TargetDevice->AttachedDevice->DeviceObjectExtension->AttachedTo = NULL;
TargetDevice->AttachedDevice = NULL;
{
ULONG ActualDevices = 1;
PDEVICE_OBJECT CurrentDevice = DriverObject->DeviceObject;
-
+
DPRINT1("IoEnumerateDeviceObjectList\n");
-
+
/* Find out how many devices we'll enumerate */
while ((CurrentDevice = CurrentDevice->NextDevice))
{
ActualDevices++;
}
-
+
/* Go back to the first */
CurrentDevice = DriverObject->DeviceObject;
-
+
/* Start by at least returning this */
*ActualNumberDeviceObjects = ActualDevices;
-
+
/* Check if we can support so many */
if ((ActualDevices * 4) > DeviceObjectListSize)
{
/* Fail because the buffer was too small */
return STATUS_BUFFER_TOO_SMALL;
}
-
+
/* Check if the caller only wanted the size */
- if (DeviceObjectList)
+ if (DeviceObjectList)
{
/* Loop through all the devices */
while (ActualDevices)
{
/* Reference each Device */
ObReferenceObject(CurrentDevice);
-
+
/* Add it to the list */
*DeviceObjectList = CurrentDevice;
-
+
/* Go to the next one */
CurrentDevice = CurrentDevice->NextDevice;
ActualDevices--;
DeviceObjectList++;
}
}
-
+
/* Return the status */
return STATUS_SUCCESS;
}
* Status
* @implemented
*/
-PDEVICE_OBJECT
+PDEVICE_OBJECT
STDCALL
IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject)
{
PDEVICE_OBJECT Current = DeviceObject;
-
+
/* Get the last attached device */
- while (Current->AttachedDevice)
+ while (Current->AttachedDevice)
{
Current = Current->AttachedDevice;
}
-
+
/* Return it */
return Current;
}
* Status
* @implemented
*/
-PDEVICE_OBJECT
+PDEVICE_OBJECT
STDCALL
IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject)
{
PDEVICE_OBJECT Current = IoGetAttachedDevice(DeviceObject);
-
+
/* Reference the ATtached Device */
ObReferenceObject(Current);
return Current;
* Status
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
IoGetDeviceObjectPointer(IN PUNICODE_STRING ObjectName,
IN ACCESS_MASK DesiredAccess,
OUT PDEVICE_OBJECT *DeviceObject)
{
/* Call the helper routine for a normal operation */
- return IopGetDeviceObjectPointer(ObjectName,
- DesiredAccess,
- FileObject,
- DeviceObject,
+ return IopGetDeviceObjectPointer(ObjectName,
+ DesiredAccess,
+ FileObject,
+ DeviceObject,
0);
}
PDEVOBJ_EXTENSION DeviceExtension;
PVPB Vpb;
KIRQL OldIrql;
-
+
/* Make sure there's a VPB */
if (!FileSystemDeviceObject->Vpb) return STATUS_INVALID_PARAMETER;
-
+
/* Acquire it */
IoAcquireVpbSpinLock(&OldIrql);
-
+
/* Get the Device Extension */
DeviceExtension = FileSystemDeviceObject->DeviceObjectExtension;
-
+
/* Make sure this one has a VPB too */
Vpb = DeviceExtension->Vpb;
if (!Vpb) return STATUS_INVALID_PARAMETER;
-
+
/* Make sure someone it's mounted */
if ((!Vpb->ReferenceCount) || (Vpb->Flags & VPB_MOUNTED)) return STATUS_VOLUME_DISMOUNTED;
-
+
/* Return the Disk Device Object */
*DiskDeviceObject = Vpb->RealDevice;
-
+
/* Release the lock */
IoReleaseVpbSpinLock(OldIrql);
return STATUS_SUCCESS;
{
PDEVOBJ_EXTENSION DeviceExtension = DeviceObject->DeviceObjectExtension;
PDEVICE_OBJECT LowerDeviceObject = NULL;
-
+
/* Make sure it's not getting deleted */
- if (DeviceExtension->ExtensionFlags & (DOE_UNLOAD_PENDING |
+ if (DeviceExtension->ExtensionFlags & (DOE_UNLOAD_PENDING |
DOE_DELETE_PENDING |
- DOE_REMOVE_PENDING |
+ DOE_REMOVE_PENDING |
DOE_REMOVE_PROCESSED))
{
- /* Get the Lower Device Object */
- LowerDeviceObject = DeviceExtension->AttachedTo;
-
+ /* Get the Lower Device Object */
+ LowerDeviceObject = DeviceExtension->AttachedTo;
+
/* Reference it */
ObReferenceObject(LowerDeviceObject);
}
* Status
* @implemented
*/
-PDEVICE_OBJECT
+PDEVICE_OBJECT
STDCALL
IoGetRelatedDeviceObject(IN PFILE_OBJECT FileObject)
{
PDEVICE_OBJECT DeviceObject = FileObject->DeviceObject;
-
+
/* Get logical volume mounted on a physical/virtual/logical device */
if (FileObject->Vpb && FileObject->Vpb->DeviceObject)
{
* Check if file object has an associated device object mounted by some
* other file system.
*/
- if (FileObject->DeviceObject->Vpb &&
+ if (FileObject->DeviceObject->Vpb &&
FileObject->DeviceObject->Vpb->DeviceObject)
{
DeviceObject = FileObject->DeviceObject->Vpb->DeviceObject;
* @implemented
*/
NTSTATUS
-STDCALL
+STDCALL
IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
{
PSHUTDOWN_ENTRY Entry;
{
PKDEVICE_QUEUE_ENTRY entry;
PIRP Irp;
-
+
entry = KeRemoveByKeyDeviceQueue(&DeviceObject->DeviceQueue,
Key);
-
+
if (entry != NULL)
{
Irp = CONTAINING_RECORD(entry,
{
DPRINT("No next irp\n");
DeviceObject->CurrentIrp = NULL;
- }
+ }
}
/*
*/
VOID
STDCALL
-IoStartNextPacket(PDEVICE_OBJECT DeviceObject,
+IoStartNextPacket(PDEVICE_OBJECT DeviceObject,
BOOLEAN Cancelable)
{
PKDEVICE_QUEUE_ENTRY entry;
PIRP Irp;
-
+
DPRINT("IoStartNextPacket(DeviceObject %x, Cancelable %d)\n",
DeviceObject,Cancelable);
-
+
entry = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
-
+
if (entry!=NULL)
{
Irp = CONTAINING_RECORD(entry,IRP,Tail.Overlay.DeviceQueueEntry);
DeviceObject->CurrentIrp = Irp;
- DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
+ DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
}
else
{
VOID
STDCALL
IoStartPacket(PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PULONG Key,
+ PIRP Irp,
+ PULONG Key,
PDRIVER_CANCEL CancelFunction)
{
BOOLEAN stat;
KIRQL oldirql;
-
+
DPRINT("IoStartPacket(Irp %x)\n", Irp);
-
+
ASSERT_IRQL(DISPATCH_LEVEL);
-
+
IoAcquireCancelSpinLock(&oldirql);
-
+
if (CancelFunction != NULL)
{
Irp->CancelRoutine = CancelFunction;
}
-
+
if (Key!=0)
{
stat = KeInsertByKeyDeviceQueue(&DeviceObject->DeviceQueue,
stat = KeInsertDeviceQueue(&DeviceObject->DeviceQueue,
&Irp->Tail.Overlay.DeviceQueueEntry);
}
-
-
+
+
if (!stat)
- {
+ {
IoReleaseCancelSpinLock(DISPATCH_LEVEL);
DeviceObject->CurrentIrp = Irp;
DeviceObject->DriverObject->DriverStartIo(DeviceObject,Irp);
/*
* @implemented
*/
-VOID
-STDCALL
+VOID
+STDCALL
IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
{
PSHUTDOWN_ENTRY ShutdownEntry;
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/deviface.c
* PURPOSE: Device interface functions
- *
+ *
* PROGRAMMERS: Filip Navara (xnavara@volny.cz)
* Matthew Brace (ismarc@austin.rr.com)
* Hervé Poussineau (hpoussin@reactos.com)
* Returns a list of device interfaces of a particular device interface class.
*
* Parameters
- * InterfaceClassGuid
+ * InterfaceClassGuid
* Points to a class GUID specifying the device interface class.
*
- * PhysicalDeviceObject
+ * PhysicalDeviceObject
* Points to an optional PDO that narrows the search to only the
- * device interfaces of the device represented by the PDO.
+ * device interfaces of the device represented by the PDO.
*
- * Flags
+ * Flags
* Specifies flags that modify the search for device interfaces. The
* DEVICE_INTERFACE_INCLUDE_NONACTIVE flag specifies that the list of
* returned symbolic links should contain also disabled device
- * interfaces in addition to the enabled ones.
+ * interfaces in addition to the enabled ones.
*
- * SymbolicLinkList
+ * SymbolicLinkList
* Points to a character pointer that is filled in on successful return
* with a list of unicode strings identifying the device interfaces
* that match the search criteria. The newly allocated buffer contains
* a list of symbolic link names. Each unicode string in the list is
* null-terminated; the end of the whole list is marked by an additional
* NULL. The caller is responsible for freeing the buffer (ExFreePool)
- * when it is no longer needed.
+ * when it is no longer needed.
* If no device interfaces match the search criteria, this routine
* returns STATUS_SUCCESS and the string contains a single NULL
- * character.
+ * character.
*
* Status
* @implemented
ULONG i = 0;
ULONG j = 0;
OBJECT_ATTRIBUTES ObjectAttributes;
-
+
Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
if (!NT_SUCCESS(Status))
{
}
DPRINT("IoGetDeviceInterfaces() called with PDO, not implemented.\n");
- return STATUS_NOT_IMPLEMENTED;
+ return STATUS_NOT_IMPLEMENTED;
}
else
- {
+ {
InitializeObjectAttributes(
&ObjectAttributes,
&BaseKeyName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
-
+
Status = ZwOpenKey(
&InterfaceKey,
KEY_READ,
fip,
Size,
&Size);
-
+
if (!NT_SUCCESS(Status))
{
DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
bip = (PKEY_BASIC_INFORMATION)ExAllocatePool(NonPagedPool, Size);
ASSERT(bip != NULL);
-
+
Status = ZwEnumerateKey(
InterfaceKey,
i,
bip,
Size,
&Size);
-
+
if (!NT_SUCCESS(Status))
{
DPRINT("ZwEnumerateKey() Failed.(0x%X)\n", Status);
ZwClose(InterfaceKey);
return Status;
}
-
+
SubKeyName.Length = 0;
SubKeyName.MaximumLength = BaseKeyName.Length + bip->NameLength + sizeof(WCHAR);
SubKeyName.Buffer = ExAllocatePool(NonPagedPool, SubKeyName.MaximumLength);
bfip,
Size,
&Size);
-
+
if (!NT_SUCCESS(Status))
{
DPRINT("ZwQueryKey() Failed. (0x%X)\n", Status);
ZwClose(InterfaceKey);
return Status;
}
-
+
for(j = 0; j < bfip->SubKeys; j++)
{
Status = ZwEnumerateKey(
ZwClose(InterfaceKey);
return Status;
}
-
+
if (!wcsncmp(bip->Name, L"Control", bip->NameLength))
{
continue;
}
-
+
SymbolicLinkKeyName.Length = 0;
SymbolicLinkKeyName.MaximumLength = SubKeyName.Length + bip->NameLength + sizeof(WCHAR);
SymbolicLinkKeyName.Buffer = ExAllocatePool(NonPagedPool, SymbolicLinkKeyName.MaximumLength);
ASSERT(ControlKeyName.Buffer != NULL);
RtlCopyUnicodeString(&ControlKeyName, &SymbolicLinkKeyName);
RtlAppendUnicodeStringToString(&ControlKeyName, &Control);
-
+
ExFreePool(bip);
InitializeObjectAttributes(
}
Status = ZwQueryValueKey(
- SymbolicLinkKey,
- &SymbolicLink,
+ SymbolicLinkKey,
+ &SymbolicLink,
KeyValuePartialInformation,
NULL,
0,
&Size);
-
+
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
continue;
-
+
if (Status != STATUS_BUFFER_TOO_SMALL)
{
DPRINT("ZwQueryValueKey() Failed.(0x%X)\n", Status);
Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, ControlKeyName.Buffer);
if (NT_SUCCESS(Status))
- {
+ {
/* Put the name in the string here */
if (SymLinkList == NULL)
{
RtlCopyMemory(SymLinkListPtr, vpip->Data, vpip->DataLength);
SymLinkListPtr[vpip->DataLength / sizeof(WCHAR)] = 0;
SymLinkListPtr[1] = '?';
- }
+ }
}
RtlFreeUnicodeString(&SymbolicLinkKeyName);
}
*SymbolicLinkList = SymLinkList;
-
+
RtlFreeUnicodeString(&BaseKeyName);
ZwClose(InterfaceKey);
ExFreePool(bfip);
OBJECT_ATTRIBUTES ObjectAttributes;
ULONG i;
NTSTATUS Status;
-
+
if (!(PhysicalDeviceObject->Flags & DO_BUS_ENUMERATED_DEVICE))
{
DPRINT("PhysicalDeviceObject 0x%p is not a valid Pdo\n", PhysicalDeviceObject);
return STATUS_INVALID_PARAMETER_1;
}
-
+
Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
if (!NT_SUCCESS(Status))
{
DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
return Status;
}
-
+
/* Create Pdo name: \Device\xxxxxxxx (unnamed device) */
Status = ObQueryNameString(
PhysicalDeviceObject,
return Status;
}
ASSERT(PdoNameInfo->Name.Length);
-
+
/* Create base key name for this interface: HKLM\SYSTEM\CurrentControlSet\DeviceClasses\{GUID}\##?#ACPI#PNP0501#1#{GUID} */
ASSERT(PhysicalDeviceObject->DeviceObjectExtension->DeviceNode);
InstancePath = &PhysicalDeviceObject->DeviceObjectExtension->DeviceNode->InstancePath;
}
RtlAppendUnicodeToString(&BaseKeyName, L"#");
RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);
-
+
/* Create BaseKeyName key in registry */
InitializeObjectAttributes(
&ObjectAttributes,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF,
NULL, /* RootDirectory */
NULL); /* SecurityDescriptor */
-
+
Status = ZwCreateKey(
&InterfaceKey,
KEY_WRITE,
NULL, /* Class */
REG_OPTION_VOLATILE,
NULL); /* Disposition */
-
+
if (!NT_SUCCESS(Status))
{
DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
ExFreePool(BaseKeyName.Buffer);
return Status;
}
-
+
/* Write DeviceInstance entry. Value is InstancePath */
Status = ZwSetValueKey(
InterfaceKey,
ExFreePool(BaseKeyName.Buffer);
return Status;
}
-
+
/* Create subkey. Name is #ReferenceString */
SubKeyName.Length = 0;
SubKeyName.MaximumLength = sizeof(WCHAR);
RtlAppendUnicodeToString(&SubKeyName, L"#");
if (ReferenceString && ReferenceString->Length)
RtlAppendUnicodeStringToString(&SubKeyName, ReferenceString);
-
+
/* Create SubKeyName key in registry */
InitializeObjectAttributes(
&ObjectAttributes,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
InterfaceKey, /* RootDirectory */
NULL); /* SecurityDescriptor */
-
+
Status = ZwCreateKey(
&SubKey,
KEY_WRITE,
NULL, /* Class */
REG_OPTION_VOLATILE,
NULL); /* Disposition */
-
+
if (!NT_SUCCESS(Status))
{
DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
ExFreePool(BaseKeyName.Buffer);
return Status;
}
-
+
/* Create symbolic link name: \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
SymbolicLinkName->Length = 0;
SymbolicLinkName->MaximumLength = SymbolicLinkName->Length
RtlAppendUnicodeStringToString(SymbolicLinkName, ReferenceString);
}
SymbolicLinkName->Buffer[SymbolicLinkName->Length] = '\0';
-
+
/* Create symbolic link */
DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
Status = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
ExFreePool(SymbolicLinkName->Buffer);
return Status;
}
-
+
/* Write symbolic link name in registry */
Status = ZwSetValueKey(
SubKey,
DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
ExFreePool(SymbolicLinkName->Buffer);
}
-
+
ZwClose(InterfaceKey);
ZwClose(SubKey);
ExFreePool(SubKeyName.Buffer);
ExFreePool(BaseKeyName.Buffer);
-
+
return Status;
}
PWCHAR StartPosition;
PWCHAR EndPosition;
NTSTATUS Status;
-
+
if (SymbolicLinkName == NULL)
return STATUS_INVALID_PARAMETER_1;
-
+
DPRINT("IoSetDeviceInterfaceState('%wZ', %d)\n", SymbolicLinkName, Enable);
Status = IoGetDeviceObjectPointer(SymbolicLinkName,
0, /* DesiredAccess */
&PhysicalDeviceObject);
if (!NT_SUCCESS(Status))
return Status;
-
+
/* Symbolic link name is \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
/* Get GUID from SymbolicLinkName */
StartPosition = wcschr(SymbolicLinkName->Buffer, L'{');
return STATUS_INVALID_PARAMETER_1;
GuidString.Buffer = StartPosition;
GuidString.MaximumLength = GuidString.Length = (ULONG_PTR)(EndPosition + 1) - (ULONG_PTR)StartPosition;
-
+
IopNotifyPlugPlayNotification(
PhysicalDeviceObject,
EventCategoryDeviceInterfaceChange,
Enable ? (LPGUID)&GUID_DEVICE_INTERFACE_ARRIVAL : (LPGUID)&GUID_DEVICE_INTERFACE_REMOVAL,
&GuidString,
(PVOID)SymbolicLinkName);
-
+
ObDereferenceObject(FileObject);
-
+
return STATUS_SUCCESS;
}
/* Set ending CHS values */
PartitionSector->Partition[j].EndingCylinder = EndCylinder & 0xff;
PartitionSector->Partition[j].EndingHead = EndHead;
- PartitionSector->Partition[j].EndingSector =
+ PartitionSector->Partition[j].EndingSector =
((EndCylinder & 0x0300) >> 2) + (EndSector & 0x3f);
/* Calculate start sector and sector count */
if (IsContainerPartition (PartitionBuffer->PartitionEntry[i + j].PartitionType))
{
ContainerEntry = TRUE;
- NextPartitionOffset =
+ NextPartitionOffset =
PartitionBuffer->PartitionEntry[i + j].StartingOffset.QuadPart;
#if defined(__GNUC__)
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/driver.c
* PURPOSE: Loading and unloading of drivers
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
* Filip Navara (xnavara@volny.cz)
*/
InitializeListHead(&DriverReinitListHead);
KeInitializeSpinLock(&DriverReinitListLock);
DriverReinitTailEntry = NULL;
-
+
InitializeListHead(&DriverBootReinitListHead);
KeInitializeSpinLock(&DriverBootReinitListLock);
DriverBootReinitTailEntry = NULL;
RtlInitUnicodeString(&DriverName, NameBuffer);
DPRINT("Driver name: '%wZ'\n", &DriverName);
-
+
Buffer = (PWSTR)ExAllocatePool(NonPagedPool, DriverName.Length);
/* If we don't success, it is not a problem. Our driver
* object will not have associated driver name... */
UNICODE_STRING RegistryKey;
PDRIVER_INITIALIZE DriverEntry;
NTSTATUS Status;
-
+
DriverEntry = ModuleObject->EntryPoint;
-
+
if (ServiceName != NULL && ServiceName->Length != 0)
{
RegistryKey.Length = 0;
IopMarkLastReinitializeDriver();
Status = DriverEntry(*DriverObject, &RegistryKey);
-
+
RtlFreeUnicodeString(&RegistryKey);
-
+
if (!NT_SUCCESS(Status))
{
ObMakeTemporaryObject(*DriverObject);
PMODULE_OBJECT ModuleObject;
PDRIVER_OBJECT DriverObject;
NTSTATUS Status;
-
+
for (Filters = ValueData;
((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength &&
*Filters != 0;
{
DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath);
ServiceName.Buffer = Filters;
- ServiceName.MaximumLength =
+ ServiceName.MaximumLength =
ServiceName.Length = wcslen(Filters) * sizeof(WCHAR);
/* Load and initialize the filter driver */
/*
* First load the device filters
*/
-
+
QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback;
if (Lower)
QueryTable[0].Name = L"LowerFilters";
QueryTable[1].Name = NULL;
KeyBuffer = ExAllocatePool(
- PagedPool,
+ PagedPool,
(49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\");
- wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);
+ wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer);
RtlQueryRegistryValues(
RTL_REGISTRY_ABSOLUTE,
ExFreePool(KeyBuffer);
}
-
+
return STATUS_SUCCESS;
}
-static NTSTATUS STDCALL
+static NTSTATUS STDCALL
IopGetGroupOrderList(PWSTR ValueName,
ULONG ValueType,
PVOID ValueData,
Status = IopInitializeDriverModule(DeviceNode, ModuleObject,
&DeviceNode->ServiceName, FALSE, &DriverObject);
-
+
if (!NT_SUCCESS(Status))
{
if (ModuleDeviceNode == NULL)
*
* Parameters
* None
- *
+ *
* Return Value
* None
*/
if (Service->ErrorControl == 1)
{
/* Log error */
- }
+ }
else if (Service->ErrorControl == 2)
{
if (IsLastKnownGood == FALSE)
{
/* Boot last known good configuration */
}
- }
+ }
else if (Service->ErrorControl == 3)
{
if (IsLastKnownGood == FALSE)
{
/* Boot last known good configuration */
- }
+ }
else
{
/* BSOD! */
*
* Parameters
* None
- *
+ *
* Return Value
* None
*/
DPRINT("Group: %wZ\n", &CurrentGroup->GroupName);
- /* Load all drivers with a valid tag */
+ /* Load all drivers with a valid tag */
for (i = 0; i < CurrentGroup->TagCount; i++)
{
ServiceEntry = ServiceListHead.Flink;
* Whether to unload Plug & Plug or only legacy drivers. If this
* parameter is set to FALSE, the routine will unload only legacy
* drivers.
- *
+ *
* Return Value
* Status
*
UNICODE_STRING ServiceKeyName;
HANDLE hDriver;
ULONG i;
-
+
/* First, create a unique name for the driver if we don't have one */
if (!DriverName) {
-
+
/* Create a random name and set up the string*/
NameLength = swprintf(NameBuffer, L"\\Driver\\%08u", KeTickCount);
LocalDriverName.Length = NameLength * sizeof(WCHAR);
LocalDriverName.MaximumLength = LocalDriverName.Length + sizeof(UNICODE_NULL);
LocalDriverName.Buffer = NameBuffer;
-
+
} else {
-
+
/* So we can avoid another code path, use a local var */
LocalDriverName = *DriverName;
}
-
+
/* Initialize the Attributes */
ObjectSize = sizeof(DRIVER_OBJECT) + sizeof(DRIVER_EXTENSION);
InitializeObjectAttributes(&ObjectAttributes,
OBJ_PERMANENT | OBJ_CASE_INSENSITIVE,
NULL,
NULL);
-
+
/* Create the Object */
Status = ObCreateObject(KernelMode,
IoDriverObjectType,
0,
0,
(PVOID*)&DriverObject);
-
+
/* Return on failure */
if (!NT_SUCCESS(Status)) return Status;
-
+
/* Set up the Object */
RtlZeroMemory(DriverObject, ObjectSize);
DriverObject->Type = IO_TYPE_DRIVER;
DriverObject->DriverExtension = (PDRIVER_EXTENSION)(DriverObject + 1);
DriverObject->DriverExtension->DriverObject = DriverObject;
DriverObject->DriverInit = InitializationFunction;
-
+
/* Invalidate all Major Functions */
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = IopInvalidDeviceRequest;
}
-
+
/* Set up the Service Key Name */
ServiceKeyName.Buffer = ExAllocatePool(PagedPool, LocalDriverName.Length + sizeof(WCHAR));
ServiceKeyName.Length = LocalDriverName.Length;
RtlMoveMemory(ServiceKeyName.Buffer, LocalDriverName.Buffer, LocalDriverName.Length);
ServiceKeyName.Buffer[ServiceKeyName.Length / sizeof(WCHAR)] = L'\0';
DriverObject->DriverExtension->ServiceKeyName = ServiceKeyName;
-
+
/* Also store it in the Driver Object. This is a bit of a hack. */
RtlMoveMemory(&DriverObject->DriverName, &ServiceKeyName, sizeof(UNICODE_STRING));
-
+
/* Add the Object and get its handle */
Status = ObInsertObject(DriverObject,
NULL,
0,
NULL,
&hDriver);
-
+
/* Return on Failure */
if (!NT_SUCCESS(Status)) return Status;
-
+
/* Now reference it */
Status = ObReferenceObjectByHandle(hDriver,
0,
(PVOID*)&DriverObject,
NULL);
ZwClose(hDriver);
-
+
/* Finally, call its init function */
Status = (*InitializationFunction)(DriverObject, NULL);
-
+
if (!NT_SUCCESS(Status)) {
/* If it didn't work, then kill the object */
ObMakeTemporaryObject(DriverObject);
ObDereferenceObject(DriverObject);
}
-
+
/* Return the Status */
return Status;
}
* Parameters
* DriverServiceName
* Name of the service to load (registry key).
- *
+ *
* Return Value
* Status
*
PMODULE_OBJECT ModuleObject;
PDRIVER_OBJECT DriverObject;
WCHAR *cur;
-
+
PAGED_CODE();
-
+
PreviousMode = KeGetPreviousMode();
/*
}
IopInitializeDevice(DeviceNode, DriverObject);
-
+
ReleaseCapturedString:
RtlReleaseCapturedUnicodeString(&CapturedDriverServiceName,
PreviousMode,
* Parameters
* DriverServiceName
* Name of the service to unload (registry key).
- *
+ *
* Return Value
* Status
*
ReinitItem->DriverObject = DriverObject;
ReinitItem->ReinitRoutine = ReinitRoutine;
ReinitItem->Context = Context;
-
+
DriverObject->Flags |= DRVO_REINIT_REGISTERED;
ExInterlockedInsertTailList(
ReinitItem->DriverObject = DriverObject;
ReinitItem->ReinitRoutine = DriverReinitializationRoutine;
ReinitItem->Context = Context;
-
+
DriverObject->Flags |= DRVO_BOOTREINIT_REGISTERED;
ExInterlockedInsertTailList(
if (NewDriverExtension == NULL)
{
- return STATUS_INSUFFICIENT_RESOURCES;
+ return STATUS_INSUFFICIENT_RESOURCES;
}
-
+
OldIrql = KeRaiseIrqlToDpcLevel();
NewDriverExtension->Link = DriverObject->DriverSection;
*DriverObjectExtension = &NewDriverExtension->Extension;
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
/*
-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/efi.c
* PURPOSE: EFI Unimplemented Function Calls
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
-
+
NTSTATUS
STDCALL
NtDeleteBootEntry(
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
-
+
NTSTATUS
STDCALL
NtEnumerateBootEntries(
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
-
+
NTSTATUS
STDCALL
NtQueryBootEntryOrder(
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
-
+
NTSTATUS
STDCALL
NtQueryBootOptions(
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
-
+
NTSTATUS
STDCALL
NtSetBootEntryOrder(
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}
-
-NTSTATUS
-STDCALL
+
+NTSTATUS
+STDCALL
NtSetBootOptions(
- ULONG Unknown1,
+ ULONG Unknown1,
ULONG Unknown2
)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-STDCALL
+}
+
+NTSTATUS
+STDCALL
NtTranslateFilePath(
- ULONG Unknown1,
+ ULONG Unknown1,
ULONG Unknown2,
ULONG Unknown3
)
{
/* Free the APC */
ExFreePool(Apc);
-}
+}
VOID
STDCALL
PIRP Irp = (PIRP)NormalContext;
//PVPB Vpb = (PVPB)SystemArgument1;
//PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)SystemArgument2;
-
+
/* FIXME: UNIMPLEMENTED */
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
-}
+}
/*
* @implemented
*/
-VOID
-STDCALL
+VOID
+STDCALL
IoRaiseHardError(PIRP Irp,
PVPB Vpb,
PDEVICE_OBJECT RealDeviceObject)
{
PETHREAD Thread = (PETHREAD)&Irp->Tail.Overlay.Thread;
PKAPC ErrorApc;
-
+
/* Don't do anything if hard errors are disabled on the thread */
if (Thread->HardErrorsAreDisabled)
{
IoCompleteRequest(Irp, IO_DISK_INCREMENT);
return;
}
-
+
/* Setup an APC */
- ErrorApc = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(KAPC),
+ ErrorApc = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(KAPC),
TAG('K', 'A', 'P', 'C'));
KeInitializeApc(ErrorApc,
&Thread->Tcb,
(PKNORMAL_ROUTINE)IopRaiseHardError,
KernelMode,
Irp);
-
+
/* Queue an APC to deal with the error (see osr documentation) */
KeInsertQueueApc(ErrorApc, Vpb, RealDeviceObject, 0);
}
/*
* @unimplemented
*/
-BOOLEAN
-STDCALL
+BOOLEAN
+STDCALL
IoRaiseInformationalHardError(NTSTATUS ErrorStatus,
PUNICODE_STRING String,
PKTHREAD Thread)
*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
{
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/event.c
* PURPOSE: Implements named events
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
PKEVENT Event;
HANDLE Handle;
NTSTATUS Status;
-
+
PreviousMode = ExGetPreviousMode();
InitializeObjectAttributes(&ObjectAttributes,
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/file.c
* PURPOSE: I/O File Object & NT File Handle Access/Managment of Files.
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/* INTERNAL FUNCTIONS ********************************************************/
-static
-NTSTATUS
+static
+NTSTATUS
STDCALL
IopLockFileCompletionRoutine(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
/*
* NAME INTERNAL
* IopCreateFile
- *
+ *
* DESCRIPTION
- *
+ *
* ARGUMENTS
- *
+ *
* RETURN VALUE
*
* REVISIONS
*/
-NTSTATUS
+NTSTATUS
STDCALL
IopCreateFile(PVOID ObjectBody,
PVOID Parent,
return(STATUS_SUCCESS);
}
-VOID
+VOID
STDCALL
IopDeleteFile(PVOID ObjectBody)
{
NTSTATUS Status;
KEVENT Event;
PDEVICE_OBJECT DeviceObject;
-
+
DPRINT("IopDeleteFile()\n");
if (FileObject->DeviceObject)
- {
+ {
/* Check if this is a direct open or not */
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
{
{
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
-
+
/* Clear and set up Events */
KeClearEvent(&FileObject->Event);
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
-
+
/* Allocate an IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
-
+
/* Set it up */
Irp->UserEvent = &Event;
Irp->UserIosb = &Irp->IoStatus;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
-
+
/* Set up Stack Pointer Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_CLOSE;
StackPtr->DeviceObject = DeviceObject;
StackPtr->FileObject = FileObject;
-
+
/* Call the FS Driver */
Status = IoCallDriver(DeviceObject, Irp);
-
+
/* Wait for completion */
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
}
IoFreeIrp(Irp);
-
+
}
- /* Clear the file name */
+ /* Clear the file name */
if (FileObject->FileName.Buffer)
{
ExFreePool(FileObject->FileName.Buffer);
FileObject->FileName.Buffer = NULL;
}
-
+
/* Free the completion context */
if (FileObject->CompletionContext)
{
}
}
-static
+static
NTSTATUS
IopSetDefaultSecurityDescriptor(SECURITY_INFORMATION SecurityInformation,
PSECURITY_DESCRIPTOR SecurityDescriptor,
return Status;
}
-VOID
+VOID
STDCALL
IopCloseFile(PVOID ObjectBody,
ULONG HandleCount)
PIO_STACK_LOCATION StackPtr;
NTSTATUS Status;
PDEVICE_OBJECT DeviceObject;
-
+
DPRINT("IopCloseFile()\n");
-
+
if (HandleCount > 1 || FileObject->DeviceObject == NULL) return;
/* Check if this is a direct open or not */
{
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
-
+
/* Clear and set up Events */
KeClearEvent(&FileObject->Event);
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
-
+
/* Allocate an IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
-
+
/* Set it up */
Irp->UserEvent = &Event;
Irp->UserIosb = &Irp->IoStatus;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Flags = IRP_CLOSE_OPERATION | IRP_SYNCHRONOUS_API;
-
+
/* Set up Stack Pointer Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_CLEANUP;
StackPtr->FileObject = FileObject;
-
+
/* Call the FS Driver */
Status = IoCallDriver(DeviceObject, Irp);
-
+
/* Wait for completion */
if (Status == STATUS_PENDING)
{
/*
* NAME EXPORTED
* IoCreateFile@56
- *
+ *
* DESCRIPTION
* Either causes a new file or directory to be created, or it
* opens an existing file, device, directory or volume, giving
* the caller a handle for the file object. This handle can be
* used by subsequent calls to manipulate data within the file
* or the file object's state of attributes.
- *
+ *
* ARGUMENTS
* FileHandle (OUT)
* Points to a variable which receives the file handle
* on return;
- *
+ *
* DesiredAccess
* Desired access to the file;
- *
+ *
* ObjectAttributes
* Structure describing the file;
- *
+ *
* IoStatusBlock (OUT)
* Receives information about the operation on return;
- *
+ *
* AllocationSize [OPTIONAL]
* Initial size of the file in bytes;
- *
+ *
* FileAttributes
* Attributes to create the file with;
- *
+ *
* ShareAccess
* Type of shared access the caller would like to the
* file;
- *
+ *
* CreateDisposition
* Specifies what to do, depending on whether the
* file already exists;
- *
+ *
* CreateOptions
* Options for creating a new file;
- *
+ *
* EaBuffer [OPTIONAL]
* Undocumented;
- *
+ *
* EaLength
* Undocumented;
- *
+ *
* CreateFileType
* Type of file (normal, named pipe, mailslot) to create;
- *
+ *
* ExtraCreateParameters [OPTIONAL]
* Additional creation data for named pipe and mailsots;
- *
+ *
* Options
* Undocumented.
- *
+ *
* RETURN VALUE
* Status
*
* Prototype taken from Bo Branten's ntifs.h v15.
* Description taken from old NtCreateFile's which is
* now a wrapper of this call.
- *
+ *
* REVISIONS
- *
+ *
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
IoCreateFile(OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
LARGE_INTEGER SafeAllocationSize;
PVOID SystemEaBuffer = NULL;
NTSTATUS Status = STATUS_SUCCESS;
-
+
DPRINT("IoCreateFile(FileHandle %x, DesiredAccess %x, "
"ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
FileHandle,DesiredAccess,ObjectAttributes,
ObjectAttributes->ObjectName->Buffer);
-
+
ASSERT_IRQL(PASSIVE_LEVEL);
if (IoStatusBlock == NULL || FileHandle == NULL)
AccessMode = KernelMode;
else
AccessMode = ExGetPreviousMode();
-
+
if(AccessMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
AccessMode,
(PVOID*)&DeviceObject,
NULL);
- ZwClose(LocalHandle);
+ ZwClose(LocalHandle);
if (!NT_SUCCESS(Status))
{
return Status;
return Status;
}
}
- RtlMapGenericMask(&DesiredAccess,
+ RtlMapGenericMask(&DesiredAccess,
BODY_TO_HEADER(FileObject)->ObjectType->Mapping);
-
+
Status = ObInsertObject ((PVOID)FileObject,
NULL,
DesiredAccess,
SecurityContext.AccessState = NULL; /* ?? */
SecurityContext.DesiredAccess = DesiredAccess;
SecurityContext.FullCreateOptions = 0; /* ?? */
-
+
KeInitializeEvent(&FileObject->Lock, SynchronizationEvent, TRUE);
KeInitializeEvent(&FileObject->Event, NotificationEvent, FALSE);
-
+
DPRINT("FileObject %x\n", FileObject);
DPRINT("FileObject->DeviceObject %x\n", FileObject->DeviceObject);
/*
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->UserEvent = &FileObject->Event;
Irp->Overlay.AllocationSize = SafeAllocationSize;
-
+
/*
* Get the stack location for the new
* IRP and prepare it.
StackLoc->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
StackLoc->Parameters.Create.EaLength = SystemEaBuffer != NULL ? EaLength : 0;
break;
-
+
case CreateFileTypeNamedPipe:
StackLoc->MajorFunction = IRP_MJ_CREATE_NAMED_PIPE;
StackLoc->Parameters.CreatePipe.SecurityContext = &SecurityContext;
*/
Status = IofCallDriver(FileObject->DeviceObject, Irp );
DPRINT("Status :%x\n", Status);
-
+
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&FileObject->Event,
/*
* NAME EXPORTED
* IoCreateStreamFileObject@8
- *
+ *
* DESCRIPTION
- *
+ *
* ARGUMENTS
* FileObject
* ?
- *
+ *
* DeviceObject
* ?
- *
+ *
* RETURN VALUE
*
* NOTE
- *
+ *
* REVISIONS
- *
+ *
* @implemented
*/
-PFILE_OBJECT
+PFILE_OBJECT
STDCALL
IoCreateStreamFileObject(PFILE_OBJECT FileObject,
PDEVICE_OBJECT DeviceObject)
DPRINT("DeviceObject %x\n", DeviceObject);
- if (DeviceObject->Vpb &&
+ if (DeviceObject->Vpb &&
DeviceObject->Vpb->DeviceObject)
{
CreatedFileObject->DeviceObject = DeviceObject->Vpb->DeviceObject;
}
else
{
- CreatedFileObject->DeviceObject = DeviceObject;
+ CreatedFileObject->DeviceObject = DeviceObject;
}
CreatedFileObject->Vpb = DeviceObject->Vpb;
CreatedFileObject->Type = IO_TYPE_FILE;
/*
* @implemented
*/
-PGENERIC_MAPPING
+PGENERIC_MAPPING
STDCALL
IoGetFileObjectGenericMapping(VOID)
{
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
IoQueryFileInformation(IN PFILE_OBJECT FileObject,
IN FILE_INFORMATION_CLASS FileInformationClass,
BOOLEAN LocalEvent = FALSE;
KEVENT Event;
NTSTATUS Status;
-
+
ASSERT(FileInformation != NULL);
-
+
Status = ObReferenceObjectByPointer(FileObject,
FILE_READ_ATTRIBUTES,
IoFileObjectType,
KernelMode);
if (!NT_SUCCESS(Status)) return(Status);
-
+
DPRINT("FileObject %x\n", FileObject);
-
+
/* Get the Device Object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
+
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
LocalEvent = TRUE;
}
-
+
/* Allocate the IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
-
+
/* Set the IRP */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = KernelMode;
Irp->UserEvent = (LocalEvent) ? &Event : NULL;
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+
/* Set the Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
- StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
+ StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
StackPtr->FileObject = FileObject;
-
+
/* Set Parameters */
StackPtr->Parameters.QueryFile.FileInformationClass = FileInformationClass;
StackPtr->Parameters.QueryFile.Length = Length;
-
+
/* Call the Driver */
Status = IoCallDriver(FileObject->DeviceObject, Irp);
-
+
if (Status == STATUS_PENDING)
{
if (LocalEvent)
{
- KeWaitForSingleObject(&Event,
- Executive,
- KernelMode,
- FileObject->Flags & FO_ALERTABLE_IO,
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = IoStatusBlock.Status;
}
else
{
KeWaitForSingleObject(&FileObject->Event,
- Executive,
- KernelMode,
- FileObject->Flags & FO_ALERTABLE_IO,
+ Executive,
+ KernelMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = FileObject->FinalStatus;
}
}
-
-
+
+
/* Return the Length and Status. ReturnedLength is NOT optional */
*ReturnedLength = IoStatusBlock.Information;
return Status;
/**
* @name NtCancelIoFile
*
- * Cancel all pending I/O operations in the current thread for specified
+ * Cancel all pending I/O operations in the current thread for specified
* file object.
*
* @param FileHandle
*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtCancelIoFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock)
/* Don't break here, we want to cancel all IRPs for the file object. */
OurIrpsInList = TRUE;
}
- }
+ }
KfLowerIrql(OldIrql);
/*
* NAME EXPORTED
* NtCreateFile@44
- *
+ *
* DESCRIPTION
* Entry point to call IoCreateFile with
* default parameters.
*
* ARGUMENTS
* See IoCreateFile.
- *
+ *
* RETURN VALUE
* See IoCreateFile.
*
*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtCreateFile(PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
IN PLARGE_INTEGER TimeOut)
{
MAILSLOT_CREATE_PARAMETERS Buffer;
-
+
DPRINT("NtCreateMailslotFile(FileHandle %x, DesiredAccess %x, "
"ObjectAttributes %x ObjectAttributes->ObjectName->Buffer %S)\n",
FileHandle,DesiredAccess,ObjectAttributes,
ObjectAttributes->ObjectName->Buffer);
-
+
ASSERT_IRQL(PASSIVE_LEVEL);
-
+
if (TimeOut != NULL)
{
Buffer.ReadTimeout.QuadPart = TimeOut->QuadPart;
/*
* NAME EXPORTED
* NtDeleteFile@4
- *
+ *
* DESCRIPTION
- *
+ *
* ARGUMENTS
* ObjectAttributes
* ?
* RETURN VALUE
*
* REVISIONS
- *
+ *
* @unimplemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtDeleteFile(IN POBJECT_ATTRIBUTES ObjectAttributes)
{
* FUNCTION: Flushes cached file data to disk
* ARGUMENTS:
* FileHandle = Points to the file
- * IoStatusBlock = Caller must supply storage to receive the result of
+ * IoStatusBlock = Caller must supply storage to receive the result of
* the flush buffers operation. The information field is
* set to number of bytes flushed to disk.
- * RETURNS: Status
+ * RETURNS: Status
* REMARKS: This function maps to the win32 FlushFileBuffers
*/
NTSTATUS
{
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
-
+
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
-
+
/* Set up the IRP */
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
Irp->RequestorMode = PreviousMode;
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_FLUSH_BUFFERS;
StackPtr->FileObject = FileObject;
-
+
/* Call the Driver */
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
if (LocalEvent)
{
- KeWaitForSingleObject(&Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
+ KeWaitForSingleObject(&Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = IoStatusBlock->Status;
}
else
{
KeWaitForSingleObject(&FileObject->Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = FileObject->FinalStatus;
}
NTSTATUS
STDCALL
NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
- IN HANDLE Event OPTIONAL,
- IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
- IN PVOID ApcContext OPTIONAL,
+ IN HANDLE Event OPTIONAL,
+ IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
+ IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG BufferSize,
PIO_STACK_LOCATION IoStack;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
DPRINT("NtNotifyChangeDirectoryFile()\n");
-
+
PAGED_CODE();
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
(PVOID *)&FileObject,
NULL);
if (Status != STATUS_SUCCESS) return(Status);
-
-
+
+
DeviceObject = FileObject->DeviceObject;
-
-
+
+
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
if (Irp==NULL)
{
ObDereferenceObject(FileObject);
return STATUS_UNSUCCESSFUL;
}
-
+
if (Event == NULL)
{
Event = &FileObject->Event;
Irp->UserBuffer = Buffer;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
-
+
IoStack = IoGetNextIrpStackLocation(Irp);
-
+
IoStack->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
IoStack->MinorFunction = IRP_MN_NOTIFY_CHANGE_DIRECTORY;
IoStack->Flags = 0;
IoStack->Control = 0;
IoStack->DeviceObject = DeviceObject;
IoStack->FileObject = FileObject;
-
+
if (WatchTree)
{
IoStack->Flags = SL_WATCH_TREE;
IoStack->Parameters.NotifyDirectory.CompletionFilter = CompletionFilter;
IoStack->Parameters.NotifyDirectory.Length = BufferSize;
-
+
Status = IoCallDriver(FileObject->DeviceObject,Irp);
/* FIXME: Should we wait here or not for synchronously opened files? */
/*
* NAME EXPORTED
* NtOpenFile@24
- *
+ *
* DESCRIPTION
* Opens an existing file (simpler than NtCreateFile).
*
* ARGUMENTS
* FileHandle (OUT)
* Variable that receives the file handle on return;
- *
+ *
* DesiredAccess
* Access desired by the caller to the file;
- *
+ *
* ObjectAttributes
* Structue describing the file to be opened;
- *
+ *
* IoStatusBlock (OUT)
* Receives details about the result of the
* operation;
- *
+ *
* ShareAccess
* Type of shared access the caller requires;
- *
+ *
* OpenOptions
* Options for the file open.
*
* RETURN VALUE
* Status.
- *
+ *
* NOTE
* Undocumented.
*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtOpenFile(PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
0);
}
-NTSTATUS
+NTSTATUS
STDCALL
NtQueryAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PFILE_BASIC_INFORMATION FileInformation)
* FileBothDirectoryInformation FILE_BOTH_DIR_INFORMATION
*
* Length = Size of the storage supplied
- * FileInformationClass = Indicates the type of information requested.
- * ReturnSingleEntry = Specify true if caller only requests the first
+ * FileInformationClass = Indicates the type of information requested.
+ * ReturnSingleEntry = Specify true if caller only requests the first
* directory found.
- * FileName = Initial directory name to query, that may contain wild
+ * FileName = Initial directory name to query, that may contain wild
* cards.
* RestartScan = Number of times the action should be repeated
* RETURNS: Status [ STATUS_SUCCESS, STATUS_ACCESS_DENIED, STATUS_INSUFFICIENT_RESOURCES,
* STATUS_INVALID_INFO_CLASS, STATUS_NO_SUCH_FILE, STATUS_NO_MORE_FILES ]
*/
NTSTATUS
-STDCALL
+STDCALL
NtQueryDirectoryFile(IN HANDLE FileHandle,
IN HANDLE PEvent OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN LocalEvent = FALSE;
PKEVENT Event = NULL;
-
+
DPRINT("NtQueryDirectoryFile()\n");
PAGED_CODE();
-
+
/* Validate User-Mode Buffers */
if(PreviousMode != KernelMode)
{
(PVOID *)&FileObject,
NULL);
if (Status != STATUS_SUCCESS) return(Status);
-
+
/* Get Event Object */
if (PEvent)
{
{
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
-
+
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
{
LocalEvent = TRUE;
}
-
+
/* Allocate the IRP */
if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE)))
{
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
-
+
/* Set up the IRP */
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock;
Irp->UserBuffer = FileInformation;
Irp->Overlay.AsynchronousParameters.UserApcRoutine = ApcRoutine;
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
-
+
/* Set up Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
StackPtr->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
StackPtr->MinorFunction = IRP_MN_QUERY_DIRECTORY;
-
+
/* Set Parameters */
StackPtr->Parameters.QueryDirectory.FileInformationClass = FileInformationClass;
StackPtr->Parameters.QueryDirectory.FileName = FileName;
StackPtr->Flags = 0;
if (RestartScan) StackPtr->Flags = SL_RESTART_SCAN;
if (ReturnSingleEntry) StackPtr->Flags |= SL_RETURN_SINGLE_ENTRY;
-
+
/* Call the Driver */
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
if (!LocalEvent)
{
KeWaitForSingleObject(&FileObject->Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = FileObject->FinalStatus;
}
return STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtQueryFullAttributesFile(IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PFILE_NETWORK_OPEN_INFORMATION FileInformation)
}
DPRINT("FileObject %x\n", FileObject);
-
+
/* Check if this is a direct open or not */
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
{
{
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
-
+
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
-
+
/* Allocate the System Buffer */
- if (!(Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
- Length,
+ if (!(Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
+ Length,
TAG_SYSB)))
{
IoFreeIrp(Irp);
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER | IRP_INPUT_OPERATION;
Irp->Flags |= (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
-
+
/* Set up Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_QUERY_INFORMATION;
/* Set the Parameters */
StackPtr->Parameters.QueryFile.FileInformationClass = FileInformationClass;
StackPtr->Parameters.QueryFile.Length = Length;
-
+
/* Call the Driver */
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
if (LocalEvent)
{
- KeWaitForSingleObject(&Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
+ KeWaitForSingleObject(&Event,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = IoStatusBlock->Status;
}
else
{
KeWaitForSingleObject(&FileObject->Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = FileObject->FinalStatus;
}
*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtReadFile(IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
"IoStatusBlock %x)\n", FileHandle, Buffer, Length, ByteOffset,
IoStatusBlock);
PAGED_CODE();
-
+
/* Validate User-Mode Buffers */
if(PreviousMode != KernelMode)
{
ProbeForWrite(Buffer,
Length,
sizeof(ULONG));
- #endif
+ #endif
}
_SEH_HANDLE
{
(PVOID*)&FileObject,
NULL);
if (!NT_SUCCESS(Status)) return Status;
-
+
/* Check the Byte Offset */
- if (!ByteOffset ||
+ if (!ByteOffset ||
(ByteOffset->u.LowPart == FILE_USE_FILE_POINTER_POSITION &&
ByteOffset->u.HighPart == 0xffffffff))
{
{
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
-
+
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
{
LocalEvent = TRUE;
}
-
+
/* Create the IRP */
_SEH_TRY
{
Irp->Overlay.AsynchronousParameters.UserApcContext = ApcContext;
Irp->Flags |= IRP_READ_OPERATION;
if (FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING) Irp->Flags |= IRP_NOCACHE;
-
+
/* Setup Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->FileObject = FileObject;
if (!LocalEvent)
{
KeWaitForSingleObject(&FileObject->Event,
- Executive,
- PreviousMode,
- FileObject->Flags & FO_ALERTABLE_IO,
+ Executive,
+ PreviousMode,
+ FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = FileObject->FinalStatus;
}
/*
* NAME EXPORTED
* NtReadFileScatter
- *
+ *
* DESCRIPTION
*
* ARGUMENTS
/*
* @unimplemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtSetEaFile(IN HANDLE FileHandle,
IN PIO_STATUS_BLOCK IoStatusBlock,
/*
* @unimplemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtSetQuotaInformationFile(HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtWriteFile (IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
/*
* NAME EXPORTED
* NtWriteFileGather
- *
+ *
* DESCRIPTION
*
* ARGUMENTS
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/fs.c
* PURPOSE: Filesystem functions
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
StackPtr->FileObject = FileObject;
StackPtr->DeviceObject = DeviceObject;
StackPtr->Parameters.FileSystemControl.InputBufferLength = InputBufferSize;
- StackPtr->Parameters.FileSystemControl.OutputBufferLength =
+ StackPtr->Parameters.FileSystemControl.OutputBufferLength =
OutputBufferSize;
StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
* If the FILE_OBJECT's VPB is defined,
* get the device from it.
*/
- if (NULL != (Vpb = FileObject->Vpb))
+ if (NULL != (Vpb = FileObject->Vpb))
{
if (NULL != (DeviceObject = Vpb->DeviceObject))
{
* in the FILE_OBJECT's DeviceObject.
*/
DeviceObject = FileObject->DeviceObject;
- if (NULL == (Vpb = DeviceObject->Vpb))
+ if (NULL == (Vpb = DeviceObject->Vpb))
{
/* DeviceObject->Vpb UNDEFINED! */
return DeviceObject;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/iocomp.c
* PURPOSE: No purpose listed.
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
#define NDEBUG
#include <internal/debug.h>
-#define IOC_TAG TAG('I', 'O', 'C', 'T')
+#define IOC_TAG TAG('I', 'O', 'C', 'T')
POBJECT_TYPE ExIoCompletionType;
NPAGED_LOOKASIDE_LIST IoCompletionPacketLookaside;
-static GENERIC_MAPPING ExIoCompletionMapping =
+static GENERIC_MAPPING ExIoCompletionMapping =
{
STANDARD_RIGHTS_READ | IO_COMPLETION_QUERY_STATE,
STANDARD_RIGHTS_WRITE | IO_COMPLETION_MODIFY_STATE,
/* FUNCTIONS *****************************************************************/
-VOID
+VOID
STDCALL
IopDeleteIoCompletion(PVOID ObjectBody)
{
/* Rundown the Queue */
FirstEntry = KeRundownQueue(Queue);
-
+
/* Clean up the IRPs */
if (FirstEntry) {
-
+
CurrentEntry = FirstEntry;
do {
-
+
/* Get the Packet */
Packet = CONTAINING_RECORD(CurrentEntry, IO_COMPLETION_PACKET, ListEntry);
-
+
/* Go to next Entry */
CurrentEntry = CurrentEntry->Flink;
-
+
/* Free it */
ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
} while (FirstEntry != CurrentEntry);
/* Allocate the Packet */
Packet = ExAllocateFromNPagedLookasideList(&IoCompletionPacketLookaside);
if (NULL == Packet) return STATUS_NO_MEMORY;
-
+
/* Set up the Packet */
Packet->Key = KeyContext;
Packet->Context = ApcContext;
Packet->IoStatus.Status = IoStatus;
Packet->IoStatus.Information = IoStatusInformation;
-
+
/* Insert the Queue */
KeInsertQueue(Queue, &Packet->ListEntry);
IopInitIoCompletionImplementation(VOID)
{
/* Create the IO Completion Type */
- ExIoCompletionType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
+ ExIoCompletionType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
RtlInitUnicodeString(&ExIoCompletionType->TypeName, L"IoCompletion");
ExIoCompletionType->Tag = IOC_TAG;
ExIoCompletionType->PeakObjects = 0;
HANDLE hIoCompletionHandle;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
if (PreviousMode != KernelMode) {
Status = _SEH_GetExceptionCode();
} _SEH_END;
-
+
if (!NT_SUCCESS(Status)) {
return Status;
0,
0,
(PVOID*)&Queue);
-
+
/* Check for success */
if (NT_SUCCESS(Status)) {
-
+
/* Initialize the Queue */
KeInitializeQueue(Queue, NumberOfConcurrentThreads);
NULL,
&hIoCompletionHandle);
ObDereferenceObject(Queue);
-
+
if (NT_SUCCESS(Status)) {
_SEH_TRY {
} _SEH_END;
}
}
-
+
/* Return Status */
return Status;
}
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
HANDLE hIoCompletionHandle;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
if(PreviousMode != KernelMode) {
_SEH_TRY {
return Status;
}
}
-
+
/* Open the Object */
Status = ObOpenObjectByName(ObjectAttributes,
ExIoCompletionType,
DesiredAccess,
NULL,
&hIoCompletionHandle);
-
+
if (NT_SUCCESS(Status)) {
_SEH_TRY {
Status = _SEH_GetExceptionCode();
} _SEH_END;
}
-
- /* Return Status */
+
+ /* Return Status */
return Status;
}
PKQUEUE Queue;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
/* Check buffers and parameters */
PreviousMode,
(PVOID*)&Queue,
NULL);
-
+
/* Check for Success */
if (NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
/* Return Info */
PLIST_ENTRY ListEntry;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
if (PreviousMode != KernelMode) {
Status = _SEH_GetExceptionCode();
} _SEH_END;
-
+
if (!NT_SUCCESS(Status)) {
return Status;
}
}
-
+
/* Open the Object */
Status = ObReferenceObjectByHandle(IoCompletionHandle,
IO_COMPLETION_MODIFY_STATE,
PreviousMode,
(PVOID*)&Queue,
NULL);
-
+
/* Check for success */
if (NT_SUCCESS(Status)) {
/* If we got a timeout or user_apc back, return the status */
if ((NTSTATUS)ListEntry == STATUS_TIMEOUT || (NTSTATUS)ListEntry == STATUS_USER_APC) {
-
- Status = (NTSTATUS)ListEntry;
-
+
+ Status = (NTSTATUS)ListEntry;
+
} else {
-
+
/* Get the Packet Data */
Packet = CONTAINING_RECORD(ListEntry, IO_COMPLETION_PACKET, ListEntry);
-
+
_SEH_TRY {
/* Return it */
*CompletionKey = Packet->Key;
*CompletionContext = Packet->Context;
*IoStatusBlock = Packet->IoStatus;
-
+
} _SEH_HANDLE {
Status = _SEH_GetExceptionCode();
/* Free packet */
ExFreeToNPagedLookasideList(&IoCompletionPacketLookaside, Packet);
}
-
+
/* Dereference the Object */
ObDereferenceObject(Queue);
}
-
+
/* Return status */
return Status;
}
{
NTSTATUS Status;
PKQUEUE Queue;
-
+
PAGED_CODE();
-
+
/* Get the Object */
Status = ObReferenceObjectByHandle(IoCompletionPortHandle,
IO_COMPLETION_MODIFY_STATE,
ExGetPreviousMode(),
(PVOID*)&Queue,
NULL);
-
+
/* Check for Success */
if (NT_SUCCESS(Status)) {
-
+
/* Set the Completion */
- Status = IoSetIoCompletion(Queue,
- CompletionKey,
+ Status = IoSetIoCompletion(Queue,
+ CompletionKey,
CompletionContext,
- CompletionStatus,
- CompletionInformation,
+ CompletionStatus,
+ CompletionInformation,
TRUE);
ObDereferenceObject(Queue);
}
-
+
/* Return status */
return Status;
}
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/io/iomgr.c
* PURPOSE: I/O Manager Initialization and Misc Utility Functions
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
FILE_GENERIC_WRITE,
FILE_GENERIC_EXECUTE,
FILE_ALL_ACCESS};
-
+
static KSPIN_LOCK CancelSpinLock;
extern LIST_ENTRY ShutdownListHead;
extern KSPIN_LOCK ShutdownListLock;
/* INIT FUNCTIONS ************************************************************/
-VOID
+VOID
INIT_FUNCTION
IoInitCancelHandling(VOID)
{
KeInitializeSpinLock(&CancelSpinLock);
}
-VOID
+VOID
INIT_FUNCTION
IoInitShutdownNotification (VOID)
{
HANDLE Handle;
IopInitDriverImplementation();
-
+
/*
* Register iomgr types: DeviceObjectType
*/
IoDeviceObjectType = ExAllocatePool (NonPagedPool,
sizeof (OBJECT_TYPE));
-
+
IoDeviceObjectType->Tag = TAG_DEVICE_TYPE;
IoDeviceObjectType->TotalObjects = 0;
IoDeviceObjectType->TotalHandles = 0;
IoDeviceObjectType->OkayToClose = NULL;
IoDeviceObjectType->Create = NULL;
IoDeviceObjectType->DuplicationNotify = NULL;
-
+
RtlInitUnicodeString(&IoDeviceObjectType->TypeName, L"Device");
ObpCreateTypeObject(IoDeviceObjectType);
* (alias DriverObjectType)
*/
IoFileObjectType = ExAllocatePool (NonPagedPool, sizeof (OBJECT_TYPE));
-
+
IoFileObjectType->Tag = TAG_FILE_TYPE;
IoFileObjectType->TotalObjects = 0;
IoFileObjectType->TotalHandles = 0;
IoFileObjectType->OkayToClose = NULL;
IoFileObjectType->Create = IopCreateFile;
IoFileObjectType->DuplicationNotify = NULL;
-
+
RtlInitUnicodeString(&IoFileObjectType->TypeName, L"File");
ObpCreateTypeObject(IoFileObjectType);
-
+
/*
* Register iomgr types: AdapterObjectType
*/
PnpInit();
}
-VOID
+VOID
INIT_FUNCTION
IoInit2(BOOLEAN BootLog)
{
NTSTATUS Status;
IoCreateDriverList();
-
+
KeInitializeSpinLock (&IoStatisticsLock);
/* Initialize raw filesystem driver */
IopInvalidateDeviceRelations(
IopRootDeviceNode,
BusRelations);
-
+
/* Start boot logging */
IopInitBootLog(BootLog);
-
+
/* Load boot start drivers */
IopInitializeBootDrivers();
}
IoInit3(VOID)
{
NTSTATUS Status;
-
+
/* Create ARC names for boot devices */
IoCreateArcNames();
IoAssignDriveLetters((PLOADER_PARAMETER_BLOCK)&KeLoaderBlock,
NULL,
NULL,
- NULL);
+ NULL);
}
/* FUNCTIONS *****************************************************************/
/*
* @implemented
*/
-VOID
-STDCALL
+VOID
+STDCALL
IoAcquireCancelSpinLock(PKIRQL Irql)
{
KeAcquireSpinLock(&CancelSpinLock,Irql);
/*
* @implemented
*/
-PVOID
+PVOID
STDCALL
IoGetInitialStack(VOID)
{
/*
* @implemented
*/
-VOID
+VOID
STDCALL
IoGetStackLimits(OUT PULONG LowLimit,
OUT PULONG HighLimit)
* @implemented
*/
VOID
-STDCALL
+STDCALL
IoReleaseCancelSpinLock(KIRQL Irql)
{
KeReleaseSpinLock(&CancelSpinLock,Irql);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/iowork.c
* PURPOSE: Manage IO system work queues
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Robert Dickenson (odin@pnc.com.au)
*/
* @implemented
*/
VOID STDCALL
-IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem,
+IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem,
IN PIO_WORKITEM_ROUTINE WorkerRoutine,
- IN WORK_QUEUE_TYPE QueueType,
+ IN WORK_QUEUE_TYPE QueueType,
IN PVOID Context)
/*
* FUNCTION: Inserts a work item in a queue for one of the system worker
* QueueType = Queue to insert it in
*/
{
- ExInitializeWorkItem(&IoWorkItem->Item, IoWorkItemCallback,
+ ExInitializeWorkItem(&IoWorkItem->Item, IoWorkItemCallback,
(PVOID)IoWorkItem);
IoWorkItem->WorkerRoutine = WorkerRoutine;
IoWorkItem->Context = Context;
IoAllocateWorkItem(PDEVICE_OBJECT DeviceObject)
{
PIO_WORKITEM IoWorkItem = NULL;
-
- IoWorkItem =
+
+ IoWorkItem =
ExAllocatePoolWithTag(NonPagedPool, sizeof(IO_WORKITEM), TAG_IOWI);
if (IoWorkItem == NULL)
{
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/irp.c
* PURPOSE: Handle IRPs
- *
+ *
* PROGRAMMERS: Hartmut Birr
* Alex Ionescu (alex@relsoft.net)
* David Welch (welch@mcmail.com)
/* PRIVATE FUNCTIONS ********************************************************/
-VOID
+VOID
STDCALL
IopFreeIrpKernelApc(PKAPC Apc,
PKNORMAL_ROUTINE *NormalRoutine,
IoFreeIrp(CONTAINING_RECORD(Apc, IRP, Tail.Apc));
}
-VOID
+VOID
STDCALL
IopAbortIrpKernelApc(PKAPC Apc)
{
/*
* FUNCTION: Performs the second stage of irp completion for read/write irps
- *
+ *
* Called as a special kernel APC kernel-routine or directly from IofCompleteRequest()
*
* Note that we'll never see irp's flagged IRP_PAGING_IO (IRP_MOUNT_OPERATION)
* cleanup/completion is fully taken care of in IoCompleteRequest.
* -Gunnar
*/
-VOID
+VOID
STDCALL
IopCompleteRequest(PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
BOOLEAN SyncIrp;
if (Apc) DPRINT("IoSecondStageCompletition with APC: %x\n", Apc);
-
+
/* Get data from the APC */
FileObject = (PFILE_OBJECT)(*SystemArgument1);
Irp = CONTAINING_RECORD(Apc, IRP, Tail.Apc);
DPRINT("IoSecondStageCompletition, %x\n", Irp);
-
+
/* Save the User Event */
UserEvent = Irp->UserEvent;
-
+
/* Remember if the IRP is Sync or not */
SyncIrp = Irp->Flags & IRP_SYNCHRONOUS_API ? TRUE : FALSE;
Irp->AssociatedIrp.SystemBuffer,
Irp->IoStatus.Information);
}
-
+
/* Also check if we should de-allocate it */
if (Irp->Flags & IRP_DEALLOCATE_BUFFER)
{
ExFreePoolWithTag(Irp->AssociatedIrp.SystemBuffer, TAG_SYS_BUF);
}
}
-
+
/* Now we got rid of these two... */
Irp->Flags &= ~(IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER);
-
+
/* Check if there's an MDL */
while ((Mdl = Irp->MdlAddress))
{
/* Remove the IRP from the list of Thread Pending IRPs */
RemoveEntryList(&Irp->ThreadListEntry);
- InitializeListHead(&Irp->ThreadListEntry);
+ InitializeListHead(&Irp->ThreadListEntry);
#if 1
/* Check for Success but allow failure for Async IRPs */
- if (NT_SUCCESS(Irp->IoStatus.Status) ||
+ if (NT_SUCCESS(Irp->IoStatus.Status) ||
(Irp->PendingReturned &&
!SyncIrp &&
(FileObject == NULL || FileObject->Flags & FO_SYNCHRONOUS_IO)))
- {
+ {
_SEH_TRY
{
/* Save the IOSB Information */
/* Ignore any error */
}
_SEH_END;
-
+
/* Check if there's an event */
if (UserEvent)
{
/* Signal the File Object Instead */
KeSetEvent(&FileObject->Event, 0, FALSE);
-
+
}
-
+
/* Now call the User APC if one was requested */
if (Irp->Overlay.AsynchronousParameters.UserApcRoutine != NULL)
{
}
}
else
- {
+ {
/* Signal the Events only if PendingReturned and we have a File Object */
if (FileObject && Irp->PendingReturned)
{
/* Ignore any error */
}
_SEH_END;
-
+
/* Signal our event if we have one */
if (UserEvent)
{
else
{
#if 1
- /* FIXME: This is necessary to fix bug #609 */
+ /* FIXME: This is necessary to fix bug #609 */
_SEH_TRY
{
*Irp->UserIosb = Irp->IoStatus;
#endif
/* We'll report the Status to the File Object, not the IRP */
FileObject->FinalStatus = Irp->IoStatus.Status;
-
+
/* Signal the File Object ONLY if this was Async */
KeSetEvent(&FileObject->Event, 0, FALSE);
}
}
-
+
/* Dereference the Event if it's an ASYNC IRP on a File Object */
if (UserEvent && !SyncIrp && FileObject)
{
if (UserEvent != &FileObject->Event)
{
ObDereferenceObject(UserEvent);
- }
+ }
}
- }
-
+ }
+
/* Dereference the File Object */
if (FileObject) ObDereferenceObject(FileObject);
-
+
/* Free the IRP */
- if (Irp) IoFreeIrp(Irp);
+ if (Irp) IoFreeIrp(Irp);
#else
}
}
}
-
+
/* Signal the user event, if one exist */
if (UserEvent)
{
Irp = NULL;
}
}
-
+
/* Free the Irp if it hasn't already */
if (Irp) IoFreeIrp(Irp);
{
/* Dereference the user event, if it is an event object */
/* FIXME: Remove last check when I/O code is fixed */
- if (UserEvent && !SyncIrp && UserEvent != &FileObject->Event)
+ if (UserEvent && !SyncIrp && UserEvent != &FileObject->Event)
{
ObDereferenceObject(UserEvent);
}
* ChargeQuota = Charge allocation to current threads quota
* RETURNS: Irp allocated
*/
-PIRP
+PIRP
STDCALL
IoAllocateIrp(CCHAR StackSize,
BOOLEAN ChargeQuota)
{
PIRP Irp;
USHORT Size = IoSizeOfIrp(StackSize);
-
+
/* Check if we shoudl charge quota */
if (ChargeQuota)
{
/* Now Initialize it */
IoInitializeIrp(Irp, Size, StackSize);
-
+
/* Return it */
return Irp;
}
*
* FUNCTION: Allocates and sets up an IRP to be sent to lower level drivers
* ARGUMENTS:
- * MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
+ * MajorFunction = One of IRP_MJ_READ, IRP_MJ_WRITE,
* IRP_MJ_FLUSH_BUFFERS or IRP_MJ_SHUTDOWN
* DeviceObject = Device object to send the irp to
* Buffer = Buffer into which data will be read or written
/* Allocate IRP */
if (!(Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE))) return Irp;
-
+
/* Get the Stack */
StackPtr = IoGetNextIrpStackLocation(Irp);
-
+
/* Write the Major function and then deal with it */
- StackPtr->MajorFunction = (UCHAR)MajorFunction;
-
+ StackPtr->MajorFunction = (UCHAR)MajorFunction;
+
/* Do not handle the following here */
if (MajorFunction != IRP_MJ_FLUSH_BUFFERS &&
MajorFunction != IRP_MJ_SHUTDOWN &&
- MajorFunction != IRP_MJ_PNP)
+ MajorFunction != IRP_MJ_PNP)
{
/* Check if this is Buffered IO */
if (DeviceObject->Flags & DO_BUFFERED_IO)
Irp->AssociatedIrp.SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYS_BUF);
-
+
/* Set flags */
Irp->Flags = IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER;
-
+
/* Handle special IRP_MJ_WRITE Case */
if (MajorFunction == IRP_MJ_WRITE)
{
{
/* Use an MDL for Direct I/O */
Irp->MdlAddress = MmCreateMdl(NULL, Buffer, Length);
-
+
/* Use the right Access Type */
if (MajorFunction == IRP_MJ_READ)
{
{
AccessType = IoWriteAccess;
}
-
+
/* Probe and Lock */
_SEH_FILTER(FreeAndGoOn)
{
IoFreeMdl(Irp->MdlAddress);
IoFreeIrp(Irp);
return EXCEPTION_CONTINUE_SEARCH;
- }
+ }
_SEH_TRY
{
/* Do the probe */
Irp = NULL;
}
_SEH_END;
-
+
if (!Irp)
return NULL;
- }
+ }
else
{
/* Neither, use the buffer */
StackPtr->Parameters.Write.ByteOffset = *StartingOffset;
}
}
-
+
/* Set the Current Thread and IOSB */
if (!IoStatusBlock) KEBUGCHECK(0); /* Temporary to catch illegal ROS Drivers */
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+
/* Set the Status Block after all is done */
return Irp;
}
Irp = NULL;
}
_SEH_END;
-
+
if (!Irp)
return NULL;
}
* RETURNS: The IRP allocated on success, or
* NULL on failure
*/
-PIRP
+PIRP
STDCALL
IoBuildSynchronousFsdRequest(ULONG MajorFunction,
PDEVICE_OBJECT DeviceObject,
PIO_STATUS_BLOCK IoStatusBlock)
{
PIRP Irp;
-
+
DPRINT("IoBuildSynchronousFsdRequest(MajorFunction %x, DeviceObject %x, "
"Buffer %x, Length %x, StartingOffset %x, Event %x, "
"IoStatusBlock %x\n",MajorFunction,DeviceObject,Buffer,Length,
StartingOffset,Event,IoStatusBlock);
-
+
/* Do the big work to set up the IRP */
Irp = IoBuildAsynchronousFsdRequest(MajorFunction,
DeviceObject,
Length,
StartingOffset,
IoStatusBlock );
-
+
/* Set the Event which makes it Syncronous */
Irp->UserEvent = Event;
/*
* @implemented
*/
-BOOLEAN
-STDCALL
+BOOLEAN
+STDCALL
IoCancelIrp(PIRP Irp)
{
KIRQL oldlvl;
PDRIVER_CANCEL CancelRoutine;
-
+
DPRINT("IoCancelIrp(Irp %x)\n",Irp);
-
+
IoAcquireCancelSpinLock(&oldlvl);
-
+
Irp->Cancel = TRUE;
-
+
CancelRoutine = IoSetCancelRoutine(Irp, NULL);
if (CancelRoutine == NULL)
{
IoReleaseCancelSpinLock(oldlvl);
return(FALSE);
}
-
+
Irp->CancelIrql = oldlvl;
CancelRoutine(IoGetCurrentIrpStackLocation(Irp)->DeviceObject, Irp);
return(TRUE);
* Thread to cancel requests for.
*/
-VOID
+VOID
STDCALL
IoCancelThreadIo(PETHREAD Thread)
{
DPRINT1("Thread with dead IRPs!");
ASSERT(FALSE);
}
-
+
OldIrql = KfRaiseIrql(APC_LEVEL);
}
/*
* @implemented
*/
-VOID
+VOID
STDCALL
IoCompleteRequest(PIRP Irp,
CCHAR PriorityBoost)
/*
* @implemented
*/
-VOID
+VOID
STDCALL
IoEnqueueIrp(IN PIRP Irp)
{
*
* FUNCTION: Sends an IRP to the next lower driver
*/
-NTSTATUS
+NTSTATUS
FASTCALL
IofCallDriver(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/* Get the Driver Object */
DriverObject = DeviceObject->DriverObject;
-
+
/* Set the Stack Location */
IoSetNextIrpStackLocation(Irp);
-
+
/* Get the current one */
Param = IoGetCurrentIrpStackLocation(Irp);
/* Get the Device Object */
Param->DeviceObject = DeviceObject;
-
+
/* Call it */
return DriverObject->MajorFunction[Param->MajorFunction](DeviceObject, Irp);
}
* PriorityBoost = Increment by which to boost the priority of the
* thread making the request
*/
-VOID
+VOID
FASTCALL
IofCompleteRequest(PIRP Irp,
CCHAR PriorityBoost)
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
ASSERT(!Irp->CancelRoutine);
ASSERT(Irp->IoStatus.Status != STATUS_PENDING);
-
+
/* Get the Current Stack */
StackPtr = IoGetCurrentIrpStackLocation(Irp);
IoSkipCurrentIrpStackLocation(Irp);
-
+
/* Loop the Stacks and complete the IRPs */
for (;Irp->CurrentLocation <= (Irp->StackCount + 1); StackPtr++)
{
/* Set Pending Returned */
Irp->PendingReturned = StackPtr->Control & SL_PENDING_RETURNED;
-
+
/*
* Completion routines expect the current irp stack location to be the same as when
* IoSetCompletionRoutine was called to set them. A side effect is that completion
}
/* Check if there is a Completion Routine to Call */
- if ((NT_SUCCESS(Irp->IoStatus.Status) &&
+ if ((NT_SUCCESS(Irp->IoStatus.Status) &&
(StackPtr->Control & SL_INVOKE_ON_SUCCESS)) ||
- (!NT_SUCCESS(Irp->IoStatus.Status) &&
+ (!NT_SUCCESS(Irp->IoStatus.Status) &&
(StackPtr->Control & SL_INVOKE_ON_ERROR)) ||
(Irp->Cancel && (StackPtr->Control & SL_INVOKE_ON_CANCEL)))
{
if (IoGetCurrentIrpStackLocation(Irp)->Control & SL_PENDING_RETURNED)
{
Irp->PendingReturned = TRUE;
- }
+ }
}
}
-
+
/* Move to next stack */
IoSkipCurrentIrpStackLocation(Irp);
}
/* Decrement and get the old count */
MasterIrpCount = InterlockedDecrement(&MasterIrp->AssociatedIrp.IrpCount);
-
+
/* Free MDLs and IRP */
while ((Mdl = Irp->MdlAddress))
{
IoFreeMdl(Mdl);
}
IoFreeIrp(Irp);
-
+
/* Complete the Master IRP */
if (!MasterIrpCount) IofCompleteRequest(MasterIrp, IO_NO_INCREMENT);
return;
DPRINT("Handling Sync Paging or Close I/O\n");
*Irp->UserIosb = Irp->IoStatus;
KeSetEvent(Irp->UserEvent, PriorityBoost, FALSE);
-
+
/* Free the IRP for a Paging I/O Only, Close is handled by us */
if (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO)
{
DPRINT("Handling Sync Paging I/O\n");
IoFreeIrp(Irp);
}
- }
+ }
else
{
DPRINT1("BUG BUG, YOU SHOULDNT BE HERE\n");
DPRINT("Unlocking MDL: %x\n", Mdl);
MmUnlockPages(Mdl);
Mdl = Mdl->Next;
- }
+ }
/* Check if we should exit because of a Deferred I/O (page 168) */
if (Irp->Flags & IRP_DEFER_IO_COMPLETION && !Irp->PendingReturned)
DPRINT("Quick return\n");
return;
}
-
+
/* Now queue the special APC */
if (!Irp->Cancel)
{
* ARGUMENTS:
* Irp = Irp to free
*/
-VOID
+VOID
STDCALL
IoFreeIrp(PIRP Irp)
{
OUT PULONG pSessionId)
{
*pSessionId = IoGetRequestorProcess(Irp)->Session;
-
+
return STATUS_SUCCESS;
}
/*
* @implemented
*/
-PIRP
+PIRP
STDCALL
IoGetTopLevelIrp(VOID)
{
* PacketSize = Size in bytes of the IRP
* StackSize = Number of stack locations in the IRP
*/
-VOID
+VOID
STDCALL
IoInitializeIrp(PIRP Irp,
USHORT PacketSize,
ASSERT(Irp != NULL);
DPRINT("IoInitializeIrp(StackSize %x, Irp %x)\n",StackSize, Irp);
-
+
/* Clear it */
RtlZeroMemory(Irp, PacketSize);
-
+
/* Set the Header and other data */
Irp->Type = IO_TYPE_IRP;
Irp->Size = PacketSize;
Irp->CurrentLocation = StackSize + 1;
Irp->ApcEnvironment = KeGetCurrentThread()->ApcStateIndex;
Irp->Tail.Overlay.CurrentStackLocation = (PIO_STACK_LOCATION)(Irp + 1) + StackSize;
-
+
/* Initialize the Thread List */
InitializeListHead(&Irp->ThreadListEntry);
-
- DPRINT("Irp->Tail.Overlay.CurrentStackLocation %x\n", Irp->Tail.Overlay.CurrentStackLocation);
+
+ DPRINT("Irp->Tail.Overlay.CurrentStackLocation %x\n", Irp->Tail.Overlay.CurrentStackLocation);
}
/*
*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
IoIsOperationSynchronous(IN PIRP Irp)
{
/* Check the flags */
if ((Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) ||
- (Irp->Flags & IRP_SYNCHRONOUS_API) ||
- (IoGetCurrentIrpStackLocation(Irp)->FileObject->Flags &
+ (Irp->Flags & IRP_SYNCHRONOUS_API) ||
+ (IoGetCurrentIrpStackLocation(Irp)->FileObject->Flags &
FO_SYNCHRONOUS_IO))
{
/* Synch API or Paging I/O is OK, as is Sync File I/O */
* NOTE: The caller is responsible for incrementing
* Irp->AssociatedIrp.IrpCount.
*/
-PIRP
+PIRP
STDCALL
IoMakeAssociatedIrp(PIRP Irp,
CCHAR StackSize)
/* Associate them */
AssocIrp->AssociatedIrp.MasterIrp = Irp;
-
+
return AssocIrp;
}
/*
* @implemented
*/
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
IoPageRead(PFILE_OBJECT FileObject,
PMDL Mdl,
PLARGE_INTEGER Offset,
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PDEVICE_OBJECT DeviceObject;
-
+
DPRINT("IoPageRead(FileObject %x, Mdl %x)\n",
FileObject, Mdl);
-
+
/* Get the Device Object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
+
/* Allocate IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
-
+
/* Get the Stack */
StackPtr = IoGetNextIrpStackLocation(Irp);
-
+
/* Create the IRP Settings */
Irp->MdlAddress = Mdl;
Irp->UserBuffer = MmGetMdlVirtualAddress(Mdl);
Irp->Flags = IRP_PAGING_IO | IRP_NOCACHE | IRP_SYNCHRONOUS_PAGING_IO | IRP_INPUT_OPERATION;
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+
/* Set the Stack Settings */
StackPtr->Parameters.Read.Length = MmGetMdlByteCount(Mdl);
StackPtr->Parameters.Read.ByteOffset = *Offset;
StackPtr->MajorFunction = IRP_MJ_READ;
StackPtr->FileObject = FileObject;
-
+
/* Call the Driver */
return IofCallDriver(DeviceObject, Irp);
}
/*
* @implemented
*/
-VOID
+VOID
STDCALL
IoQueueThreadIrp(IN PIRP Irp)
{
KIRQL OldIrql;
-
+
/* Raise to APC */
OldIrql = KfRaiseIrql(APC_LEVEL);
-
+
/*
* Synchronous irp's are queued to requestor thread. If they are not
* completed when the thread exits, they are canceled (cleaned up).
* - Gunnar
*/
InsertTailList(&Irp->Tail.Overlay.Thread->IrpList, &Irp->ThreadListEntry);
-
+
/* Lower back */
KfLowerIrql(OldIrql);
}
/*
* @implemented
- * Reference: Chris Cant's "Writing WDM Device Drivers"
+ * Reference: Chris Cant's "Writing WDM Device Drivers"
*/
-VOID
+VOID
STDCALL
IoReuseIrp(IN OUT PIRP Irp,
IN NTSTATUS Status)
{
UCHAR AllocationFlags;
-
+
/* Get the old flags */
AllocationFlags = Irp->AllocationFlags;
-
+
/* Reinitialize the IRP */
IoInitializeIrp(Irp, Irp->Size, Irp->StackCount);
-
+
/* Duplicate the data */
Irp->IoStatus.Status = Status;
Irp->AllocationFlags = AllocationFlags;
/*
* @implemented
*/
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
IoSynchronousPageWrite(PFILE_OBJECT FileObject,
PMDL Mdl,
PLARGE_INTEGER Offset,
PIRP Irp;
PIO_STACK_LOCATION StackPtr;
PDEVICE_OBJECT DeviceObject;
-
+
DPRINT("IoSynchronousPageWrite(FileObject %x, Mdl %x)\n",
FileObject, Mdl);
-
+
/* Get the Device Object */
DeviceObject = IoGetRelatedDeviceObject(FileObject);
-
+
/* Allocate IRP */
Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
-
+
/* Get the Stack */
StackPtr = IoGetNextIrpStackLocation(Irp);
-
+
/* Create the IRP Settings */
Irp->MdlAddress = Mdl;
Irp->UserBuffer = MmGetMdlVirtualAddress(Mdl);
Irp->Flags = IRP_PAGING_IO | IRP_NOCACHE | IRP_SYNCHRONOUS_PAGING_IO;
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+
/* Set the Stack Settings */
StackPtr->Parameters.Write.Length = MmGetMdlByteCount(Mdl);
StackPtr->Parameters.Write.ByteOffset = *Offset;
StackPtr->MajorFunction = IRP_MJ_WRITE;
StackPtr->FileObject = FileObject;
-
+
/* Call the Driver */
return IofCallDriver(DeviceObject, Irp);
}
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/irq.c
* PURPOSE: IRQ handling
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/*
* FUNCTION: Registers a driver's isr to be called when its device interrupts
* ARGUMENTS:
- * InterruptObject (OUT) = Points to the interrupt object created on
+ * InterruptObject (OUT) = Points to the interrupt object created on
* return
* ServiceRoutine = Routine to be called when the device interrupts
* ServiceContext = Parameter to be passed to ServiceRoutine
* access between the isr and other driver routines. This is
* required if the isr handles more than one vector or the
* driver has more than one isr
- * Vector = Interrupt vector to allocate
+ * Vector = Interrupt vector to allocate
* (returned from HalGetInterruptVector)
* Irql = DIRQL returned from HalGetInterruptVector
* SynchronizeIrql = DIRQL at which the isr will execute. This must
{
PKINTERRUPT Interrupt;
ULONG i, count;
-
+
ASSERT_IRQL(PASSIVE_LEVEL);
-
+
DPRINT("IoConnectInterrupt(Vector %x)\n",Vector);
-
+
ProcessorEnableMask &= ((1 << KeNumberProcessors) - 1);
if (ProcessorEnableMask == 0)
{
return STATUS_INVALID_PARAMETER;
}
-
+
for (i = 0, count = 0; i < KeNumberProcessors; i++)
{
if (ProcessorEnableMask & (1 << i))
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/plugplay.c
* PURPOSE: Plug-and-play interface routines
- *
+ *
* PROGRAMMERS: Eric Kohl <eric.kohl@t-online.de>
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/pnpdma.c
* PURPOSE: PnP manager DMA routines
- *
+ *
* PROGRAMMERS: Filip Navara (xnavara@volny.cz)
*/
PDMA_ADAPTER Result = NULL;
PDMA_ADAPTER_INTERNAL ResultInternal = NULL;
PADAPTER_OBJECT HalAdapter;
-
+
DPRINT("IoGetDmaAdapter called\n");
-
+
/*
* Try to create DMA adapter through bus driver
*/
{
if (DeviceDescription->InterfaceType == 0x0F /*PNPBus*/ ||
DeviceDescription->InterfaceType == 0xFFFFFFFF)
- {
+ {
RtlCopyMemory(&PrivateDeviceDescription, DeviceDescription,
sizeof(DEVICE_DESCRIPTION));
Status = IoGetDeviceProperty(PhysicalDeviceObject,
- DevicePropertyLegacyBusType, sizeof(INTERFACE_TYPE),
+ DevicePropertyLegacyBusType, sizeof(INTERFACE_TYPE),
&PrivateDeviceDescription.InterfaceType, &ResultLength);
if (!NT_SUCCESS(Status))
{
Stack.Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
Stack.Parameters.QueryInterface.Version = 1;
Stack.Parameters.QueryInterface.Interface = (PINTERFACE)&BusInterface;
- Stack.Parameters.QueryInterface.InterfaceType =
+ Stack.Parameters.QueryInterface.InterfaceType =
&GUID_BUS_INTERFACE_STANDARD;
Status = IopInitiatePnpIrp(PhysicalDeviceObject, &IoStatusBlock,
IRP_MN_QUERY_INTERFACE, &Stack);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/pnpmgr.c
* PURPOSE: Initializes the PnP manager
- *
+ *
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
KeyNameBuffer = ExAllocatePool(PagedPool,
(49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length);
-
- DPRINT("KeyNameBuffer: %x, value %S\n",
+
+ DPRINT("KeyNameBuffer: %x, value %S\n",
KeyNameBuffer, RegistryPropertyName);
if (KeyNameBuffer == NULL)
* @param DeviceObject Device to get the registry key for.
* @param DevInstKeyType Type of the key to return.
* @param DesiredAccess Access mask (eg. KEY_READ | KEY_WRITE).
- * @param DevInstRegKey Handle to the opened registry key on
+ * @param DevInstRegKey Handle to the opened registry key on
* successful return.
*
* @return Status.
if (DevInstKeyType & PLUGPLAY_REGKEY_CURRENT_HWPROFILE)
RtlAppendUnicodeToString(&KeyName, ProfileKeyName);
-
+
if (DevInstKeyType & PLUGPLAY_REGKEY_DRIVER)
{
RtlAppendUnicodeToString(&KeyName, ClassKeyName);
{
WCHAR RegKeyBuffer[MAX_PATH];
UNICODE_STRING RegKey;
-
+
RegKey.Length = 0;
RegKey.MaximumLength = sizeof(RegKeyBuffer);
RegKey.Buffer = RegKeyBuffer;
-
+
/*
* Retrieve configuration from Enum key
*/
-/* $Id:$
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/pnpnotify.c
* PURPOSE: Plug & Play notification functions
- *
+ *
* PROGRAMMERS: Filip Navara (xnavara@volny.cz)
* Hervé Poussineau (hpoussin@reactos.com)
*/
PPNP_NOTIFY_ENTRY Entry;
PWSTR SymbolicLinkList;
NTSTATUS Status;
-
+
PAGED_CODE();
-
+
DPRINT("IoRegisterPlugPlayNotification(EventCategory 0x%x, EventCategoryFlags 0x%lx, DriverObject %p) called.\n",
EventCategory,
EventCategoryFlags,
DriverObject);
-
+
ObReferenceObject(DriverObject);
-
+
/* Try to allocate entry for notification before sending any notification */
Entry = ExAllocatePoolWithTag(
NonPagedPool,
ObDereferenceObject(DriverObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
-
+
if (EventCategory == EventCategoryTargetDeviceChange
&& EventCategoryFlags & PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES)
{
DPRINT1("IoRegisterPlugPlayNotification(): need to send notifications for existing interfaces!\n");
ExFreePool(SymbolicLinkList);
}
-
+
Entry->PnpNotificationProc = CallbackRoutine;
Entry->EventCategory = EventCategory;
Entry->Context = Context;
break;
}
}
-
+
KeAcquireGuardedMutex(&PnpNotifyListLock);
InsertHeadList(&PnpNotifyListHead,
&Entry->PnpNotifyList);
KeReleaseGuardedMutex(&PnpNotifyListLock);
-
+
DPRINT("IoRegisterPlugPlayNotification() returns NotificationEntry %p\n",
Entry);
*NotificationEntry = Entry;
IN PVOID NotificationEntry)
{
PPNP_NOTIFY_ENTRY Entry;
-
+
PAGED_CODE();
-
+
Entry = (PPNP_NOTIFY_ENTRY)NotificationEntry;
DPRINT("IoUnregisterPlugPlayNotification(NotificationEntry %p) called\n",
Entry);
-
+
KeAcquireGuardedMutex(&PnpNotifyListLock);
RtlFreeUnicodeString(&Entry->Guid);
RemoveEntryList(&Entry->PnpNotifyList);
KeReleaseGuardedMutex(&PnpNotifyListLock);
-
+
return STATUS_SUCCESS;
}
PLIST_ENTRY Entry;
PVOID NotificationStructure;
BOOLEAN CallCurrentEntry;
-
+
ASSERT(DeviceObject);
-
+
KeAcquireGuardedMutex(&PnpNotifyListLock);
if (IsListEmpty(&PnpNotifyListHead))
{
KeReleaseGuardedMutex(&PnpNotifyListLock);
return;
}
-
+
switch (EventCategory)
{
case EventCategoryDeviceInterfaceChange:
return;
}
}
-
+
/* Loop through procedures registred in PnpNotifyListHead
* list to find those that meet some criteria.
*/
-
+
Entry = PnpNotifyListHead.Flink;
while (Entry != &PnpNotifyListHead)
{
ChangeEntry = CONTAINING_RECORD(Entry, PNP_NOTIFY_ENTRY, PnpNotifyList);
CallCurrentEntry = FALSE;
-
+
switch (EventCategory)
{
case EventCategoryDeviceInterfaceChange:
break;
}
}
-
+
if (CallCurrentEntry)
{
/* Call entry into new allocated memory */
DPRINT("IopNotifyPlugPlayNotification(): found suitable callback %p\n",
ChangeEntry);
-
+
(ChangeEntry->PnpNotificationProc)(
NotificationStructure,
ChangeEntry->Context);
}
-
+
Entry = Entry->Flink;
}
KeReleaseGuardedMutex(&PnpNotifyListLock);
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/pnpreport.c
* PURPOSE: Device Changes Reporting functions
- *
+ *
* PROGRAMMERS: Filip Navara (xnavara@volny.cz)
*/
PDEVICE_NODE DeviceNode;
PDEVICE_OBJECT Pdo;
NTSTATUS Status = STATUS_SUCCESS;
-
+
DPRINT("IoReportDetectedDevice (DeviceObject %p, *DeviceObject %p)\n",
DeviceObject, DeviceObject ? *DeviceObject : NULL);
-
+
/* if *DeviceObject is not NULL, we must use it as a PDO,
* and don't create a new one.
*/
if (DeviceObject)
*DeviceObject = Pdo;
}
-
+
/* we don't need to call AddDevice and send IRP_MN_START_DEVICE */
-
+
/* FIXME: save this device into the root-enumerated list, so this
* device would be detected as a PnP device during next startups.
*/
-
+
return Status;
}
{
*ConflictDetected = FALSE;
DPRINT1("IoReportResourceForDetection partly implemented\n");
-
+
/* FIXME: Manually indicate conflicts with KD Ports */
if (DriverList)
{
if (KdpDetectConflicts(DriverList))
{
*ConflictDetected = TRUE;
- return STATUS_CONFLICTING_ADDRESSES;
+ return STATUS_CONFLICTING_ADDRESSES;
}
}
-
+
if (PopSystemPowerDeviceNode != NULL && DriverListSize > 0)
{
/* We hope legacy devices will be enumerated by ACPI */
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/pnproot.c
* PURPOSE: PnP manager root device
- *
+ *
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
NTSTATUS Status;
DPRINT("Called\n");
-
+
Status = Irp->IoStatus.Status;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
}
/* FIXME: Disabled due to still using the old method of auto loading drivers e.g.
- there are more entries in the list than found in the registry as some
+ there are more entries in the list than found in the registry as some
drivers are passed on the command line */
// DeviceExtension->DeviceListCount = 0;
if (!NT_SUCCESS(Status))
{
DPRINT("PnpRootFdoReadDeviceInfo() failed with status %x\n", Status);
- /* FIXME: */
+ /* FIXME: */
}
ExInterlockedInsertTailList(
if (Irp->IoStatus.Information)
{
- /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
+ /* FIXME: Another bus driver has already created a DEVICE_RELATIONS
structure so we must merge this structure with our own */
}
Size = sizeof(DEVICE_RELATIONS) + sizeof(Relations->Objects) *
- (DeviceExtension->DeviceListCount - 1);
+ (DeviceExtension->DeviceListCount - 1);
Relations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, Size);
if (!Relations)
pDeviceObject,
Buffer,
WriteLength,
- WriteOffset,
- &Event,
+ WriteOffset,
+ &Event,
&IoStatus);
if (!Irp)
{
IN ULONG CtlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferSize,
- IN OUT PVOID OutputBuffer,
+ IN OUT PVOID OutputBuffer,
IN OUT PULONG pOutputBufferSize)
{
ULONG OutputBufferSize = 0;
NTSTATUS Status;
DPRINT("RawFsBlockDeviceIoControl(DeviceObject %x, CtlCode %x, "
- "InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
- "POutputBufferSize %x (%x)\n", DeviceObject, CtlCode,
- InputBuffer, InputBufferSize, OutputBuffer, pOutputBufferSize,
+ "InputBuffer %x, InputBufferSize %x, OutputBuffer %x, "
+ "POutputBufferSize %x (%x)\n", DeviceObject, CtlCode,
+ InputBuffer, InputBufferSize, OutputBuffer, pOutputBufferSize,
pOutputBufferSize ? *pOutputBufferSize : 0);
if (pOutputBufferSize)
KeInitializeEvent(&Event, NotificationEvent, FALSE);
DPRINT("Building device I/O control request ...\n");
- Irp = IoBuildDeviceIoControlRequest(CtlCode,
- DeviceObject,
- InputBuffer,
- InputBufferSize,
+ Irp = IoBuildDeviceIoControlRequest(CtlCode,
+ DeviceObject,
+ InputBuffer,
+ InputBufferSize,
OutputBuffer,
- OutputBufferSize,
- FALSE,
- &Event,
+ OutputBufferSize,
+ FALSE,
+ &Event,
&IoStatus);
if (Irp == NULL)
{
memset(Fcb, 0, sizeof(RAWFS_FCB));
ExInitializeResourceLite(&Fcb->PagingIoResource);
ExInitializeResourceLite(&Fcb->MainResource);
-// FsRtlInitializeFileLock(&Fcb->FileLock, NULL, NULL);
+// FsRtlInitializeFileLock(&Fcb->FileLock, NULL, NULL);
return Fcb;
}
static VOID
RawFsDestroyFCB(IN PRAWFS_GLOBAL_DATA pGlobalData, IN PRAWFS_FCB pFcb)
{
- //FsRtlUninitializeFileLock(&pFcb->FileLock);
+ //FsRtlUninitializeFileLock(&pFcb->FileLock);
ExDeleteResourceLite(&pFcb->PagingIoResource);
ExDeleteResourceLite(&pFcb->MainResource);
ExFreeToNPagedLookasideList(&pGlobalData->FcbLookasideList, pFcb);
FileObject = IoSp->FileObject;
DeviceExt = IrpContext->DeviceObject->DeviceExtension;
- if (FileObject->FileName.Length == 0 &&
+ if (FileObject->FileName.Length == 0 &&
FileObject->RelatedFileObject == NULL)
{
/* This a open operation for the volume itself */
DPRINT("RawFsCreate(IrpContext %x)\n", IrpContext);
ASSERT(IrpContext);
-
+
if (RawFsIsRawFileSystemDeviceObject(IrpContext->DeviceObject))
{
/* DeviceObject represents FileSystem instead of logical volume */
Status = RawFsCreateFile(IrpContext);
IrpContext->Irp->IoStatus.Status = Status;
- IoCompleteRequest(IrpContext->Irp,
+ IoCompleteRequest(IrpContext->Irp,
(CCHAR)(NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));
RawFsFreeIrpContext(IrpContext);
DeviceObject->Flags |= DO_DIRECT_IO;
DeviceExt = (PVOID) DeviceObject->DeviceExtension;
RtlZeroMemory(DeviceExt, sizeof(RAWFS_DEVICE_EXTENSION));
-
+
/* Use same vpb as device disk */
DeviceObject->Vpb = IrpContext->Stack->Parameters.MountVolume.DeviceObject->Vpb;
DeviceExt->StorageDevice = IrpContext->Stack->Parameters.MountVolume.DeviceObject;
DeviceExt->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
DeviceObject->StackSize = DeviceExt->StorageDevice->StackSize + 1;
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
-
+
KeInitializeSpinLock(&DeviceExt->FcbListLock);
InitializeListHead(&DeviceExt->FcbListHead);
NTSTATUS Status;
DPRINT("RawFsFileSystemControl(IrpContext %x)\n", IrpContext);
-
+
ASSERT(IrpContext);
switch (IrpContext->MinorFunction)
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/remlock.c
* PURPOSE: Remove Lock functions
- *
+ *
* PROGRAMMERS: Filip Navara (xnavara@volny.cz)
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/resource.c
* PURPOSE: Hardware resource managment
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Alex Ionescu (alex@relsoft.net)
*/
*
* FUNCTION:
* Reads and returns Hardware information from the appropriate hardware
- * registry key. Helper sub of IopQueryBusDescription.
+ * registry key. Helper sub of IopQueryBusDescription.
*
* ARGUMENTS:
* Query - What the parent function wants.
UNICODE_STRING RootKey,
HANDLE RootKeyHandle,
ULONG Bus,
- PKEY_VALUE_FULL_INFORMATION *BusInformation)
+ PKEY_VALUE_FULL_INFORMATION *BusInformation)
{
NTSTATUS Status = STATUS_SUCCESS;
ExFreePool(ControllerFullInformation);
return Status;
}
-
+
/* Find out Controller Numbers */
ControllerNumber = 0;
MaximumControllerNumber = ControllerFullInformation->SubKeys;
/* Create String */
Status |= RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
Status |= RtlAppendUnicodeStringToString(&ControllerRootRegName, &TempString);
-
+
/* Something messed up */
if (!NT_SUCCESS(Status)) break;
Status |= RtlAppendUnicodeToString(&ControllerRootRegName, ArcTypes[*Query->PeripheralType]);
/* Something messed up */
- if (!NT_SUCCESS(Status)) goto EndLoop;
+ if (!NT_SUCCESS(Status)) goto EndLoop;
/* Set the Peripheral Number if specified */
if (Query->PeripheralNumber && *Query->PeripheralNumber)
/* Create String */
Status |= RtlAppendUnicodeToString(&ControllerRootRegName, L"\\");
Status |= RtlAppendUnicodeStringToString(&ControllerRootRegName, &TempString);
-
+
/* Something messed up */
if (!NT_SUCCESS(Status)) break;
UNICODE_STRING RootKey,
HANDLE RootKeyHandle,
PULONG Bus,
- BOOLEAN KeyIsRoot)
+ BOOLEAN KeyIsRoot)
{
NTSTATUS Status;
ULONG BusLoop;
ZwClose(SubRootKeyHandle);
SubRootKeyHandle = NULL;
}
-
+
/* Free the last remaining Allocated Memory */
if (BasicInformation)
ExFreePool(BasicInformation);
BOOLEAN OverrideConflict,
PBOOLEAN ConflictDetected)
/*
- * FUNCTION: Reports hardware resources in the
+ * FUNCTION: Reports hardware resources in the
* \Registry\Machine\Hardware\ResourceMap tree, so that a subsequently
* loaded driver cannot attempt to use the same resources.
* ARGUMENTS:
* DriverClassName - The class of driver under which the resource
* information should be stored.
- * DriverObject - The driver object that was input to the
+ * DriverObject - The driver object that was input to the
* DriverEntry.
* DriverList - Resources that claimed for the driver rather than
* per-device.
RootRegKey.MaximumLength = 2048;
RootRegKey.Buffer = ExAllocatePoolWithTag(PagedPool, RootRegKey.MaximumLength, TAG_IO_RESOURCE);
RtlAppendUnicodeToString(&RootRegKey, RootRegString);
-
+
/* Open a handle to the Root Registry Key */
InitializeObjectAttributes(
&ObjectAttributes,
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/share.c
* PURPOSE: No purpose listed.
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
PSHARE_ACCESS ShareAccess)
{
PAGED_CODE();
-
+
if (FileObject->ReadAccess ||
FileObject->WriteAccess ||
FileObject->DeleteAccess)
BOOLEAN SharedRead;
BOOLEAN SharedWrite;
BOOLEAN SharedDelete;
-
+
PAGED_CODE();
ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE)) != 0;
BOOLEAN SharedRead;
BOOLEAN SharedWrite;
BOOLEAN SharedDelete;
-
+
PAGED_CODE();
ReadAccess = (DesiredAccess & (FILE_READ_DATA | FILE_EXECUTE)) != 0;
IN ACCESS_MASK GrantedAccess)
{
PAGED_CODE();
-
+
RtlMapGenericMask(DesiredAccess,
IoFileObjectType->Mapping);
}
DPRINT("FileObject %x\n", FileObject);
-
+
DeviceObject = FileObject->DeviceObject;
Irp = IoAllocateIrp(DeviceObject->StackSize,
NULL);
Status = IoStatusBlock.Status;
}
-
+
return Status;
}
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/timer.c
* PURPOSE: IO timers
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Alex Ionescu (alex@relsoft.net)
*/
PLIST_ENTRY TimerEntry;
PIO_TIMER Timer;
ULONG i;
-
+
DPRINT("Dispatching IO Timers. There are: %x \n", IopTimerCount);
-
+
/* Check if any Timers are actualyl enabled as of now */
if (IopTimerCount) {
-
+
/* Lock the Timers */
- KeAcquireSpinLock(&IopTimerLock, &OldIrql);
-
+ KeAcquireSpinLock(&IopTimerLock, &OldIrql);
+
/* Call the Timer Routine of each enabled Timer */
for(TimerEntry = IopTimerQueueHead.Flink, i = IopTimerCount;
(TimerEntry != &IopTimerQueueHead) && i;
Timer = CONTAINING_RECORD(TimerEntry, IO_TIMER, IoTimerList);
if (Timer->TimerEnabled) {
- DPRINT("Dispatching a Timer Routine: %x for Device Object: %x \n",
+ DPRINT("Dispatching a Timer Routine: %x for Device Object: %x \n",
Timer->TimerRoutine,
Timer->DeviceObject);
Timer->TimerRoutine(Timer->DeviceObject, Timer->Context);
i--;
}
}
-
+
/* Unlock the Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
}
/* Lock Timers */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
-
+
/* Remove Timer from the List and Drop the Timer Count if Enabled */
RemoveEntryList(&Timer->IoTimerList);
if (Timer->TimerEnabled) IopTimerCount--;
-
+
/* Unlock the Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
}
*/
{
LARGE_INTEGER ExpireTime;
-
+
/* Initialize Timer List Lock */
KeInitializeSpinLock(&IopTimerLock);
-
+
/* Initialize Timer List */
InitializeListHead(&IopTimerQueueHead);
-
+
/* Initialize the DPC/Timer which will call the other Timer Routines */
ExpireTime.QuadPart = -10000000;
KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL);
*/
NTSTATUS
STDCALL
-IoInitializeTimer(PDEVICE_OBJECT DeviceObject,
+IoInitializeTimer(PDEVICE_OBJECT DeviceObject,
PIO_TIMER_ROUTINE TimerRoutine,
PVOID Context)
/*
*/
{
DPRINT("IoInitializeTimer() called for Device Object: %x with Routine: %x \n", DeviceObject, TimerRoutine);
-
+
/* Allocate Timer */
if (!DeviceObject->Timer) {
DeviceObject->Timer = ExAllocatePoolWithTag(NonPagedPool,
DeviceObject->Timer->Type = IO_TYPE_TIMER;
DeviceObject->Timer->DeviceObject = DeviceObject;
}
-
+
DeviceObject->Timer->TimerRoutine = TimerRoutine;
DeviceObject->Timer->Context = Context;
DeviceObject->Timer->TimerEnabled = FALSE;
ExInterlockedInsertTailList(&IopTimerQueueHead,
&DeviceObject->Timer->IoTimerList,
&IopTimerLock);
-
- /* Return Success */
+
+ /* Return Success */
DPRINT("IoInitializeTimer() Completed\n");
return(STATUS_SUCCESS);
}
*/
{
KIRQL OldIrql;
-
+
DPRINT("IoStartTimer for Device Object: %x\n", DeviceObject);
-
+
/* Lock Timers */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
-
+
/* If the timer isn't already enabled, enable it and increase IO Timer Count*/
if (!DeviceObject->Timer->TimerEnabled) {
DeviceObject->Timer->TimerEnabled = TRUE;
IopTimerCount++;
}
-
+
/* Unlock Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
DPRINT("IoStartTimer Completed for Device Object: %x New Count: %x \n", DeviceObject, IopTimerCount);
*/
{
KIRQL OldIrql;
-
+
DPRINT("IoStopTimer for Device Object: %x\n", DeviceObject);
-
+
/* Lock Timers */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
-
+
/* If the timer is enabled, disable it and decrease IO Timer Count*/
if (DeviceObject->Timer->TimerEnabled) {
DeviceObject->Timer->TimerEnabled = FALSE;
IopTimerCount--;
}
-
+
/* Unlock Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
DPRINT("IoStopTimer Completed for Device Object: %x New Count: %x \n", DeviceObject, IopTimerCount);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/vpb.c
* PURPOSE: Volume Parameter Block managment
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
IopAttachVpb(PDEVICE_OBJECT DeviceObject)
{
PVPB Vpb;
-
+
/* Allocate the Vpb */
Vpb = ExAllocatePoolWithTag(NonPagedPool,
sizeof(VPB),
TAG_VPB);
if (Vpb == NULL) return(STATUS_UNSUCCESSFUL);
-
+
/* Clear it so we don't waste time manually */
RtlZeroMemory(Vpb, sizeof(VPB));
-
+
/* Set the Header and Device Field */
Vpb->Type = IO_TYPE_VPB;
Vpb->Size = sizeof(VPB);
/*
* FUNCTION: Queries the volume information
- * ARGUMENTS:
+ * ARGUMENTS:
* FileHandle = Handle to a file object on the target volume
* ReturnLength = DataWritten
- * FsInformation = Caller should supply storage for the information
+ * FsInformation = Caller should supply storage for the information
* structure.
* Length = Size of the information structure
* FsInformationClass = Index to a information structure
* FileFsSizeInformation FILE_FS_SIZE_INFORMATION
* FileFsDeviceInformation FILE_FS_DEVICE_INFORMATION
* FileFsAttributeInformation FILE_FS_ATTRIBUTE_INFORMATION
- * FileFsControlInformation
+ * FileFsControlInformation
* FileFsQuotaQueryInformation --
* FileFsQuotaSetInformation --
- * FileFsMaximumInformation
+ * FileFsMaximumInformation
*
* RETURNS: Status
*
PIO_STACK_LOCATION StackPtr;
PVOID SystemBuffer;
KPROCESSOR_MODE PreviousMode;
-
+
ASSERT(IoStatusBlock != NULL);
ASSERT(FsInformation != NULL);
-
+
DPRINT("FsInformation %p\n", FsInformation);
PreviousMode = ExGetPreviousMode();
{
return(Status);
}
-
+
DeviceObject = FileObject->DeviceObject;
-
+
Irp = IoAllocateIrp(DeviceObject->StackSize,
TRUE);
if (Irp == NULL)
ObDereferenceObject(FileObject);
return(STATUS_INSUFFICIENT_RESOURCES);
}
-
+
SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
ObDereferenceObject(FileObject);
return(STATUS_INSUFFICIENT_RESOURCES);
}
-
+
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->UserEvent = &FileObject->Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
StackPtr->MinorFunction = 0;
StackPtr->Parameters.QueryVolume.Length = Length;
StackPtr->Parameters.QueryVolume.FsInformationClass =
FsInformationClass;
-
+
Status = IoCallDriver(DeviceObject,
Irp);
if (Status == STATUS_PENDING)
Status = IoStatusBlock->Status;
}
DPRINT("Status %x\n", Status);
-
+
if (NT_SUCCESS(Status))
{
DPRINT("Information %lu\n", IoStatusBlock->Information);
}
ExFreePool(SystemBuffer);
-
+
return(Status);
}
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
NTSTATUS Status;
-
+
ASSERT(FsInformation != NULL);
-
+
DPRINT("FsInformation %p\n", FsInformation);
-
+
Status = ObReferenceObjectByPointer(FileObject,
FILE_READ_ATTRIBUTES,
IoFileObjectType,
{
return(Status);
}
-
+
DeviceObject = FileObject->DeviceObject;
-
+
Irp = IoAllocateIrp(DeviceObject->StackSize,
TRUE);
if (Irp == NULL)
Irp->UserEvent = &FileObject->Event;
Irp->UserIosb = &IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
StackPtr->MinorFunction = 0;
StackPtr->Parameters.QueryVolume.Length = Length;
StackPtr->Parameters.QueryVolume.FsInformationClass =
FsInformationClass;
-
+
Status = IoCallDriver(DeviceObject,
Irp);
if (Status == STATUS_PENDING)
Status = IoStatusBlock.Status;
}
DPRINT("Status %x\n", Status);
-
+
if (ReturnedLength != NULL)
{
*ReturnedLength = IoStatusBlock.Information;
}
-
+
return(Status);
}
{
return(Status);
}
-
+
DeviceObject = FileObject->DeviceObject;
-
+
Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
if (Irp == NULL)
{
ObDereferenceObject(FileObject);
return(STATUS_INSUFFICIENT_RESOURCES);
}
-
+
SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
ObDereferenceObject(FileObject);
return(STATUS_INSUFFICIENT_RESOURCES);
}
-
+
MmSafeCopyFromUser(SystemBuffer,
FsInformation,
Length);
-
+
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->UserEvent = &FileObject->Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_SET_VOLUME_INFORMATION;
StackPtr->MinorFunction = 0;
StackPtr->Parameters.SetVolume.Length = Length;
StackPtr->Parameters.SetVolume.FsInformationClass =
FsInformationClass;
-
+
Status = IoCallDriver(DeviceObject,Irp);
if (Status == STATUS_PENDING)
{
}
ExFreePool(SystemBuffer);
-
+
return(Status);
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/wmi.c
* PURPOSE: Windows Management Instrumentation
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/kd/kdinit.c
* PURPOSE: Kernel Debugger Initializtion
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
PLOADER_PARAMETER_BLOCK LoaderBlock)
{
PCHAR p2 = Currentp2;
-
+
#ifdef DBG
/* Check for BOCHS Debugging */
if (!_strnicmp(p2, "BOCHS", 5))
/* Enable it */
p2 += 3;
KdpDebugMode.Gdb = TRUE;
-
+
/* Enable Debugging */
KdDebuggerEnabled = TRUE;
WrapperInitRoutine = KdpGdbStubInit;
/* Enable it */
p2 += 4;
KdpDebugMode.Pice = TRUE;
-
+
/* Enable Debugging */
KdDebuggerEnabled = TRUE;
}
#endif
return p2;
}
-
+
PCHAR
STDCALL
KdpGetDebugMode(PCHAR Currentp2)
{
PCHAR p2 = Currentp2;
ULONG Value;
-
+
/* Check for Screen Debugging */
if (!_strnicmp(p2, "SCREEN", 6))
{
{
/* Valid port found, enable Serial Debugging */
KdpDebugMode.Serial = TRUE;
-
+
/* Set the port to use */
SerialPortInfo.ComPort = Value;
KdpPort = Value;
{
PLIST_ENTRY CurrentEntry;
PKD_DISPATCH_TABLE CurrentTable;
-
+
/* Call the registered handlers */
CurrentEntry = KdProviders.Flink;
while (CurrentEntry != &KdProviders)
{
/* Get the current table */
- CurrentTable = CONTAINING_RECORD(CurrentEntry,
- KD_DISPATCH_TABLE,
+ CurrentTable = CONTAINING_RECORD(CurrentEntry,
+ KD_DISPATCH_TABLE,
KdProvidersList);
-
+
/* Call it */
CurrentTable->KdpInitRoutine(CurrentTable, BootPhase);
-
+
/* Next Table */
CurrentEntry = CurrentEntry->Flink;
}
-
+
/* Call the Wrapper Init Routine */
if (WrapperInitRoutine)
WrapperTable.KdpInitRoutine(&WrapperTable, BootPhase);
{
/* Initialize the Provider List */
InitializeListHead(&KdProviders);
-
+
/* Parse the Command Line */
p1 = (PCHAR)LoaderBlock->CommandLine;
while (p1 && (p2 = strchr(p1, '/')))
{
/* Move past the slash */
p2++;
-
+
/* Identify the Debug Type being Used */
if (!_strnicmp(p2, "DEBUGPORT=", 10))
{
p2 += 7;
KdDebuggerEnabled = FALSE;
}
- /* Check for Kernel Debugging Bypass unless STOP Error */
+ /* Check for Kernel Debugging Bypass unless STOP Error */
else if (!_strnicmp(p2, "CRASHDEBUG", 10))
{
/* Disable Debugging */
/* Get the Baud Rate */
p2 += 9;
Value = (ULONG)atol(p2);
-
+
/* Check if it's valid and Set it */
if (0 < Value) PortInfo.BaudRate = SerialPortInfo.BaudRate = Value;
}
/* Get the IRQ */
p2 += 3;
Value = (ULONG)atol(p2);
-
+
/* Check if it's valid and set it */
if (0 < Value) KdpPortIrq = Value;
}
-
+
/* Move to next */
p1 = p2;
- }
-
+ }
+
/* Call Providers at Phase 0 */
for (i = 0; i < KdMax; i++)
{
InitRoutines[i](&DispatchTable[i], 0);
}
-
+
/* Call Wrapper at Phase 0 */
if (WrapperInitRoutine) WrapperInitRoutine(&WrapperTable, 0);
/* GLOBALS *******************************************************************/
-#define BufferSize 32*1024
+#define BufferSize 32*1024
HANDLE KdbLogFileHandle;
BOOLEAN KdpLogInitialized;
CurrentPosition,
NULL,
NULL);
-
+
/* Clear the Current Position */
CurrentPosition = 0;
-
+
/* A new item can be queued now */
ItemQueued = FALSE;
}
KdpPrintToLog(PCH String)
{
ULONG StringLength = strlen(String);
-
+
/* Don't overflow */
if ((CurrentPosition + StringLength) > BufferSize) return;
-
+
/* Add the string to the buffer */
RtlMoveMemory(&DebugBuffer[CurrentPosition], String, StringLength);
-
+
/* Update the Current Position */
CurrentPosition += StringLength;
-
+
/* Make sure we are initialized and can queue */
if (!KdpLogInitialized || (ItemQueued)) return;
-
+
/* Queue the work item */
ExQueueWorkItem(&KdpDebugLogQueue, HyperCriticalWorkQueue);
ItemQueued = TRUE;
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING FileName;
- IO_STATUS_BLOCK Iosb;
-
+ IO_STATUS_BLOCK Iosb;
+
if (BootPhase == 0)
{
/* Write out the functions that we support for now */
DispatchTable->KdpInitRoutine = KdpInitDebugLog;
DispatchTable->KdpPrintRoutine = KdpPrintToLog;
-
+
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
}
0,
NULL,
NULL);
-
+
/* Create the Log File */
Status = NtCreateFile(&KdbLogFileHandle,
FILE_ALL_ACCESS,
FILE_WRITE_THROUGH | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
-
+
/* Allow it to be used */
ExInitializeWorkItem(&KdpDebugLogQueue, &KdpPrintToLogInternal, NULL);
KdpLogInitialized = TRUE;
/* Write out the functions that we support for now */
DispatchTable->KdpInitRoutine = KdpSerialInit;
DispatchTable->KdpPrintRoutine = KdpSerialDebugPrint;
-
+
/* Initialize the Port */
KdPortInitializeEx(&SerialPortInfo, 0, 0);
-
+
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
}
else if (BootPhase == 2)
{
HalDisplayString("\n Serial debugging enabled\n\n");
- }
+ }
}
/* SCREEN FUNCTIONS **********************************************************/
/* Write out the functions that we support for now */
DispatchTable->KdpInitRoutine = KdpScreenInit;
DispatchTable->KdpPrintRoutine = HalDisplayString;
-
+
/* Register as a Provider */
InsertTailList(&KdProviders, &DispatchTable->KdProvidersList);
}
else if (BootPhase == 2)
{
HalDisplayString("\n Screen debugging enabled\n\n");
- }
+ }
}
/* GENERAL FUNCTIONS *********************************************************/
case 3: ComPortBase = 0x3e8; break;
case 4: ComPortBase = 0x2e8; break;
}
-
+
/* search for this port address in DriverList */
for (i = 0; i < DriverList->List[0].PartialResourceList.Count; i++)
{
ResourceDescriptor = &DriverList->List[0].PartialResourceList.PartialDescriptors[i];
if (ResourceDescriptor->Type == CmResourceTypePort)
{
- if ((ResourceDescriptor->u.Port.Start.u.LowPart <= ComPortBase) &&
- (ResourceDescriptor->u.Port.Start.u.LowPart +
+ if ((ResourceDescriptor->u.Port.Start.u.LowPart <= ComPortBase) &&
+ (ResourceDescriptor->u.Port.Start.u.LowPart +
ResourceDescriptor->u.Port.Length > ComPortBase))
{
/* Conflict found */
}
}
}
-
+
/* No Conflicts */
return FALSE;
}
PCH pch = String->Buffer;
PLIST_ENTRY CurrentEntry;
PKD_DISPATCH_TABLE CurrentTable;
-
+
/* Call the registered handlers */
CurrentEntry = KdProviders.Flink;
while (CurrentEntry != &KdProviders)
{
/* Get the current table */
- CurrentTable = CONTAINING_RECORD(CurrentEntry,
+ CurrentTable = CONTAINING_RECORD(CurrentEntry,
KD_DISPATCH_TABLE,
KdProvidersList);
-
+
/* Call it */
CurrentTable->KdpPrintRoutine(pch);
-
+
/* Next Table */
CurrentEntry = CurrentEntry->Flink;
}
-
+
/* Call the Wrapper Routine */
if (WrapperInitRoutine) WrapperTable.KdpPrintRoutine(pch);
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/kd/kdinit.c
* PURPOSE: Kernel Debugger Initializtion
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
case 1: /* DbgPrint */
Result = KdpPrintString ((PANSI_STRING)Context1);
break;
-
+
case TAG('R', 'o', 's', ' '): /* ROS-INTERNAL */
{
switch ((ULONG)Context1)
{
- case DumpNonPagedPool:
+ case DumpNonPagedPool:
MiDebugDumpNonPagedPool(FALSE);
break;
-
+
case ManualBugCheck:
KEBUGCHECK(MANUALLY_INITIATED_CRASH);
break;
-
+
case DumpNonPagedPoolStats:
MiDebugDumpNonPagedPoolStats(FALSE);
break;
-
+
case DumpNewNonPagedPool:
MiDebugDumpNonPagedPool(TRUE);
break;
-
+
case DumpNewNonPagedPoolStats:
MiDebugDumpNonPagedPoolStats(TRUE);
break;
case DumpAllThreads:
PspDumpThreads(TRUE);
break;
-
+
case DumpUserThreads:
PspDumpThreads(FALSE);
break;
-
+
case EnterDebugger:
DbgBreakPoint();
break;
-
+
default:
break;
}
{
/* Get out of here if the Debugger isn't enabled */
if (!KdDebuggerEnabled) return kdHandleException;
-
+
/* FIXME:
* Right now, the GDB wrapper seems to handle exceptions differntly
* from KDGB and both are called at different times, while the GDB
{
/* Call the registered wrapper */
if (WrapperInitRoutine) return WrapperTable.
- KdpExceptionRoutine(ExceptionRecord,
+ KdpExceptionRoutine(ExceptionRecord,
Context,
TrapFrame);
}
-
+
/* Call KDBG if available */
return KdbEnterDebuggerException(ExceptionRecord,
PreviousMode,
KdDisableDebugger(VOID)
{
KIRQL OldIrql;
-
+
/* Raise IRQL */
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
-
+
/* TODO: Disable any breakpoints */
-
+
/* Disable the Debugger */
KdDebuggerEnabled = FALSE;
-
+
/* Lower the IRQL */
KeLowerIrql(OldIrql);
}
KdEnableDebugger(VOID)
{
KIRQL OldIrql;
-
+
/* Raise IRQL */
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
-
+
/* TODO: Re-enable any breakpoints */
-
+
/* Enable the Debugger */
KdDebuggerEnabled = TRUE;
-
+
/* Lower the IRQL */
KeLowerIrql(OldIrql);
}
/*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
KdPollBreakIn(VOID)
{
/*
* @implemented
*/
-VOID
+VOID
STDCALL
KeEnterKernelDebugger(VOID)
{
/* Set the Variable */
KdEnteredDebugger = TRUE;
-
+
/* Halt the CPU */
for (;;) Ke386HaltProcessor();
}
-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/kd/wrappers/bochs.c
* PURPOSE: BOCHS Wrapper for Kd
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
else if (BootPhase == 2)
{
HalDisplayString("\n Bochs debugging enabled\n\n");
- }
+ }
}
/* EOF */
#define EIP_REGNO 8
-typedef
-VOID
-STDCALL_FUNC
-(*PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine,
+typedef
+VOID
+STDCALL_FUNC
+(*PKSYSTEM_ROUTINE)(PKSTART_ROUTINE StartRoutine,
PVOID StartContext);
VOID
STDCALL
-KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
- PKSTART_ROUTINE StartRoutine,
- PVOID StartContext,
+KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
+ PKSTART_ROUTINE StartRoutine,
+ PVOID StartContext,
BOOLEAN UserThread,
KTRAP_FRAME TrapFrame);
-
+
static CPU_REGISTER GspRegisters[NUMREGS] =
{
{ 4, FIELD_OFFSET (KTRAP_FRAME_X86, Eax), FIELD_OFFSET (CONTEXT, Eax), TRUE },
{ 4, FIELD_OFFSET (KTRAP_FRAME_X86, Fs), FIELD_OFFSET (CONTEXT, SegFs), TRUE },
{ 4, FIELD_OFFSET (KTRAP_FRAME_X86, Gs), FIELD_OFFSET (CONTEXT, SegGs), TRUE }
};
-
+
static PCHAR GspThreadStates[DeferredReady+1] =
-{ "Initialized",
- "Ready",
+{ "Initialized",
+ "Ready",
"Running",
- "Standby",
- "Terminated",
+ "Standby",
+ "Terminated",
"Waiting",
- "Transition",
- "DeferredReady"
+ "Transition",
+ "DeferredReady"
};
char *
if (GspFindThread (ptr, &ThreadInfo))
{
PCHAR String = GspThreadStates[ThreadInfo->Tcb.State];
-
+
ObDereferenceObject(ThreadInfo);
-
+
GspMem2Hex (String, &GspOutBuffer[0], strlen (String), FALSE);
}
}
else
{
/* Don't switch threads */
-
+
/* Always use the current thread when entering the exception handler */
if (NULL != GspDbgThread)
{
if (GspInitialized)
{
ULONG Length;
-
+
GspOutBuffer[0] = 'O';
GspOutBuffer[1] = '\0';
strcat (&GspOutBuffer[0], Message);
}
/* Initialize the GDB stub */
-VOID
+VOID
STDCALL
KdpGdbStubInit(PKD_DISPATCH_TABLE WrapperTable,
ULONG BootPhase)
{
if (!KdDebuggerEnabled || !KdpDebugMode.Gdb) return;
-
+
if (BootPhase == 0)
{
/* Write out the functions that we support for now */
WrapperTable->KdpInitRoutine = KdpGdbStubInit;
WrapperTable->KdpPrintRoutine = KdpGdbDebugPrint;
WrapperTable->KdpExceptionRoutine = KdpGdbEnterDebuggerException;
-
+
/* Initialize the Port */
KdPortInitializeEx(&GdbPortInfo, 0, 0);
}
HalDisplayString("Waiting for GDB to attach\n");
DbgPrint("Module 'hal.dll' loaded at 0x%.08x.\n", LdrHalBase);
DbgBreakPointWithStatus (DBG_STATUS_CONTROL_C);
- }
+ }
else if (BootPhase == 2)
{
HalDisplayString("\n GDB debugging enabled\n\n");
/* Interface between the opcode library and its callers.
Copyright 2001, 2002 Free Software Foundation, Inc.
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
-
+
Written by Cygnus Support, 1993.
The opcode library (libopcodes.a) provides instruction decoders for
dis_dref2 /* Two data references in instruction */
};
-/* This struct is passed into the instruction decoding routine,
+/* This struct is passed into the instruction decoding routine,
and is passed back out into each callback. The various fields are used
for conveying information from your main routine into your callbacks,
for passing information into the instruction decoders (such as the
int bytes_per_chunk;
enum bfd_endian display_endian;
- /* Number of octets per incremented target address
+ /* Number of octets per incremented target address
Normally one, but some DSPs have byte sizes of 16 or 32 bits. */
unsigned int octets_per_byte;
extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
-extern int print_insn_s390 PARAMS ((bfd_vma, disassemble_info*));
+extern int print_insn_s390 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
extern int print_insn_tic4x PARAMS ((bfd_vma, disassemble_info*));
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/i386/i386-dis.c
} bfd_flavour;
typedef enum bfd_architecture
{
- bfd_arch_i386,
+ bfd_arch_i386,
} bfd_arch;
typedef unsigned int bfd_vma;
typedef unsigned char bfd_byte;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/kdbg/kdb.c
* PURPOSE: Kernel Debugger
- *
+ *
* PROGRAMMERS: Gregor Anich
*/
/* Get the protection for the address. */
Protect = MmGetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address));
-
+
/* Return if that page isn't present. */
if (Protect & PAGE_NOACCESS)
{
return STATUS_MEMORY_NOT_ALLOCATED;
}
-
+
/* Attach to the process */
if (CurrentProcess != Process)
{
MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address),
(Protect & ~(PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ)) | PAGE_READWRITE);
}
-
+
/* Copy the old instruction back to the caller. */
if (OldInst != NULL)
{
return Status;
}
}
-
+
/* Copy the new instruction in its place. */
Status = KdbpSafeWriteMemory((PUCHAR)Address, &NewInst, 1);
-
+
/* Restore the page protection. */
if (Protect & (PAGE_READONLY|PAGE_EXECUTE|PAGE_EXECUTE_READ))
{
MmSetPageProtect(Process, (PVOID)PAGE_ROUND_DOWN(Address), Protect);
}
-
+
/* Detach from process */
if (CurrentProcess != Process)
{
/*KdbpPrint("Couldn't access memory at 0x%x\n", (UINT)Idtr.Base + (IntVect * 8));*/
return FALSE;
}
-
+
/* Check descriptor and get target eip (16 bit interrupt/trap gates not supported) */
if ((IntDesc[1] & (1 << 15)) == 0) /* not present */
{
{
return FALSE;
}
-
+
bp = KdbBreakPoints + BreakPointNr;
if (Address != NULL)
*Address = bp->Address;
{
return STATUS_UNSUCCESSFUL;
}
-
+
/* Parse conditon expression string and duplicate it */
if (ConditionExpression != NULL)
{
}
}
ASSERT(i < RTL_NUMBER_OF(KdbBreakPoints));
-
+
/* Set the breakpoint */
ASSERT(KdbCurrentProcess != NULL);
KdbBreakPoints[i].Type = Type;
KdbBreakPoints[i].Data.Hw.AccessType = AccessType;
}
KdbBreakPointCount++;
-
+
if (Type != KdbBreakPointTemporary)
KdbpPrint("Breakpoint %d inserted.\n", i);
KdbpPrint("Breakpoint %d deleted.\n", BreakPointNr);
BreakPoint->Type = KdbBreakPointNone;
KdbBreakPointCount--;
-
+
return TRUE;
}
}
}
}
-
+
return -1;
}
KdbpPrint("Invalid breakpoint: %d\n", BreakPointNr);
return FALSE;
}
-
+
if (BreakPoint->Enabled == TRUE)
{
KdbpPrint("Breakpoint %d is already enabled.\n", BreakPointNr);
{
INT i;
NTSTATUS Status;
-
+
if (BreakPointNr < 0)
{
ASSERT(BreakPoint != NULL);
KdbpPrint("Couldn't restore original instruction.\n");
return FALSE;
}
-
+
for (i = 0; i < KdbSwBreakPointCount; i++)
{
if (KdbSwBreakPoints[i] == BreakPoint)
else
{
ASSERT(BreakPoint->Type == KdbBreakPointHardware);
-
+
/* Clear the breakpoint. */
KdbTrapFrame.Tf.Dr7 &= ~(0x3 << (BreakPoint->Data.Hw.DebugReg * 2));
if ((KdbTrapFrame.Tf.Dr7 & 0xFF) == 0)
KdbpPrint("Cannot attach to thread within another process while executing a DPC.\n");
return FALSE;
}
-
+
/* Save the current thread's context (if we previously attached to a thread) */
if (KdbCurrentThread != KdbOriginalThread)
{
*/
STATIC VOID
KdbpInternalEnter()
-{
+{
PETHREAD Thread;
PVOID SavedInitialStack, SavedStackBase, SavedKernelStack;
ULONG SavedStackLimit;
-
+
KbdDisableMouse();
if (KdpDebugMode.Screen)
{
{
Resume = TRUE; /* Set the resume flag when continuing execution */
}
-
+
/*
* When a temporary breakpoint is hit we have to make sure that we are
* in the same context in which it was set, otherwise it could happen
BreakPoint->Process == KdbCurrentProcess)
{
ASSERT((TrapFrame->Eflags & X86_EFLAGS_TF) == 0);
-
+
/*
* Delete the temporary breakpoint which was used to step over or into the instruction.
*/
TrapFrame->Eflags |= X86_EFLAGS_TF;
KdbBreakPointToReenable = BreakPoint;
}
-
+
/*
* Make sure that the breakpoint should be triggered in this context
*/
{
goto continue_execution; /* return */
}
-
+
/*
* Check if the condition for the breakpoint is met.
*/
}
}
}
-
+
/* Once we enter the debugger we do not expect any more single steps to happen */
KdbNumSingleSteps = 0;
-
+
/* Update the current process pointer */
KdbCurrentProcess = KdbOriginalProcess = PsGetCurrentProcess();
KdbCurrentThread = KdbOriginalThread = PsGetCurrentThread();
{
TrapFrame->Eflags |= X86_EFLAGS_RF;
}
-
+
/* Clear dr6 status flags. */
TrapFrame->Dr6 &= ~0x0000e00f;
KdbDeleteProcessHook(IN PEPROCESS Process)
{
KdbSymFreeProcessSymbols(Process);
-
+
/* FIXME: Delete breakpoints for process */
}
p2 += 8;
KdbDebugState |= KD_DEBUG_KDNOECHO;
}
-
+
p1 = p2;
}
}
KdbpDisassemble(
IN ULONG Address,
IN ULONG IntelSyntax);
-
+
LONG
KdbpGetInstLength(
IN ULONG Address);
KdbpSymFindModuleByIndex(IN INT Index,
OUT PKDB_MODULE_INFO pInfo);
-BOOLEAN
+BOOLEAN
KdbSymPrintAddress(IN PVOID Address);
NTSTATUS
IN PCHAR ConditionExpression OPTIONAL,
IN BOOLEAN Global,
OUT PULONG BreakPointNumber OPTIONAL);
-
+
BOOLEAN
KdbpDeleteBreakPoint(
IN LONG BreakPointNr OPTIONAL,
* UPDATE HISTORY:
* Created 16/01/2005
*/
-
+
/* INCLUDES ******************************************************************/
#include <ntoskrnl.h>
ErrMsg += 2;
KdbpPrint("%*s%s\n", ExpressionErrOffset, "", ErrMsg);
}
-
+
return Ok;
}
KdbpPrint("?: Argument required\n");
return TRUE;
}
-
+
/* Put the arguments back together */
Argc--;
for (i = 1; i < Argc; i++)
len = strlen(Argv[i]);
Argv[i][len] = ' ';
}
-
+
/* Evaluate the expression */
Ok = KdbpEvaluateExpression(Argv[1], sizeof("kdb:> ")-1 + (Argv[1]-Argv[0]), &Result);
if (Ok)
KdbpPrint("0x%08lx %10lu\n", ul, ul);
}
}
-
+
return TRUE;
}
{
ULONG Esp;
USHORT Ss;
-
+
if (!(Tf->Cs & 1))
{
Esp = (ULONG)Tf->TempEsp;
" PCE", " OSFXSR", " OSXMMEXCPT", NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-
+
Cr0 = KdbCurrentTrapFrame->Cr0;
Cr2 = KdbCurrentTrapFrame->Cr2;
Cr3 = KdbCurrentTrapFrame->Cr3;
/* Get the task register */
asm volatile("str %0" : "=g"(Tr));
-
+
/* Display the control registers */
KdbpPrint("CR0 0x%08x ", Cr0);
for (i = 0; i < 32; i++)
if ((Cr4 & (1 << i)) != 0)
KdbpPrint(Cr4Bits[i]);
}
-
+
/* Display the descriptor table regs */
KdbpPrint("\nGDTR Base 0x%08x Size 0x%04x\n", Gdtr.Base, Gdtr.Limit);
KdbpPrint("LDTR Base 0x%08x Size 0x%04x\n", Ldtr.Base, Ldtr.Limit);
break;
}
}
-
+
return TRUE;
}
KdbpCmdStep(ULONG Argc, PCHAR Argv[])
{
ULONG Count = 1;
-
+
if (Argc > 1)
{
Count = strtoul(Argv[1], NULL, 0);
return TRUE;
}
}
-
+
if (Argv[0][0] == 'n')
KdbSingleStepOver = TRUE;
else
KdbpPrint("No breakpoints.\n");
return TRUE;
}
-
+
KdbpPrint("Breakpoints:\n");
do
{
KDB_ACCESS_TYPE AccessType = 0;
INT AddressArgIndex, ConditionArgIndex, i;
BOOLEAN Global = TRUE;
-
+
if (Argv[0][2] == 'x') /* software breakpoint */
{
if (Argc < 2)
else /* memory breakpoint */
{
ASSERT(Argv[0][2] == 'm');
-
+
if (Argc < 2)
{
KdbpPrint("bpm: Access type argument required (one of r, w, rw, x)\n");
KdbpPrint("bpm: Unknown access type '%s'\n", Argv[1]);
return TRUE;
}
-
+
if (Argc < 3)
{
KdbpPrint("bpm: %s argument required.\n", AccessType == KdbAccessExec ? "Address" : "Memory size");
KdbpPrint("bpm: Unknown memory size '%s'\n", Argv[2]);
return TRUE;
}
-
+
if (Argc <= AddressArgIndex)
{
KdbpPrint("bpm: Address argument required.\n");
Type = KdbBreakPointHardware;
}
-
+
/* Put the arguments back together */
ConditionArgIndex = -1;
for (i = AddressArgIndex; i < (Argc-1); i++)
KdbpInsertBreakPoint(Address, Type, Size, AccessType,
(ConditionArgIndex < 0) ? NULL : Argv[ConditionArgIndex],
Global, NULL);
-
+
return TRUE;
}
if (Argc >= 2 && _stricmp(Argv[1], "list") == 0)
{
Process = KdbCurrentProcess;
-
+
if (Argc >= 3)
{
ul = strtoul(Argv[2], &pend, 0);
return TRUE;
}
}
-
+
Entry = Process->ThreadListHead.Flink;
if (Entry == &Process->ThreadListHead)
{
Ebp = (PULONG)Esp[4];
Eip = 0;
if (Ebp != NULL) /* FIXME: Should we attach to the process to read Ebp[1]? */
- KdbpSafeReadMemory(&Eip, Ebp + 1, sizeof (Eip));;
+ KdbpSafeReadMemory(&Eip, Ebp + 1, sizeof (Eip));
}
if (Thread->Tcb.State < (DeferredReady + 1))
State = ThreadStateToString[Thread->Tcb.State];
else
State = "Unknown";
-
+
KdbpPrint(" %s0x%08x %-11s %3d 0x%08x 0x%08x 0x%08x%s\n",
str1,
Thread->Cid.UniqueThread,
Ebp,
Eip,
str2);
-
+
Entry = Entry->Flink;
}
while (Entry != &Process->ThreadListHead);
return TRUE;
}
}
-
+
if (Thread->Tcb.State < (DeferredReady + 1))
State = ThreadStateToString[Thread->Tcb.State];
else
KdbpPrint("No processes in the system!\n");
return TRUE;
}
-
+
KdbpPrint(" PID State Filename\n");
do
{
State = ((Process->Pcb.State == PROCESS_STATE_TERMINATED) ? "Terminated" :
((Process->Pcb.State == PROCESS_STATE_ACTIVE) ? "Active" : "Unknown"));
-
+
KdbpPrint(" %s0x%08x %-10s %s%s\n",
str1,
Process->UniqueProcessId,
State,
Process->ImageFileName,
str2);
-
+
Entry = Entry->Flink;
}
while(Entry != &PsActiveProcessHead);
if (Result > (ULONGLONG)(~((ULONG_PTR)0)))
KdbpPrint("%s: Warning: Address %I64x is beeing truncated\n", Argv[0]);
Address = (ULONG_PTR)Result;
-
+
if (!KdbpSymFindModuleByAddress((PVOID)Address, &Info))
{
KdbpPrint("No module containing address 0x%x found!\n", Address);
i = 0;
ul = 1 << 2;
}
-
+
if (Reg.Limit < 7)
{
KdbpPrint("%s descriptor table is empty.\n",
}
}
}
-
+
return TRUE;
}
Pcr->MajorVersion, Pcr->MinorVersion, Pcr->SetMember, Pcr->StallScaleFactor,
Pcr->DebugActive, Pcr->ProcessorNumber, Pcr->L2CacheAssociativity,
Pcr->VdmAlert, Pcr->L2CacheSize, Pcr->InterruptMode);
-
+
return TRUE;
}
if (!TerminalInitialized)
{
DbgPrint("\x1b[7h"); /* Enable linewrap */
-
+
/* Query terminal type */
/*DbgPrint("\x1b[Z");*/
DbgPrint("\x05");
-
+
TerminalInitialized = TRUE;
Length = 0;
for (;;)
while (p[0] != '\0')
{
i = strcspn(p, "\n");
-
+
/* Calculate the number of lines which will be printed in the terminal
* when outputting the current line
*/
RowsPrintedByTerminal = 0;
if (p[i] == '\n')
RowsPrintedByTerminal++;
-
+
/*DbgPrint("!%d!%d!%d!%d!", KdbNumberOfRowsPrinted, KdbNumberOfColsPrinted, i, RowsPrintedByTerminal);*/
/* Display a prompt if we printed one screen full of text */
{
c = '\0';
}
-
+
/* Remove escape sequences from the line if there's no terminal connected */
if (!TerminalConnected)
{
LONG Length2 = 0;
INT i;
PCHAR Buffer;
-
+
ASSERT(Length1 <= RTL_NUMBER_OF(KdbCommandHistoryBuffer));
if (Length1 <= 1 ||
p++;
if (*p == '\0')
break;
-
+
i = strcspn(p, "\t ");
Argv[Argc++] = p;
p += i;
/* Read a command and remember it */
KdbpReadCommand(Command, sizeof (Command));
KdbpCommandHistoryAppend(Command);
-
+
/* Reset the number of rows/cols printed and output aborted state */
KdbNumberOfRowsPrinted = KdbNumberOfColsPrinted = 0;
KdbOutputAborted = FALSE;
-
+
/* Call the command */
Continue = KdbpDoCommand(Command);
} while (Continue);
{
KdbpDoCommand(p1);
}
-
+
p1[i] = c;
}
p1 += i;
/* Initialize the object attributes */
RtlInitUnicodeString(&FileName, L"\\SystemRoot\\system32\\drivers\\etc\\KDBinit");
InitializeObjectAttributes(&ObjectAttributes, &FileName, 0, NULL, NULL);
-
+
/* Open the file */
Status = ZwOpenFile(&hFile, FILE_READ_DATA, &ObjectAttributes, &Iosb, 0,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
case RpnOpNop:
DbgPrint("NOP,");
break;
-
+
case RpnOpImmediate:
DbgPrint("0x%I64x,", Op->Data.Immediate);
break;
-
+
case RpnOpBinaryOperator:
if (Op->Data.BinaryOperator == RpnBinaryOperatorAdd)
DbgPrint("+,");
else
DbgPrint("UNKNOWN OP,");
break;
-
+
case RpnOpRegister:
DbgPrint("%s,", RegisterToTrapFrame[Op->Data.Register].Name);
break;
-
+
case RpnOpDereference:
DbgPrint("[%s],",
(Op->Data.DerefMemorySize == 1) ? ("byte") :
)
);
break;
-
+
default:
DbgPrint("\nUnsupported Type: %d\n", Op->Type);
ul = Stack->Sp;
p++;
CharacterOffset++;
}
-
+
/* Check for end of expression */
if (p[0] == '\0' || p[0] == ')' || p[0] == ']')
break;
{
/* Remember operator */
Operator = p++;
- OperatorOffset = CharacterOffset++;;
-
+ OperatorOffset = CharacterOffset++;
+
/* Pop operator (to get the right operator precedence) */
HavePoppedOperator = FALSE;
if (*Operator == '*' || *Operator == '/' || *Operator == '%')
*ErrOffset = CharacterOffset;
return FALSE;
}
-
+
p += i;
CharacterOffset += i;
goto get_operand;
/* Skip closing brace/bracket */
pend++;
-
+
CharacterOffset += pend - p;
p = pend;
}
IsComparativeOp = TRUE;
RpnOp.Data.BinaryOperator = RpnBinaryOperatorEquals;
break;
-
+
case '!':
ASSERT(Operator[1] == '=');
IsComparativeOp = TRUE;
}
}
}
-
+
First = FALSE;
}
-
+
//end_of_expression:
if (ComparativeOpFilled && !RpnpPushStack(Stack, &ComparativeOp))
if (End != NULL)
*End = p;
-
+
return TRUE;
}
case RpnOpNop:
/* No operation */
break;
-
+
case RpnOpImmediate:
if (ValueStackPointer == RPN_VALUE_STACK_SIZE)
{
*ErrOffset = -1;
return FALSE;
}
-
+
*Result = ValueStack[0];
return TRUE;
}
OUT PCHAR ErrMsg OPTIONAL)
{
PRPN_STACK Stack = (PRPN_STACK)&RpnStack;
-
+
ASSERT(Expression != NULL);
ASSERT(TrapFrame != NULL);
ASSERT(Result != NULL);
}
memcpy(NewStack, Stack, Size);
NewStack->Size = NewStack->Sp;
-
+
return NewStack;
}
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb_keyboard.c
* PURPOSE: Keyboard driver
- *
+ *
* PROGRAMMERS: Victor Kirhenshtein (sauros@iname.com)
* Jason Filby (jasonfilby@yahoo.com)
*/
#if 1
-#define KBD_STATUS_REG 0x64
-#define KBD_CNTL_REG 0x64
-#define KBD_DATA_REG 0x60
+#define KBD_STATUS_REG 0x64
+#define KBD_CNTL_REG 0x64
+#define KBD_DATA_REG 0x60
#define KBD_DISABLE_MOUSE 0xA7
#define KBD_ENABLE_MOUSE 0xA8
}
}
}
-
+
return -1;
}
#define K_TIMEOUT 0x40 /* timout error flag */
#define K_PARITY_ERROR 0x80 /* parity error flag */
-/*
+/*
* Keyboard controller commands (sent to K_CMD port).
*/
#define KC_CMD_READ 0x20 /* read controller command byte */
#define KC_CMD_ECHO 0xee /* used for diagnostic testing */
#define KC_CMD_PULSE 0xff /* pulse bits 3-0 based on low nybble */
-/*
+/*
* Keyboard commands (send to K_RDWR).
*/
#define K_CMD_LEDS 0xed /* set status LEDs (caps lock, etc.) */
#define K_CMD_TYPEMATIC 0xf3 /* set key repeat and delay */
-/*
- * Bit definitions for controller command byte (sent following
+/*
+ * Bit definitions for controller command byte (sent following
* KC_CMD_WRITE command).
*
* Bits 0x02 and 0x80 unused, always set to 0.
#define K_CB_IGNPARITY 0x20 /* ignore parity from keyboard */
#define K_CB_SCAN 0x40 /* standard scan conversion */
-/*
- * Bit definitions for "Indicator Status Byte" (sent after a
- * K_CMD_LEDS command). If the bit is on, the LED is on. Undefined
+/*
+ * Bit definitions for "Indicator Status Byte" (sent after a
+ * K_CMD_LEDS command). If the bit is on, the LED is on. Undefined
* bit positions must be 0.
*/
#define K_LED_SCRLLK 0x1 /* scroll lock */
#define K_LED_NUMLK 0x2 /* num lock */
#define K_LED_CAPSLK 0x4 /* caps lock */
-/*
+/*
* Bit definitions for "Miscellaneous port B" (K_PORTB).
*/
/* read/write */
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb_serial.c
* PURPOSE: Serial driver
- *
+ *
* PROGRAMMERS: Victor Kirhenshtein (sauros@iname.com)
* Jason Filby (jasonfilby@yahoo.com)
* arty
-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/dbg/kdb_symbols.c
* PURPOSE: Getting symbol information...
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/apc.c
* PURPOSE: NT Implementation of APCs
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* Phillip Susi
*/
/* FUNCTIONS *****************************************************************/
/*++
- * KiKernelApcDeliveryCheck
+ * KiKernelApcDeliveryCheck
* @implemented NT 5.2
*
* The KiKernelApcDeliveryCheck routine is called whenever APCs have just
}
/*++
- * KeEnterCriticalRegion
+ * KeEnterCriticalRegion
* @implemented NT4
*
- * The KeEnterCriticalRegion routine temporarily disables the delivery of
+ * The KeEnterCriticalRegion routine temporarily disables the delivery of
* normal kernel APCs; special kernel-mode APCs are still delivered.
*
* Params:
*
* Remarks:
* Highest-level drivers can call this routine while running in the context
- * of the thread that requested the current I/O operation. Any caller of
+ * of the thread that requested the current I/O operation. Any caller of
* this routine should call KeLeaveCriticalRegion as quickly as possible.
*
* Callers of KeEnterCriticalRegion must be running at IRQL <= APC_LEVEL.
*
*--*/
#undef KeEnterCriticalRegion
-VOID
-STDCALL
+VOID
+STDCALL
KeEnterCriticalRegion(VOID)
{
/* Disable Kernel APCs */
}
/*++
- * KeLeaveCriticalRegion
+ * KeLeaveCriticalRegion
* @implemented NT4
*
- * The KeLeaveCriticalRegion routine reenables the delivery of normal
+ * The KeLeaveCriticalRegion routine reenables the delivery of normal
* kernel-mode APCs that were disabled by a call to KeEnterCriticalRegion.
*
* Params:
*
* Remarks:
* Highest-level drivers can call this routine while running in the context
- * of the thread that requested the current I/O operation.
+ * of the thread that requested the current I/O operation.
*
* Callers of KeLeaveCriticalRegion must be running at IRQL <= DISPATCH_LEVEL.
*
*--*/
#undef KeLeaveCriticalRegion
-VOID
-STDCALL
+VOID
+STDCALL
KeLeaveCriticalRegion (VOID)
{
- PKTHREAD Thread = KeGetCurrentThread();
+ PKTHREAD Thread = KeGetCurrentThread();
/* Check if Kernel APCs are now enabled */
- if((Thread) && (++Thread->KernelApcDisable == 0))
- {
+ if((Thread) && (++Thread->KernelApcDisable == 0))
+ {
/* Check if we need to request an APC Delivery */
- if (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
- {
+ if (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode]))
+ {
/* Check for the right environment */
KiKernelApcDeliveryCheck();
- }
- }
+ }
+ }
}
/*++
- * KeInitializeApc
+ * KeInitializeApc
* @implemented NT4
*
* The The KeInitializeApc routine initializes an APC object, and registers
* the Kernel, Rundown and Normal routines for that object.
*
* Params:
- * Apc - Pointer to a KAPC structure that represents the APC object to
+ * Apc - Pointer to a KAPC structure that represents the APC object to
* initialize. The caller must allocate storage for the structure
* from resident memory.
*
*
* Mode - Specifies the processor mode at which to run the Normal Routine.
*
- * Context - Specifices the value to pass as Context parameter to the
+ * Context - Specifices the value to pass as Context parameter to the
* registered routines.
*
* Returns:
* Remarks:
* The caller can queue an initialized APC with KeInsertQueueApc.
*
- * Storage for the APC object must be resident, such as nonpaged pool
+ * Storage for the APC object must be resident, such as nonpaged pool
* allocated by the caller.
*
* Callers of this routine must be running at IRQL = PASSIVE_LEVEL.
RtlZeroMemory(Apc, sizeof(KAPC));
Apc->Type = ApcObject;
Apc->Size = sizeof(KAPC);
-
+
/* Set the Environment */
if (TargetEnvironment == CurrentApcEnvironment) {
-
+
Apc->ApcStateIndex = Thread->ApcStateIndex;
-
+
} else {
-
+
Apc->ApcStateIndex = TargetEnvironment;
}
-
+
/* Set the Thread and Routines */
Apc->Thread = Thread;
Apc->KernelRoutine = KernelRoutine;
Apc->RundownRoutine = RundownRoutine;
Apc->NormalRoutine = NormalRoutine;
-
+
/* Check if this is a Special APC, in which case we use KernelMode and no Context */
if (ARGUMENT_PRESENT(NormalRoutine)) {
-
+
Apc->ApcMode = Mode;
Apc->NormalContext = Context;
-
+
} else {
-
+
Apc->ApcMode = KernelMode;
- }
+ }
}
/*++
- * KiInsertQueueApc
+ * KiInsertQueueApc
*
* The KiInsertQueueApc routine queues a APC for execution when the right
* scheduler environment exists.
*
* Params:
* Apc - Pointer to an initialized control object of type DPC for which the
- * caller provides the storage.
+ * caller provides the storage.
*
* PriorityBoost - Priority Boost to apply to the Thread.
*
PKTHREAD Thread = Apc->Thread;
PLIST_ENTRY ApcListEntry;
PKAPC QueuedApc;
-
+
/* Don't do anything if the APC is already inserted */
if (Apc->Inserted) {
-
+
return FALSE;
}
-
- /* Three scenarios:
+
+ /* Three scenarios:
1) Kernel APC with Normal Routine or User APC = Put it at the end of the List
2) User APC which is PsExitSpecialApc = Put it at the front of the List
3) Kernel APC without Normal Routine = Put it at the end of the No-Normal Routine Kernel APC list
*/
if ((Apc->ApcMode != KernelMode) && (Apc->KernelRoutine == (PKKERNEL_ROUTINE)PsExitSpecialApc)) {
-
+
DPRINT ("Inserting the Process Exit APC into the Queue\n");
Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = TRUE;
InsertHeadList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
&Apc->ApcListEntry);
-
+
} else if (Apc->NormalRoutine == NULL) {
-
+
DPRINT ("Inserting Special APC %x into the Queue\n", Apc);
-
+
for (ApcListEntry = Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode].Flink;
ApcListEntry != &Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode];
ApcListEntry = ApcListEntry->Flink) {
QueuedApc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
if (Apc->NormalRoutine != NULL) break;
}
-
+
/* We found the first "Normal" APC, so write right before it */
ApcListEntry = ApcListEntry->Blink;
InsertHeadList(ApcListEntry, &Apc->ApcListEntry);
-
+
} else {
-
+
DPRINT ("Inserting Normal APC %x into the %x Queue\n", Apc, Apc->ApcMode);
InsertTailList(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode],
&Apc->ApcListEntry);
}
-
- /* Confirm Insertion */
+
+ /* Confirm Insertion */
Apc->Inserted = TRUE;
/*
* 1) Kernel APC, The thread is Running: Request an Interrupt
* 2) Kernel APC, The Thread is Waiting at PASSIVE_LEVEL and APCs are enabled and not in progress: Unwait the Thread
* 3) User APC, Unwait the Thread if it is alertable
- */
- if (Apc->ApcMode == KernelMode) {
-
+ */
+ if (Apc->ApcMode == KernelMode) {
+
/* Set Kernel APC pending */
Thread->ApcState.KernelApcPending = TRUE;
-
+
/* Check the Thread State */
- if (Thread->State == Running) {
-
+ if (Thread->State == Running) {
+
/* FIXME: Use IPI */
DPRINT ("Requesting APC Interrupt for Running Thread \n");
HalRequestSoftwareInterrupt(APC_LEVEL);
-
+
} else if ((Thread->State == Waiting) && (Thread->WaitIrql == PASSIVE_LEVEL) &&
- ((Apc->NormalRoutine == NULL) ||
+ ((Apc->NormalRoutine == NULL) ||
((!Thread->KernelApcDisable) && (!Thread->ApcState.KernelApcInProgress)))) {
-
+
DPRINT("Waking up Thread for Kernel-Mode APC Delivery \n");
KiAbortWaitThread(Thread, STATUS_KERNEL_APC, PriorityBoost);
}
-
- } else if ((Thread->State == Waiting) &&
- (Thread->WaitMode == UserMode) &&
+
+ } else if ((Thread->State == Waiting) &&
+ (Thread->WaitMode == UserMode) &&
(Thread->Alertable)) {
-
+
DPRINT("Waking up Thread for User-Mode APC Delivery \n");
Thread->ApcState.UserApcPending = TRUE;
KiAbortWaitThread(Thread, STATUS_USER_APC, PriorityBoost);
}
-
+
return TRUE;
}
-
+
/*++
- * KeInsertQueueApc
+ * KeInsertQueueApc
* @implemented NT4
*
* The KeInsertQueueApc routine queues a APC for execution when the right
*
* Params:
* Apc - Pointer to an initialized control object of type DPC for which the
- * caller provides the storage.
+ * caller provides the storage.
*
* SystemArgument[1,2] - Pointer to a set of two parameters that contain
* untyped data.
KIRQL OldIrql;
PKTHREAD Thread;
BOOLEAN Inserted;
-
+
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
DPRINT("KeInsertQueueApc(Apc %x, SystemArgument1 %x, "
"SystemArgument2 %x)\n",Apc,SystemArgument1,
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Get the Thread specified in the APC */
Thread = Apc->Thread;
-
+
/* Make sure the thread allows APC Queues.
* The thread is not apc queueable, for instance, when it's (about to be) terminated.
*/
KeReleaseDispatcherDatabaseLock(OldIrql);
return FALSE;
}
-
+
/* Set the System Arguments */
Apc->SystemArgument1 = SystemArgument1;
Apc->SystemArgument2 = SystemArgument2;
}
/*++
- * KeRemoveQueueApc
+ * KeRemoveQueueApc
*
- * The KeRemoveQueueApc routine removes a given APC object from the system
+ * The KeRemoveQueueApc routine removes a given APC object from the system
* APC queue.
*
* Params:
* Callers of KeLeaveCriticalRegion can be running at any IRQL.
*
*--*/
-BOOLEAN
+BOOLEAN
STDCALL
KeRemoveQueueApc(PKAPC Apc)
{
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
DPRINT("KeRemoveQueueApc called for APC: %x \n", Apc);
-
+
OldIrql = KeAcquireDispatcherDatabaseLock();
KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
-
+
/* Check if it's inserted */
if (Apc->Inserted) {
-
+
/* Remove it from the Queue*/
RemoveEntryList(&Apc->ApcListEntry);
Apc->Inserted = FALSE;
-
+
/* If the Queue is completely empty, then no more APCs are pending */
if (IsListEmpty(&Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->ApcListHead[(int)Apc->ApcMode])) {
-
+
/* Set the correct State based on the Apc Mode */
if (Apc->ApcMode == KernelMode) {
-
+
Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->KernelApcPending = FALSE;
-
+
} else {
-
+
Thread->ApcStatePointer[(int)Apc->ApcStateIndex]->UserApcPending = FALSE;
}
}
-
+
} else {
-
+
/* It's not inserted, fail */
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
KeReleaseDispatcherDatabaseLock(OldIrql);
return(FALSE);
}
-
+
/* Restore IRQL and Return */
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
KeReleaseDispatcherDatabaseLock(OldIrql);
}
/*++
- * KiDeliverApc
+ * KiDeliverApc
* @implemented @NT4
- *
+ *
* The KiDeliverApc routine is called from IRQL switching code if the
* thread is returning from an IRQL >= APC_LEVEL and Kernel-Mode APCs are
- * pending.
+ * pending.
*
* Params:
* DeliveryMode - Specifies the current processor mode.
* Upon entry, this routine executes at APC_LEVEL.
*
*--*/
-VOID
+VOID
STDCALL
KiDeliverApc(KPROCESSOR_MODE DeliveryMode,
PVOID Reserved,
PKNORMAL_ROUTINE NormalRoutine;
PVOID SystemArgument1;
PVOID SystemArgument2;
-
+
ASSERT_IRQL_EQUAL(APC_LEVEL);
/* Lock the APC Queue and Raise IRQL to Synch */
/* Clear APC Pending */
Thread->ApcState.KernelApcPending = FALSE;
-
+
/* Do the Kernel APCs first */
while (!IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) {
-
+
/* Get the next Entry */
ApcListEntry = Thread->ApcState.ApcListHead[KernelMode].Flink;
Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
-
+
/* Save Parameters so that it's safe to free the Object in Kernel Routine*/
NormalRoutine = Apc->NormalRoutine;
KernelRoutine = Apc->KernelRoutine;
NormalContext = Apc->NormalContext;
SystemArgument1 = Apc->SystemArgument1;
SystemArgument2 = Apc->SystemArgument2;
-
+
/* Special APC */
if (NormalRoutine == NULL) {
-
+
/* Remove the APC from the list */
Apc->Inserted = FALSE;
RemoveEntryList(ApcListEntry);
-
+
/* Go back to APC_LEVEL */
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-
+
/* Call the Special APC */
DPRINT("Delivering a Special APC: %x\n", Apc);
KernelRoutine(Apc,
/* Raise IRQL and Lock again */
KeAcquireSpinLock(&Thread->ApcQueueLock, &OldIrql);
-
+
} else {
-
+
/* Normal Kernel APC */
if (Thread->ApcState.KernelApcInProgress || Thread->KernelApcDisable) {
-
+
/*
* DeliveryMode must be KernelMode in this case, since one may not
- * return to umode while being inside a critical section or while
+ * return to umode while being inside a critical section or while
* a regular kmode apc is running (the latter should be impossible btw).
* -Gunnar
*/
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
return;
}
-
+
/* Dequeue the APC */
RemoveEntryList(ApcListEntry);
Apc->Inserted = FALSE;
-
+
/* Go back to APC_LEVEL */
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
-
+
/* Call the Kernel APC */
DPRINT("Delivering a Normal APC: %x\n", Apc);
KernelRoutine(Apc,
&NormalContext,
&SystemArgument1,
&SystemArgument2);
-
+
/* If There still is a Normal Routine, then we need to call this at PASSIVE_LEVEL */
if (NormalRoutine != NULL) {
-
+
/* At Passive Level, this APC can be prempted by a Special APC */
Thread->ApcState.KernelApcInProgress = TRUE;
KeLowerIrql(PASSIVE_LEVEL);
-
+
/* Call and Raise IRQ back to APC_LEVEL */
DPRINT("Calling the Normal Routine for a Normal APC: %x\n", Apc);
NormalRoutine(&NormalContext, &SystemArgument1, &SystemArgument2);
Thread->ApcState.KernelApcInProgress = FALSE;
}
}
-
+
/* Now we do the User APCs */
if ((!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode])) &&
(DeliveryMode == UserMode) && (Thread->ApcState.UserApcPending == TRUE)) {
-
+
/* It's not pending anymore */
Thread->ApcState.UserApcPending = FALSE;
/* Get the APC Object */
ApcListEntry = Thread->ApcState.ApcListHead[UserMode].Flink;
Apc = CONTAINING_RECORD(ApcListEntry, KAPC, ApcListEntry);
-
+
/* Save Parameters so that it's safe to free the Object in Kernel Routine*/
NormalRoutine = Apc->NormalRoutine;
KernelRoutine = Apc->KernelRoutine;
NormalContext = Apc->NormalContext;
SystemArgument1 = Apc->SystemArgument1;
- SystemArgument2 = Apc->SystemArgument2;
-
+ SystemArgument2 = Apc->SystemArgument2;
+
/* Remove the APC from Queue, restore IRQL and call the APC */
RemoveEntryList(ApcListEntry);
Apc->Inserted = FALSE;
-
+
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
DPRINT("Calling the Kernel Routine for for a User APC: %x\n", Apc);
KernelRoutine(Apc,
&SystemArgument2);
if (NormalRoutine == NULL) {
-
+
/* Check if more User APCs are Pending */
KeTestAlertThread(UserMode);
-
+
} else {
-
+
/* Set up the Trap Frame and prepare for Execution in NTDLL.DLL */
DPRINT("Delivering a User APC: %x\n", Apc);
- KiInitializeUserApc(Reserved,
+ KiInitializeUserApc(Reserved,
TrapFrame,
NormalRoutine,
NormalContext,
SystemArgument1,
SystemArgument2);
}
-
+
} else {
-
+
/* Go back to APC_LEVEL */
KeReleaseSpinLock(&Thread->ApcQueueLock, OldIrql);
}
}
-VOID
+VOID
STDCALL
KiFreeApcRoutine(PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
}
/*++
- * KiInitializeUserApc
- *
+ * KiInitializeUserApc
+ *
* Prepares the Context for a User-Mode APC called through NTDLL.DLL
*
* Params:
IN PKNORMAL_ROUTINE NormalRoutine,
IN PVOID NormalContext,
IN PVOID SystemArgument1,
- IN PVOID SystemArgument2)
+ IN PVOID SystemArgument2)
{
PCONTEXT Context;
PULONG Esp;
DPRINT("KiInitializeUserApc(TrapFrame %x/%x)\n", TrapFrame, KeGetCurrentThread()->TrapFrame);
-
+
/*
* Save the thread's current context (in other words the registers
* that will be restored when it returns to user mode) so the
Context->EFlags = TrapFrame->Eflags;
Context->Esp = TrapFrame->Esp;
Context->SegSs = TrapFrame->Ss;
-
+
/*
* Setup the trap frame so the thread will start executing at the
* APC Dispatcher when it returns to user-mode
}
/*++
- * KeAreApcsDisabled
+ * KeAreApcsDisabled
* @implemented NT4
- *
+ *
* Prepares the Context for a User-Mode APC called through NTDLL.DLL
*
* Params:
* or a guarded region, and FALSE otherwise.
*
* Remarks:
- * A thread running at IRQL = PASSIVE_LEVEL can use KeAreApcsDisabled to
- * determine if normal kernel APCs are disabled. A thread that is inside a
- * critical region has both user APCs and normal kernel APCs disabled, but
- * not special kernel APCs. A thread that is inside a guarded region has
+ * A thread running at IRQL = PASSIVE_LEVEL can use KeAreApcsDisabled to
+ * determine if normal kernel APCs are disabled. A thread that is inside a
+ * critical region has both user APCs and normal kernel APCs disabled, but
+ * not special kernel APCs. A thread that is inside a guarded region has
* all APCs disabled, including special kernel APCs.
*
* Callers of this routine must be running at IRQL <= APC_LEVEL.
}
/*++
- * NtQueueApcThread
+ * NtQueueApcThread
* NT4
- *
- * This routine is used to queue an APC from user-mode for the specified
+ *
+ * This routine is used to queue an APC from user-mode for the specified
* thread.
*
* Params:
* STATUS_SUCCESS or failure cute from associated calls.
*
* Remarks:
- * The thread must enter an alertable wait before the APC will be
+ * The thread must enter an alertable wait before the APC will be
* delivered.
*
*--*/
-NTSTATUS
+NTSTATUS
STDCALL
NtQueueApcThread(HANDLE ThreadHandle,
PKNORMAL_ROUTINE ApcRoutine,
PreviousMode,
(PVOID)&Thread,
NULL);
-
+
/* Fail if the Handle is invalid for some reason */
if (!NT_SUCCESS(Status)) {
-
+
return(Status);
}
-
+
/* If this is a Kernel or System Thread, then fail */
if (Thread->Tcb.Teb == NULL) {
-
+
ObDereferenceObject(Thread);
return STATUS_INVALID_HANDLE;
}
-
+
/* Allocate an APC */
Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG('P', 's', 'a', 'p'));
if (Apc == NULL) {
-
+
ObDereferenceObject(Thread);
return(STATUS_NO_MEMORY);
}
-
+
/* Initialize and Queue a user mode apc (always!) */
KeInitializeApc(Apc,
&Thread->Tcb,
ApcRoutine,
UserMode,
NormalContext);
-
+
if (!KeInsertQueueApc(Apc, SystemArgument1, SystemArgument2, IO_NO_INCREMENT)) {
-
+
Status = STATUS_UNSUCCESSFUL;
-
+
} else {
-
+
Status = STATUS_SUCCESS;
}
-
+
/* Dereference Thread and Return */
ObDereferenceObject(Thread);
return Status;
}
-static inline
-VOID RepairList(PLIST_ENTRY Original,
+static inline
+VOID RepairList(PLIST_ENTRY Original,
PLIST_ENTRY Copy,
KPROCESSOR_MODE Mode)
{
/* Copy Source to Desination */
if (IsListEmpty(&Original[(int)Mode])) {
-
+
InitializeListHead(&Copy[(int)Mode]);
-
+
} else {
-
- Copy[(int)Mode].Flink = Original[(int)Mode].Flink;
+
+ Copy[(int)Mode].Flink = Original[(int)Mode].Flink;
Copy[(int)Mode].Blink = Original[(int)Mode].Blink;
Original[(int)Mode].Flink->Blink = &Copy[(int)Mode];
Original[(int)Mode].Blink->Flink = &Copy[(int)Mode];
{
/* Restore backup of Original Environment */
*NewState = *OldState;
-
+
/* Repair Lists */
RepairList(NewState->ApcListHead, OldState->ApcListHead, KernelMode);
RepairList(NewState->ApcListHead, OldState->ApcListHead, UserMode);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/bug.c
* PURPOSE: Graceful system shutdown if a bug is detected
- *
+ *
* PROGRAMMERS: Alex Ionescu - Rewrote Bugcheck Routines and implemented Reason Callbacks.
* David Welch (welch@cwcom.net)
* Phillip Susi
ResourceInfo.Type = 11;
ResourceInfo.Name = 1;
ResourceInfo.Language = 9;
-
+
/* Do the lookup. */
Status = LdrFindResource_U((PVOID)KERNEL_BASE,
&ResourceInfo,
RESOURCE_DATA_LEVEL,
&ResourceDataEntry);
-
+
/* Make sure it worked */
if (NT_SUCCESS(Status)) {
-
+
DPRINT1("Found Bugcheck Resource Data!\n");
-
+
/* Now actually get a pointer to it */
Status = LdrAccessResource((PVOID)KERNEL_BASE,
ResourceDataEntry,
(PVOID*)&BugCheckData,
NULL);
-
+
/* Make sure it worked */
if (NT_SUCCESS(Status)) {
/*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
KeDeregisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord)
{
KIRQL OldIrql;
BOOLEAN Status = FALSE;
-
+
/* Raise IRQL to High */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
+
/* Check the Current State */
if (CallbackRecord->State == BufferInserted) {
/* Reset state and remove from list */
CallbackRecord->State = BufferEmpty;
RemoveEntryList(&CallbackRecord->Entry);
-
+
Status = TRUE;
}
{
KIRQL OldIrql;
BOOLEAN Status = FALSE;
-
+
/* Raise IRQL to High */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
+
/* Check the Current State */
if (CallbackRecord->State == BufferInserted) {
/* Reset state and remove from list */
CallbackRecord->State = BufferEmpty;
RemoveEntryList(&CallbackRecord->Entry);
-
+
Status = TRUE;
}
/*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine,
{
KIRQL OldIrql;
BOOLEAN Status = FALSE;
-
+
/* Raise IRQL to High */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
+
/* Check the Current State first so we don't double-register */
if (CallbackRecord->State == BufferEmpty) {
-
+
/* Set the Callback Settings and insert into the list */
CallbackRecord->Length = Length;
CallbackRecord->Buffer = Buffer;
CallbackRecord->CallbackRoutine = CallbackRoutine;
CallbackRecord->State = BufferInserted;
InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry);
-
+
Status = TRUE;
}
{
KIRQL OldIrql;
BOOLEAN Status = FALSE;
-
+
/* Raise IRQL to High */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
+
/* Check the Current State first so we don't double-register */
if (CallbackRecord->State == BufferEmpty) {
-
+
/* Set the Callback Settings and insert into the list */
CallbackRecord->Component = Component;
CallbackRecord->CallbackRoutine = CallbackRoutine;
CallbackRecord->State = BufferInserted;
CallbackRecord->Reason = Reason;
InsertTailList(&BugcheckReasonCallbackListHead, &CallbackRecord->Entry);
-
+
Status = TRUE;
}
ULONG IdOffset;
ULONG_PTR MessageEntry;
PCHAR BugCode;
-
+
/* Find the message. This code is based on RtlFindMesssage -- Alex */
for (i = 0; i < KiBugCodeMessages->NumberOfBlocks; i++) {
-
+
/* Check if the ID Matches */
if ((BugCheckCode >= KiBugCodeMessages->Blocks[i].LowId) &&
(BugCheckCode <= KiBugCodeMessages->Blocks[i].HighId)) {
-
+
/* Get Offset to Entry */
MessageEntry = (ULONG_PTR)KiBugCodeMessages + KiBugCodeMessages->Blocks[i].OffsetToEntries;
IdOffset = BugCheckCode - KiBugCodeMessages->Blocks[i].LowId;
-
+
/* Get offset to ID */
for (i = 0; i < IdOffset; i++) {
-
- /* Advance in the Entries */
+
+ /* Advance in the Entries */
MessageEntry += ((PRTL_MESSAGE_RESOURCE_ENTRY)MessageEntry)->Length;
}
-
+
/* Get the final Code */
BugCode = ((PRTL_MESSAGE_RESOURCE_ENTRY)MessageEntry)->Text;
-
+
/* Return it in the OutputString */
if (OutputString) {
-
+
OutputString->Buffer = BugCode;
OutputString->Length = strlen(BugCode) + 1;
OutputString->MaximumLength = strlen(BugCode) + 1;
-
+
} else {
-
+
/* Direct Output to Screen */
DbgPrint("%s\n", BugCode);
break;
PKBUGCHECK_CALLBACK_RECORD CurrentRecord;
PLIST_ENTRY ListHead;
PLIST_ENTRY NextEntry;
-
+
/* FIXME: Check Checksum and add support for WithReason Callbacks */
-
+
/* First make sure that the list is Initialized... it might not be */
ListHead = &BugcheckCallbackListHead;
if (ListHead->Flink && ListHead->Blink) {
-
+
/* Loop the list */
NextEntry = ListHead->Flink;
while (NextEntry != ListHead) {
-
+
/* Get the Callback Record */
- CurrentRecord = CONTAINING_RECORD(NextEntry,
+ CurrentRecord = CONTAINING_RECORD(NextEntry,
KBUGCHECK_CALLBACK_RECORD,
Entry);
-
+
/* Make sure it's inserted */
if (CurrentRecord->State == BufferInserted) {
-
+
/* Call the routine */
CurrentRecord->State = BufferStarted;
- (CurrentRecord->CallbackRoutine)(CurrentRecord->Buffer,
+ (CurrentRecord->CallbackRoutine)(CurrentRecord->Buffer,
CurrentRecord->Length);
CurrentRecord->State = BufferFinished;
}
-
+
/* Move to next Entry */
NextEntry = NextEntry->Flink;
}
}
}
-VOID
+VOID
STDCALL
KeBugCheckWithTf(ULONG BugCheckCode,
ULONG BugCheckParameter1,
PLIST_ENTRY CurrentEntry;
MODULE_TEXT_SECTION* CurrentSection = NULL;
extern LIST_ENTRY ModuleTextListHead;
-
+
/* Make sure we're switching back to the blue screen and print messages on it */
HalReleaseDisplayOwnership();
if (KdpDebugMode.Gdb) KdpDebugMode.Screen = TRUE;
-
+
/* Try to find out who did this. For this, we need a Trap Frame.
* Note: Some special BSODs pass the Frame/EIP as a Param. MSDN has the
- * info so it eventually needs to be supported.
+ * info so it eventually needs to be supported.
*/
if (Tf) {
-
+
/* For now, get Address from EIP */
Address = (PVOID)Tf->Eip;
-
+
/* Try to get information on the module */
CurrentEntry = ModuleTextListHead.Flink;
while (CurrentEntry != &ModuleTextListHead && CurrentEntry != NULL) {
-
+
/* Get the current Section */
- CurrentSection = CONTAINING_RECORD(CurrentEntry,
- MODULE_TEXT_SECTION,
+ CurrentSection = CONTAINING_RECORD(CurrentEntry,
+ MODULE_TEXT_SECTION,
ListEntry);
/* Check if this is the right one */
if ((Address != NULL && (Address >= (PVOID)CurrentSection->Base &&
Address < (PVOID)(CurrentSection->Base + CurrentSection->Length)))) {
- /* We got it */
+ /* We got it */
GotExtendedCrashInfo = TRUE;
break;
}
-
+
/* Loop again */
CurrentEntry = CurrentEntry->Flink;
}
}
-
+
/* Raise IRQL to HIGH_LEVEL */
Ke386DisableInterrupts();
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
/* Unload the Kernel Adress Space if we own it */
if (MmGetKernelAddressSpace()->Lock.Owner == KeGetCurrentThread())
MmUnlockAddressSpace(MmGetKernelAddressSpace());
-
+
/* FIXMEs: Use inbv to clear, fill and write to screen. */
-
+
/* Show the STOP Message */
DbgPrint("A problem has been detected and ReactOS has been shut down to prevent "
"damage to your computer.\n\n");
-
+
/* Show the module name of who caused this */
if (GotExtendedCrashInfo) {
-
+
DbgPrint("The problem seems to be caused by the following file: %S\n\n", CurrentSection->Name);
}
/* Show the module name and more data of who caused this */
if (GotExtendedCrashInfo) {
-
- DbgPrint("*** %S - Address 0x%p base at 0x%p, DateStamp 0x%x\n\n",
+
+ DbgPrint("*** %S - Address 0x%p base at 0x%p, DateStamp 0x%x\n\n",
CurrentSection->Name,
Address,
CurrentSection->Base,
0);
}
-
+
/* There can only be one Bugcheck per Bootup */
if (!InterlockedDecrement((PLONG)&KeBugCheckCount)) {
#ifdef CONFIG_SMP
ULONG i;
/* Freeze the other CPUs */
- for (i = 0; i < KeNumberProcessors; i++) {
+ for (i = 0; i < KeNumberProcessors; i++) {
if (i != KeGetCurrentProcessorNumber()) {
-
+
/* Send the IPI and give them one second to catch up */
KiIpiSendRequest(1 << i, IPI_REQUEST_FREEZE);
KeStallExecutionProcessor(1000000);
/* Check if we got a Trap Frame */
if (Tf) {
-
+
/* Dump it */
KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
-
+
} else {
-
+
/* We can only dump the frames */
#if defined(__GNUC__)
KeDumpStackFrames((PULONG)__builtin_frame_address(0));
#error Unknown compiler for inline assembler
#endif
}
-
+
/* Call the Callbacks */;
KiDoBugCheckCallbacks();
/* Dump the BSOD to the Paging File */
- MmDumpToPagingFile(BugCheckCode,
- BugCheckParameter1,
- BugCheckParameter2,
+ MmDumpToPagingFile(BugCheckCode,
+ BugCheckParameter1,
+ BugCheckParameter2,
BugCheckParameter3,
- BugCheckParameter4,
+ BugCheckParameter4,
Tf);
/* Wake up the Debugger */
/*
* @implemented
*
- * FUNCTION: Brings the system down in a controlled manner when an
+ * FUNCTION: Brings the system down in a controlled manner when an
* inconsistency that might otherwise cause corruption has been detected
* ARGUMENTS:
* BugCheckCode = Specifies the reason for the bug check
* BugCheckParameter[1-4] = Additional information about bug
* RETURNS: Doesn't
*/
-VOID
+VOID
STDCALL
KeBugCheckEx(ULONG BugCheckCode,
ULONG BugCheckParameter1,
ULONG BugCheckParameter4)
{
/* Call the Trap Frame version without a Trap Frame */
- KeBugCheckWithTf(BugCheckCode,
- BugCheckParameter1,
+ KeBugCheckWithTf(BugCheckCode,
+ BugCheckParameter1,
BugCheckParameter2,
- BugCheckParameter3,
- BugCheckParameter4,
+ BugCheckParameter3,
+ BugCheckParameter4,
NULL);
}
/*
* @implemented
*
- * FUNCTION: Brings the system down in a controlled manner when an
+ * FUNCTION: Brings the system down in a controlled manner when an
* inconsistency that might otherwise cause corruption has been detected
* ARGUMENTS:
* BugCheckCode = Specifies the reason for the bug check
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/catch.c
* PURPOSE: Exception handling
- *
+ *
* PROGRAMMERS: Anich Gregor
* David Welch (welch@mcmail.com)
* Casper S. Hornstrup (chorns@users.sourceforge.net)
/* Increase number of Exception Dispatches */
KeGetCurrentPrcb()->KeExceptionDispatchCount++;
- if (!Context)
+ if (!Context)
{
/* Assume Full context */
TContext.ContextFlags = CONTEXT_FULL;
-
+
/* Check the mode */
- if (PreviousMode == UserMode)
+ if (PreviousMode == UserMode)
{
/* Add Debugger Registers if this is User Mode */
TContext.ContextFlags = TContext.ContextFlags | CONTEXT_DEBUGGER;
}
-
+
/* Convert the Trapframe into a Context */
KeTrapFrameToContext(Tf, &TContext);
}
/* Break into Debugger */
- Action = KdpEnterDebuggerException(ExceptionRecord,
- PreviousMode,
- Context,
- Tf,
+ Action = KdpEnterDebuggerException(ExceptionRecord,
+ PreviousMode,
+ Context,
+ Tf,
TRUE,
TRUE);
/* If the debugger said continue, then continue */
if (Action == kdContinue) return;
-
+
/* If the Debugger couldn't handle it... */
- if (Action != kdDoNotHandleException)
- {
+ if (Action != kdDoNotHandleException)
+ {
/* See what kind of Exception this is */
- if (PreviousMode == UserMode)
- {
+ if (PreviousMode == UserMode)
+ {
/* User mode exception, search the frames if we have to */
- if (SearchFrames)
+ if (SearchFrames)
{
PULONG Stack;
ULONG CDest;
NTSTATUS StatusOfCopy;
/* Enter Debugger if available */
- Action = KdpEnterDebuggerException(ExceptionRecord,
+ Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
- Context,
- Tf,
+ Context,
+ Tf,
TRUE,
FALSE);
/* FIXME: Forward exception to user mode debugger */
/* FIXME: Check user mode stack for enough space */
-
+
/* Let usermode try and handle the exception. Setup Stack */
Stack = (PULONG)temp_space;
CDest = 3 + (ROUND_UP(sizeof(EXCEPTION_RECORD), 4) / 4);
Stack[2] = (ULONG)&pNewUserStack[CDest];
memcpy(&Stack[3], ExceptionRecord, sizeof(EXCEPTION_RECORD));
memcpy(&Stack[CDest], Context, sizeof(CONTEXT));
-
+
/* Copy Stack */
StatusOfCopy = MmCopyToCaller(pNewUserStack,
temp_space,
(12 + sizeof(EXCEPTION_RECORD) + sizeof(CONTEXT)));
-
+
/* Check for success */
- if (NT_SUCCESS(StatusOfCopy))
+ if (NT_SUCCESS(StatusOfCopy))
{
/* Set new Stack Pointer */
Tf->Esp = (ULONG)pNewUserStack;
- }
- else
- {
+ }
+ else
+ {
/*
* Now it really hit the ventilation device. Sorry,
* can do nothing but kill the sucker.
/* FIXME: Forward the exception to the process exception port */
/* Enter KDB if available */
- Action = KdpEnterDebuggerException(ExceptionRecord,
+ Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
- Context,
- Tf,
+ Context,
+ Tf,
FALSE,
FALSE);
/* Terminate the offending thread */
DPRINT1("Unhandled UserMode exception, terminating thread\n");
ZwTerminateThread(NtCurrentThread(), ExceptionRecord->ExceptionCode);
- }
- else
+ }
+ else
{
- /* This is Kernel Mode */
+ /* This is Kernel Mode */
/* Enter KDB if available */
- Action = KdpEnterDebuggerException(ExceptionRecord,
+ Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
- Context,
- Tf,
+ Context,
+ Tf,
TRUE,
FALSE);
/* Dispatch the Exception */
Value = RtlpDispatchException (ExceptionRecord, Context);
DPRINT("RtlpDispatchException() returned with 0x%X\n", Value);
-
+
/* If RtlpDispatchException() did not handle the exception then bugcheck */
if (Value != ExceptionContinueExecution ||
- 0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))
+ 0 != (ExceptionRecord->ExceptionFlags & EXCEPTION_NONCONTINUABLE))
{
DPRINT("ExceptionRecord->ExceptionAddress = 0x%x\n", ExceptionRecord->ExceptionAddress);
/* Enter KDB if available */
- Action = KdpEnterDebuggerException(ExceptionRecord,
+ Action = KdpEnterDebuggerException(ExceptionRecord,
PreviousMode,
- Context,
- Tf,
+ Context,
+ Tf,
FALSE,
FALSE);
/* Exit if we're continuing */
if (Action == kdContinue) return;
- KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED,
- ExceptionRecord->ExceptionCode,
+ KEBUGCHECKWITHTF(KMODE_EXCEPTION_NOT_HANDLED,
+ ExceptionRecord->ExceptionCode,
(ULONG)ExceptionRecord->ExceptionAddress,
ExceptionRecord->ExceptionInformation[0],
ExceptionRecord->ExceptionInformation[1],
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/clock.c
* PURPOSE: Handle System Clock
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Created
* David Welch & Phillip Susi - Implementation (?)
*/
-
+
/* NOTES ******************************************************************/
/*
* System time units are 100-nanosecond intervals
/*
* The increment in the system clock every timer tick (in system time units)
- *
- * = (1/18.2)*10^9
- *
+ *
+ * = (1/18.2)*10^9
+ *
* RJJ was 54945055
*/
#define CLOCK_INCREMENT (100000)
DPRINT1("KiInitializeSystemClock()\n");
InitializeListHead(&KiTimerListHead);
KeInitializeDpc(&KiExpireTimerDpc, (PKDEFERRED_ROUTINE)KiExpireTimers, 0);
-
+
/* Calculate the starting time for the system clock */
HalQueryRealTimeClock(&TimeFields);
RtlTimeFieldsToTime(&TimeFields, &SystemBootTime);
STDCALL
KeQueryTimeIncrement(VOID)
/*
- * FUNCTION: Gets the increment (in 100-nanosecond units) that is added to
+ * FUNCTION: Gets the increment (in 100-nanosecond units) that is added to
* the system clock every time the clock interrupts
* RETURNS: The increment
*/
/*
* @implemented
*/
-VOID
+VOID
STDCALL
KeQueryTickCount(PLARGE_INTEGER TickCount)
/*
} while (CurrentTime->u.HighPart != SharedUserData->SystemTime.High2Time);
}
-ULONGLONG
+ULONGLONG
STDCALL
KeQueryInterruptTime(VOID)
{
CurrentThread = Prcb->CurrentThread;
CurrentProcess = CurrentThread->ApcState.Process;
- /*
+ /*
* Cs bit 0 is always set for user mode if we are in protected mode.
* V86 mode is counted as user time.
*/
*
* @implemented
*/
-VOID
+VOID
STDCALL
KeUpdateSystemTime(
IN PKTRAP_FRAME TrapFrame,
ASSERT(KeGetCurrentIrql() == PROFILE_LEVEL);
KiRawTicks++;
-
+
if (KiClockSetupComplete == FALSE) return;
/*
- * Increment the number of timers ticks
+ * Increment the number of timers ticks
*/
KeTickCount++;
SharedUserData->TickCountLowDeprecated++;
NtGetTickCount(VOID)
{
LARGE_INTEGER TickCount;
-
+
KeQueryTickCount(&TickCount);
return TickCount.u.LowPart;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtQueryTimerResolution(OUT PULONG MinimumResolution,
OUT PULONG MaximumResolution,
return STATUS_NOT_IMPLEMENTED;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtSetTimerResolution(IN ULONG DesiredResolution,
IN BOOLEAN SetResolution,
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/device.c
* PURPOSE: Kernel Device/Settings Functions
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
KIRQL OldIrql;
PKPROCESS Process = NULL;
PKPRCB Prcb = NULL;
-
+
/* Raise the IRQL for the TB Flush */
OldIrql = KeRaiseIrqlToSynchLevel();
-
+
/* All CPUs need to have the TB flushed. */
if (CurrentCpuOnly == FALSE) {
Prcb = KeGetCurrentPrcb();
-
+
/* How many CPUs is our caller using? */
Process = Prcb->CurrentThread->ApcState.Process;
-
+
/* More then one, so send an IPI */
if (Process->ActiveProcessors > 1) {
/* Send IPI Packet */
}
}
-
+
/* Flush the TB for the Current CPU */
KeFlushCurrentTb();
-
+
/* Clean up */
if (CurrentCpuOnly == FALSE) {
/* Did we send an IPI? If so, wait for completion */
if (Process->ActiveProcessors > 1) {
do {
} while (Prcb->TargetSet != 0);
- }
- }
-
+ }
+ }
+
/* FIXME: According to MSKB, we should increment a counter? */
-
- /* Return to Original IRQL */
+
+ /* Return to Original IRQL */
KeLowerIrql(OldIrql);
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/dpc.c
* PURPOSE: Handle DPCs (Delayed Procedure Calls)
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Philip Susi (phreak@iag.net)
* Eric Kohl (ekohl@abo.rhein-zeitung.de)
KeInitDpc(PKPRCB Prcb)
{
InitializeListHead(&Prcb->DpcData[0].DpcListHead);
-#if 0
+#if 0
/*
* FIXME:
* Prcb->DpcEvent is a NULL pointer.
PKDEFERRED_ROUTINE DeferredRoutine,
PVOID DeferredContext)
/*
- * FUNCTION:
+ * FUNCTION:
* Initalizes a Threaded DPC and registers the DeferredRoutine for it.
* ARGUMENTS:
* Dpc = Pointer to a caller supplied DPC to be initialized. The caller must allocate this memory.
/*
* @implemented
*
- * FUNCTION:
+ * FUNCTION:
* Initalizes a DPC and registers the DeferredRoutine for it.
* ARGUMENTS:
* Dpc = Pointer to a caller supplied DPC to be initialized. The caller must allocate this memory.
/*
* @implemented
*
- * FUNCTION:
+ * FUNCTION:
* Queues a DPC for execution when the IRQL of a processor
* drops below DISPATCH_LEVEL
* ARGUMENTS:
* Dpc = Pointed to a DPC Object Initalized by KeInitializeDpc.
* SystemArgument1 = Driver Determined context data
* SystemArgument2 = Driver Determined context data
- * RETURNS:
+ * RETURNS:
* TRUE if the DPC object wasn't already in the queue
* FALSE otherwise
- * NOTES:
+ * NOTES:
* If there is currently a DPC active on the target processor, or a DPC
* interrupt has already been requested on the target processor when a
* DPC is queued, then no further action is necessary. The DPC will be
* is greater that the target depth or the minimum DPC rate is less than the
* target rate.
*/
-BOOLEAN
+BOOLEAN
STDCALL
KeInsertQueueDpc(PKDPC Dpc,
PVOID SystemArgument1,
/* Check IRQL and Raise it to HIGH_LEVEL */
ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL);
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
+
/* Check if this is a Thread DPC, which we don't support (yet) */
if (Dpc->Type == ThreadedDpcObject) {
return FALSE;
#ifdef CONFIG_SMP
/* Get the right PCR for this CPU */
if (Dpc->Number >= MAXIMUM_PROCESSORS) {
-
+
ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors);
Prcb = ((PKPCR)((ULONG_PTR)KPCR_BASE + ((Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE)))->Prcb;
-
+
} else {
-
+
ASSERT (Dpc->Number < KeNumberProcessors);
Prcb = KeGetCurrentPrcb();
Dpc->Number = KeGetCurrentProcessorNumber();
}
-
+
KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
#else
Prcb = ((PKPCR)KPCR_BASE)->Prcb;
/* Get the DPC Data */
if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Prcb->DpcData[0].DpcLock, 0)) {
-
+
DPRINT("DPC Already Inserted");
#ifdef CONFIG_SMP
KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
KeLowerIrql(OldIrql);
return(FALSE);
}
-
+
/* Make sure the lists are free if the Queue is 0 */
if (Prcb->DpcData[0].DpcQueueDepth == 0) {
-
+
ASSERT(IsListEmpty(&Prcb->DpcData[0].DpcListHead));
} else {
-
+
ASSERT(!IsListEmpty(&Prcb->DpcData[0].DpcListHead));
}
Dpc->SystemArgument2=SystemArgument2;
Prcb->DpcData[0].DpcQueueDepth++;
Prcb->DpcData[0].DpcCount++;
-
+
/* Insert the DPC into the list. HighImportance DPCs go at the beginning */
if (Dpc->Importance == HighImportance) {
-
+
InsertHeadList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry);
- } else {
-
+ } else {
+
InsertTailList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry);
}
DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
-
+
/* Make sure a DPC isn't executing already and respect rules outlined above. */
if ((!Prcb->DpcRoutineActive) && (!Prcb->DpcInterruptRequested)) {
-
-#ifdef CONFIG_SMP
+
+#ifdef CONFIG_SMP
/* Check if this is the same CPU */
if (Prcb != KeGetCurrentPrcb()) {
-
+
/* Send IPI if High Importance */
if ((Dpc->Importance == HighImportance) ||
(Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth)) {
-
+
if (Dpc->Number >= MAXIMUM_PROCESSORS) {
-
+
KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC);
} else {
-
+
KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC);
}
}
} else {
-
+
/* Request an Interrupt only if the DPC isn't low priority */
- if ((Dpc->Importance != LowImportance) ||
+ if ((Dpc->Importance != LowImportance) ||
(Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) ||
(Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) {
-
+
/* Request Interrupt */
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
Prcb->DpcInterruptRequested = TRUE;
}
#else
DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Prcb->DpcData[0].DpcQueueDepth, Prcb->MaximumDpcQueueDepth, Prcb->DpcRequestRate, Prcb->MinimumDpcRate);
-
+
/* Request an Interrupt only if the DPC isn't low priority */
- if ((Dpc->Importance != LowImportance) ||
+ if ((Dpc->Importance != LowImportance) ||
(Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) ||
(Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) {
-
+
/* Request Interrupt */
DPRINT("Requesting Interrupt\n");
HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
#ifdef CONFIG_SMP
KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
#endif
- /* Lower IRQL */
+ /* Lower IRQL */
KeLowerIrql(OldIrql);
return(TRUE);
}
/*
* @implemented
*
- * FUNCTION:
+ * FUNCTION:
* Removes DPC object from the system dpc queue
* ARGUMENTS:
* Dpc = Pointer to DPC to remove from the queue.
- * RETURNS:
+ * RETURNS:
* TRUE if the DPC was in the queue
* FALSE otherwise
*/
-BOOLEAN
+BOOLEAN
STDCALL
KeRemoveQueueDpc(PKDPC Dpc)
{
BOOLEAN WasInQueue;
KIRQL OldIrql;
-
+
/* Raise IRQL */
DPRINT("Removing DPC: %x\n", Dpc);
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
#ifdef CONFIG_SMP
KiAcquireSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock);
#endif
-
+
/* First make sure the DPC lock isn't being held */
WasInQueue = Dpc->DpcData ? TRUE : FALSE;
- if (Dpc->DpcData) {
-
+ if (Dpc->DpcData) {
+
/* Remove the DPC */
((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--;
RemoveEntryList(&Dpc->DpcListEntry);
STDCALL
KeFlushQueuedDpcs(VOID)
/*
- * FUNCTION:
+ * FUNCTION:
* Called to Deliver DPCs if any are pending.
* NOTES:
* Called when deleting a Driver.
/*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
KeIsExecutingDpc(
VOID
*
* @implemented
*/
-VOID
+VOID
STDCALL
KeSetImportanceDpc (IN PKDPC Dpc,
IN KDPC_IMPORTANCE Importance)
* Number = Processor number
* RETURNS: None
*/
-VOID
+VOID
STDCALL
KeSetTargetProcessorDpc(IN PKDPC Dpc,
IN CCHAR Number)
{
/* Check how many CPUs are on the system */
if (Number >= MAXIMUM_PROCESSORS) {
-
+
/* No CPU Number */
Dpc->Number = 0;
-
+
} else {
-
+
/* Set the Number Specified */
ASSERT(Number < KeNumberProcessors);
Dpc->Number = Number + MAXIMUM_PROCESSORS;
}
/*
- * FUNCTION:
+ * FUNCTION:
* Called when a quantum end occurs to check if priority should be changed
* and wether a new thread should be dispatched.
* NOTES:
PKPROCESS Process;
KPRIORITY OldPriority;
KPRIORITY NewPriority;
-
+
/* Lock dispatcher, get current thread */
Prcb = KeGetCurrentPrcb();
CurrentThread = KeGetCurrentThread();
OldIrql = KeRaiseIrqlToSynchLevel();
-
+
/* Get the Thread's Process */
Process = CurrentThread->ApcState.Process;
-
+
/* Set DPC Event if requested */
if (Prcb->DpcSetEventRequest) {
/*
KEBUGCHECK(0);
KeSetEvent(Prcb->DpcEvent, 0, 0);
}
-
+
/* Check if Quantum expired */
if (CurrentThread->Quantum <= 0) {
-
+
/* Reset the new Quantum */
CurrentThread->Quantum = CurrentThread->QuantumReset;
-
+
/* Calculate new priority */
OldPriority = CurrentThread->Priority;
if (OldPriority < LOW_REALTIME_PRIORITY) {
-
+
/* Set the New Priority and add the Priority Decrement */
NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1;
-
+
/* Don't go out of bounds */
if (NewPriority < CurrentThread->BasePriority) NewPriority = CurrentThread->BasePriority;
-
+
/* Reset the priority decrement */
CurrentThread->PriorityDecrement = 0;
-
+
/* Set a new priority if needed */
if (OldPriority != NewPriority) {
-
+
/* Set new Priority */
CurrentThread->Priority = NewPriority;
-
+
} else {
-
+
/* Queue new thread if none is already */
if (Prcb->NextThread == NULL) {
-
+
/* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */
-
+
} else {
-
+
/* Make the current thread non-premeptive if a new thread is queued */
CurrentThread->Preempted = FALSE;
}
}
-
+
} else {
/* Set the Quantum back to Maximum */
//if (CurrentThread->DisableQuantum) {
/* Dispatch the Thread */
KeLowerIrql(DISPATCH_LEVEL);
KiDispatchThread(Ready);
-}
+}
/*
* @implemented
*
- * FUNCTION:
+ * FUNCTION:
* Called whenever a system interrupt is generated at DISPATCH_LEVEL.
* It delivers queued DPCs and dispatches a new thread if need be.
*/
if (Prcb->DpcData[0].DpcQueueDepth > 0) {
/* Raise IRQL */
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-#ifdef CONFIG_SMP
+#ifdef CONFIG_SMP
KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
#endif
Prcb->DpcRoutineActive = TRUE;
DPRINT("&Prcb->DpcData[0].DpcListHead: %x\n", &Prcb->DpcData[0].DpcListHead);
/* Loop while we have entries */
while (!IsListEmpty(&Prcb->DpcData[0].DpcListHead)) {
-
+
ASSERT(Prcb->DpcData[0].DpcQueueDepth > 0);
DPRINT("Queue Depth: %x\n", Prcb->DpcData[0].DpcQueueDepth);
-
+
/* Get the DPC call it */
DpcEntry = RemoveHeadList(&Prcb->DpcData[0].DpcListHead);
Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry);
Dpc->SystemArgument1,
Dpc->SystemArgument2);
KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-
+
#ifdef CONFIG_SMP
KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
- /*
+ /*
* If the dpc routine drops the irql below DISPATCH_LEVEL,
- * a thread switch can occur and after the next thread switch
+ * a thread switch can occur and after the next thread switch
* the execution may start on an other processor.
*/
if (Prcb != KeGetCurrentPrcb()) {
-
+
Prcb->DpcRoutineActive = FALSE;
KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
Prcb = KeGetCurrentPrcb();
#ifdef CONFIG_SMP
KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
#endif
-
+
/* DPC Dispatching Ended, re-enable interrupts */
KeLowerIrql(OldIrql);
}
-
+
DPRINT("Checking for Quantum End\n");
-
+
/* If we have Quantum End, call the function */
if (Prcb->QuantumEnd) {
-
+
Prcb->QuantumEnd = FALSE;
KiQuantumEnd();
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/event.c
* PURPOSE: Implements events
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* David Welch (welch@mcmail.com)
*/
/*
* @implemented
*/
-VOID
-STDCALL
+VOID
+STDCALL
KeClearEvent(PKEVENT Event)
{
DPRINT("KeClearEvent(Event %x)\n", Event);
-
+
/* Reset Signal State */
Event->Header.SignalState = FALSE;
}
/*
* @implemented
*/
-VOID
-STDCALL
+VOID
+STDCALL
KeInitializeEvent(PKEVENT Event,
EVENT_TYPE Type,
BOOLEAN State)
{
DPRINT("KeInitializeEvent(Event %x)\n", Event);
-
+
/* Initialize the Dispatcher Header */
KeInitializeDispatcherHeader(&Event->Header,
Type,
/*
* @implemented
*/
-VOID
-STDCALL
+VOID
+STDCALL
KeInitializeEventPair(PKEVENT_PAIR EventPair)
{
DPRINT("KeInitializeEventPair(Event %x)\n", EventPair);
-
+
/* Initialize the Event Pair Type and Size */
EventPair->Type = EventPairObject;
EventPair->Size = sizeof(KEVENT_PAIR);
-
+
/* Initialize the two Events */
KeInitializeEvent(&EventPair->LowEvent, SynchronizationEvent, FALSE);
KeInitializeEvent(&EventPair->HighEvent, SynchronizationEvent, FALSE);
LONG PreviousState;
DPRINT("KePulseEvent(Event %x, Wait %x)\n",Event,Wait);
-
+
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Save the Old State */
PreviousState = Event->Header.SignalState;
-
+
/* Check if we are non-signaled and we have stuff in the Wait Queue */
if (!PreviousState && !IsListEmpty(&Event->Header.WaitListHead)) {
-
+
/* Set the Event to Signaled */
Event->Header.SignalState = 1;
-
+
/* Wake the Event */
KiWaitTest(&Event->Header, Increment);
}
-
+
/* Unsignal it */
Event->Header.SignalState = 0;
-
+
/* Check what wait state was requested */
if (Wait == FALSE) {
-
- /* Wait not requested, release Dispatcher Database and return */
+
+ /* Wait not requested, release Dispatcher Database and return */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
} else {
-
+
/* Return Locked and with a Wait */
KTHREAD *Thread = KeGetCurrentThread();
Thread->WaitNext = TRUE;
/*
* @implemented
*/
-LONG
-STDCALL
+LONG
+STDCALL
KeReadStateEvent(PKEVENT Event)
{
/* Return the Signal State */
/*
* @implemented
*/
-LONG
-STDCALL
+LONG
+STDCALL
KeResetEvent(PKEVENT Event)
{
KIRQL OldIrql;
LONG PreviousState;
-
+
DPRINT("KeResetEvent(Event %x)\n",Event);
-
+
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Save the Previous State */
PreviousState = Event->Header.SignalState;
-
+
/* Set it to zero */
Event->Header.SignalState = 0;
-
- /* Release Dispatcher Database and return previous state */
+
+ /* Release Dispatcher Database and return previous state */
KeReleaseDispatcherDatabaseLock(OldIrql);
return PreviousState;
}
* @implemented
*/
LONG
-STDCALL
+STDCALL
KeSetEvent(PKEVENT Event,
KPRIORITY Increment,
BOOLEAN Wait)
/* Lock the Dispathcer Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Save the Previous State */
PreviousState = Event->Header.SignalState;
-
+
/* Check if we have stuff in the Wait Queue */
if (IsListEmpty(&Event->Header.WaitListHead)) {
-
+
/* Set the Event to Signaled */
DPRINT("Empty Wait Queue, Signal the Event\n");
Event->Header.SignalState = 1;
-
+
} else {
-
+
/* Get the Wait Block */
WaitBlock = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
KWAIT_BLOCK,
WaitListEntry);
-
-
+
+
/* Check the type of event */
if (Event->Header.Type == NotificationEvent || WaitBlock->WaitType == WaitAll) {
-
+
if (PreviousState == 0) {
-
+
/* We must do a full wait satisfaction */
DPRINT("Notification Event or WaitAll, Wait on the Event and Signal\n");
Event->Header.SignalState = 1;
KiWaitTest(&Event->Header, Increment);
}
-
+
} else {
-
- /* We can satisfy wait simply by waking the thread, since our signal state is 0 now */
+
+ /* We can satisfy wait simply by waking the thread, since our signal state is 0 now */
DPRINT("WaitAny or Sync Event, just unwait the thread\n");
KiAbortWaitThread(WaitBlock->Thread, WaitBlock->WaitKey, Increment);
}
}
-
+
/* Check what wait state was requested */
if (Wait == FALSE) {
-
- /* Wait not requested, release Dispatcher Database and return */
+
+ /* Wait not requested, release Dispatcher Database and return */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
} else {
-
+
/* Return Locked and with a Wait */
KTHREAD *Thread = KeGetCurrentThread();
Thread->WaitNext = TRUE;
KIRQL OldIrql;
DPRINT("KeSetEventBoostPriority(Event %x, Thread %x)\n",Event,Thread);
-
+
/* Acquire Dispatcher Database Lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* If our wait list is empty, then signal the event and return */
if (IsListEmpty(&Event->Header.WaitListHead)) {
-
+
Event->Header.SignalState = 1;
-
+
} else {
-
+
/* Get Thread that is currently waiting. First get the Wait Block, then the Thread */
- WaitingThread = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
- KWAIT_BLOCK,
+ WaitingThread = CONTAINING_RECORD(Event->Header.WaitListHead.Flink,
+ KWAIT_BLOCK,
WaitListEntry)->Thread;
/* Return it to caller if requested */
WaitingThread->Quantum = WaitingThread->QuantumReset;
KiAbortWaitThread(WaitingThread, STATUS_SUCCESS, EVENT_INCREMENT);
}
-
+
/* Release the Dispatcher Database Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
}
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/ke/gate.c
* PURPOSE: Implements the Gate Dispatcher Object
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* FUNCTIONS ****************************************************************/
-VOID
+VOID
FASTCALL
KeInitializeGate(PKGATE Gate)
{
DPRINT1("KeInitializeGate(Gate %x)\n", Gate);
-
+
/* Initialize the Dispatcher Header */
KeInitializeDispatcherHeader(&Gate->Header,
GateObject,
FASTCALL
KeWaitForGate(PKGATE Gate,
KWAIT_REASON WaitReason,
- KPROCESSOR_MODE WaitMode)
+ KPROCESSOR_MODE WaitMode)
{
KIRQL OldIrql;
PKTHREAD CurrentThread = KeGetCurrentThread();
PKWAIT_BLOCK GateWaitBlock;
NTSTATUS Status;
-
+
DPRINT1("KeWaitForGate(Gate %x)\n", Gate);
-
- do
+
+ do
{
/* Lock the APC Queue */
KeAcquireSpinLock(&CurrentThread->ApcQueueLock, &OldIrql);
-
+
/* Check if it's already signaled */
if (!Gate->Header.SignalState)
{
/* Unsignal it */
Gate->Header.SignalState = 0;
-
+
/* Unlock the Queue and return */
KeReleaseSpinLock(&CurrentThread->ApcQueueLock, OldIrql);
return;
}
-
+
/* Setup a Wait Block */
GateWaitBlock = &CurrentThread->WaitBlock[0];
GateWaitBlock->Object = (PVOID)Gate;
GateWaitBlock->Thread = CurrentThread;
-
+
/* Set the Thread Wait Data */
CurrentThread->WaitReason = WaitReason;
CurrentThread->WaitMode = WaitMode;
CurrentThread->WaitIrql = OldIrql;
CurrentThread->GateObject = Gate;
-
+
/* Insert into the Wait List */
InsertTailList(&Gate->Header.WaitListHead, &GateWaitBlock->WaitListEntry);
-
+
/* Handle Kernel Queues */
- if (CurrentThread->Queue)
+ if (CurrentThread->Queue)
{
DPRINT1("Waking Queue\n");
KiWakeQueue(CurrentThread->Queue);
}
-
+
/* Unlock the Queue*/
KeReleaseSpinLock(&CurrentThread->ApcQueueLock, OldIrql);
-
+
/* Block the Thread */
DPRINT1("Blocking the Thread: %x\n", CurrentThread);
- KiBlockThread(&Status,
- CurrentThread->Alertable,
- WaitMode,
+ KiBlockThread(&Status,
+ CurrentThread->Alertable,
+ WaitMode,
WaitReason);
-
+
/* Check if we were executing an APC */
if (Status != STATUS_KERNEL_APC) return;
-
+
DPRINT1("Looping Again\n");
} while (TRUE);
}
NTSTATUS WaitStatus = STATUS_SUCCESS;
DPRINT1("KeSignalGateBoostPriority(EveGate %x)\n", Gate);
-
+
/* Acquire Dispatcher Database Lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Make sure we're not already signaled or that the list is empty */
if (Gate->Header.SignalState) goto quit;
-
+
/* If our wait list is empty, then signal the event and return */
if (IsListEmpty(&Gate->Header.WaitListHead))
- {
+ {
Gate->Header.SignalState = 1;
goto quit;
}
-
+
/* Get WaitBlock */
- WaitBlock = CONTAINING_RECORD(Gate->Header.WaitListHead.Flink,
- KWAIT_BLOCK,
- WaitListEntry);
+ WaitBlock = CONTAINING_RECORD(Gate->Header.WaitListHead.Flink,
+ KWAIT_BLOCK,
+ WaitListEntry);
/* Remove it */
RemoveEntryList(&WaitBlock->WaitListEntry);
-
+
/* Get the Associated thread */
WaitThread = WaitBlock->Thread;
/* Increment the Queue's active threads */
- if (WaitThread->Queue)
+ if (WaitThread->Queue)
{
DPRINT1("Incrementing Queue's active threads\n");
WaitThread->Queue->CurrentCount++;
}
-
+
/* Reschedule the Thread */
DPRINT1("Unblocking the Thread\n");
KiUnblockThread(WaitThread, &WaitStatus, EVENT_INCREMENT);
return;
-quit:
+quit:
/* Release the Dispatcher Database Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
}
* PROJECT: ReactOS Kernel
* FILE: ntoskrnl/ke/gmutex.c
* PURPOSE: Implements Guarded Mutex
- *
- * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) and
+ *
+ * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) and
* Filip Navara (xnavara@volny.cz)
*/
* Enters a guarded region. This causes all (incl. special kernel) APCs
* to be disabled.
*/
-VOID
+VOID
STDCALL
KeEnterGuardedRegion(VOID)
{
KeLeaveGuardedRegion(VOID)
{
PKTHREAD Thread = KeGetCurrentThread();
-
+
/* Boost the enable count and check if Special APCs are enabled */
if (++Thread->SpecialApcDisable == 0)
{
}
}
}
-
-VOID
+
+VOID
FASTCALL
KeInitializeGuardedMutex(PKGUARDED_MUTEX GuardedMutex)
{
GuardedMutex->Count = GM_LOCK_BIT;
GuardedMutex->Owner = NULL;
GuardedMutex->Contention = 0;
-
+
/* Initialize the Wait Gate */
KeInitializeGate(&GuardedMutex->Gate);
}
ULONG BitsToRemove;
ULONG BitsToAdd;
LONG OldValue;
-
+
/* Increase the contention count */
InterlockedIncrement((PLONG)&GuardedMutex->Contention);
-
+
/* Start by unlocking the Guarded Mutex */
BitsToRemove = GM_LOCK_BIT;
BitsToAdd = GM_LOCK_WAITER_INC;
-
+
while (1)
{
/* Get the Count Bits */
OldValue = (volatile LONG)GuardedMutex->Count;
-
+
/* Check if the Guarded Mutex is locked */
if (OldValue & GM_LOCK_BIT)
{
/* Unlock it by removing the Lock Bit */
- if (InterlockedCompareExchange(&GuardedMutex->Count,
- OldValue &~ BitsToRemove,
- OldValue) == OldValue)
+ if (InterlockedCompareExchange(&GuardedMutex->Count,
+ OldValue &~ BitsToRemove,
+ OldValue) == OldValue)
{
/* The Guarded Mutex is now unlocked */
break;
}
- }
+ }
else
{
/* The Guarded Mutex isn't locked, so simply set the bits */
- if (InterlockedCompareExchange(&GuardedMutex->Count,
- OldValue | BitsToAdd,
- OldValue) != OldValue)
+ if (InterlockedCompareExchange(&GuardedMutex->Count,
+ OldValue | BitsToAdd,
+ OldValue) != OldValue)
{
/* The Guarded Mutex value changed behind our back, start over */
continue;
}
-
+
/* Now we have to wait for it */
KeWaitForGate(&GuardedMutex->Gate, WrGuardedMutex, KernelMode);
-
+
/* Ok, the wait is done, so set the new bits */
BitsToRemove = GM_LOCK_BIT | GM_LOCK_WAITER_WOKEN;
BitsToAdd = GM_LOCK_WAITER_WOKEN;
}
}
-VOID
+VOID
FASTCALL
KeAcquireGuardedMutex(PKGUARDED_MUTEX GuardedMutex)
{
/* Disable Special APCs */
KeEnterGuardedRegion();
- /* Do the Unsafe Acquire */
+ /* Do the Unsafe Acquire */
KeAcquireGuardedMutexUnsafe(GuardedMutex);
}
/* The Guarded Mutex was already locked, enter contented case */
KiAcquireGuardedMutexContented(GuardedMutex);
}
-
+
/* Set the Owner */
GuardedMutex->Owner = KeGetCurrentThread();
}
-VOID
+VOID
FASTCALL
KeReleaseGuardedMutexUnsafe(PKGUARDED_MUTEX GuardedMutex)
{
LONG OldValue;
-
+
/* Destroy the Owner */
GuardedMutex->Owner = NULL;
-
+
/* Add the Lock Bit */
OldValue = InterlockedExchangeAdd(&GuardedMutex->Count, 1);
-
+
/* Check if it was already locked, but not woken */
if (OldValue && !(OldValue & GM_LOCK_WAITER_WOKEN))
{
/* Update the Oldvalue to what it should be now */
OldValue |= GM_LOCK_BIT;
-
+
/* Remove the Woken bit */
- if (InterlockedCompareExchange(&GuardedMutex->Count,
+ if (InterlockedCompareExchange(&GuardedMutex->Count,
OldValue &~ GM_LOCK_WAITER_WOKEN,
OldValue) == OldValue)
{
}
}
-VOID
+VOID
FASTCALL
KeReleaseGuardedMutex(PKGUARDED_MUTEX GuardedMutex)
{
/* Do the actual release */
KeReleaseGuardedMutexUnsafe(GuardedMutex);
-
+
/* Re-enable APCs */
KeLeaveGuardedRegion();
}
-BOOL
+BOOL
FASTCALL
KeTryToAcquireGuardedMutex(PKGUARDED_MUTEX GuardedMutex)
{
/* Block APCs */
KeEnterGuardedRegion();
-
+
/* Remove the lock */
if (InterlockedClearBit(&GuardedMutex->Count, 0))
{
/* Re-enable APCs */
KeLeaveGuardedRegion();
-
+
/* Return failure */
return FALSE;
}
-
+
/* Set the Owner */
GuardedMutex->Owner = KeGetCurrentThread();
return TRUE;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/bios.c
* PURPOSE: Support for calling the BIOS in v86 mode
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
Ip[0] = 0xCD; /* int XX */
Ip[1] = Int;
Ip[2] = 0x63; /* arpl ax, ax */
- Ip[3] = 0xC0;
+ Ip[3] = 0xC0;
Ip[4] = 0x90; /* nop */
Ip[5] = 0x90; /* nop */
-
+
/*
* Munge the registers
*/
Regs->Eflags = (1 << 1) | (1 << 17) | (1 << 9); /* VM, IF */
Regs->RecoveryAddress = TRAMPOLINE_BASE + 2;
Regs->RecoveryInstruction[0] = 0x63; /* arpl ax, ax */
- Regs->RecoveryInstruction[1] = 0xC0;
+ Regs->RecoveryInstruction[1] = 0xC0;
Regs->RecoveryInstruction[2] = 0x90; /* nop */
Regs->RecoveryInstruction[3] = 0x90; /* nop */
Regs->Flags = KV86M_EMULATE_CLI_STI | KV86M_ALLOW_IO_PORT_ACCESS;
* Copy the return values back to the caller
*/
memcpy(Regs, &ORegs, sizeof(KV86M_REGISTERS));
-
+
return(Status);
}
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/brkpoint.c
/*
* @implemented
*/
-VOID STDCALL
+VOID STDCALL
DbgBreakPoint(VOID)
{
#if defined(__GNUC__)
/*
* @implemented
*/
-VOID STDCALL
+VOID STDCALL
DbgBreakPointWithStatus(ULONG Status)
{
#if defined(__GNUC__)
TrapFrame->Ss = Context->SegSs;
TrapFrame->Cs = Context->SegCs;
TrapFrame->Eip = Context->Eip;
- TrapFrame->Eflags = Context->EFlags;
+ TrapFrame->Eflags = Context->EFlags;
TrapFrame->Ebp = Context->Ebp;
}
-
+
/* Process the Integer Registers */
if ((Context->ContextFlags & CONTEXT_INTEGER) == CONTEXT_INTEGER)
{
TrapFrame->Esi = Context->Esi;
TrapFrame->Edi = Context->Edi;
}
-
+
/* Process the Context Segments */
if ((Context->ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS)
{
TrapFrame->Fs = Context->SegFs;
TrapFrame->Gs = Context->SegGs;
}
-
+
/* Handle the Debug Registers */
if ((Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS)
{
TrapFrame->Dr6 = Context->Dr6;
TrapFrame->Dr7 = Context->Dr7;
}
-
+
/* Handle FPU and Extended Registers */
return KiContextToFxSaveArea((PFX_SAVE_AREA)(TrapFrame + 1), Context);
}
{
/*
* FIXME: Implement this case
- */
+ */
Context->ContextFlags &= (~CONTEXT_DEBUG_REGISTERS) | CONTEXT_i386;
}
if ((Context->ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT)
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/fpu.c
* PURPOSE: Handles the FPU
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
UCHAR Tag;
INT i;
struct FPREG { USHORT Significand[4]; USHORT Exponent; } *FpReg;
-
+
for (i = 0; i < 8; i++)
{
if (FxSave->TagWord & (1 << i)) /* valid */
Tag = 2; /* Special */
}
break;
-
+
case 0x7fff:
Tag = 2; /* Special */
break;
-
+
default:
if (FpReg->Significand[3] & 0x00008000)
{
if (Prcb->FeatureBits & (X86_FEATURE_SSE | X86_FEATURE_SSE2))
{
Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT);
-
+
/* enable SSE */
XmmSupport = 1;
}
-
+
Ke386SetCr0(Ke386GetCr0() | X86_CR0_TS);
Ke386RestoreFlags(Flags);
}
#ifndef CONFIG_SMP
PKTHREAD NpxThread;
#endif
-
+
(void) cr0;
ASSERT((cr0 & X86_CR0_TS) == X86_CR0_TS);
ASSERT((Tf->Eflags & X86_EFLAGS_VM) == 0);
/* Dispatch exception */
DPRINT("Dispatching exception (ExceptionCode = 0x%08x)\n", Er.ExceptionCode);
KiDispatchException(&Er, Context, Tf, PreviousMode, TRUE);
-
+
DPRINT("Math-fault handled!\n");
return STATUS_SUCCESS;
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/gdt.c
* PURPOSE: GDT managment
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
PUSHORT KiGdtArray[MAXIMUM_PROCESSORS];
-USHORT KiBootGdt[11 * 4] =
+USHORT KiBootGdt[11 * 4] =
{
0x0, 0x0, 0x0, 0x0, /* Null */
0xffff, 0x0, 0x9a00, 0xcf, /* Kernel CS */
PUSHORT Gdt;
struct LocalGdtDescriptor_t Descriptor;
ULONG Entry;
- ULONG Base;
+ ULONG Base;
if (Pcr == NULL)
{
Pcr->GDT = Gdt;
/*
- * Set the base address of the PCR
+ * Set the base address of the PCR
*/
Base = (ULONG)Pcr;
Entry = PCR_SELECTOR / 2;
Gdt[Entry + 1] = (USHORT)(((ULONG)Base) & 0xffff);
-
+
Gdt[Entry + 2] = Gdt[Entry + 2] & ~(0xff);
Gdt[Entry + 2] = (USHORT)(Gdt[Entry + 2] | ((((ULONG)Base) & 0xff0000) >> 16));
-
+
Gdt[Entry + 3] = Gdt[Entry + 3] & ~(0xff00);
Gdt[Entry + 3] = (USHORT)(Gdt[Entry + 3] | ((((ULONG)Base) & 0xff000000) >> 16));
Descriptor.Base = (ULONG)Gdt;
#if defined(__GNUC__)
__asm__ ("lgdt %0\n\t" : /* no output */ : "m" (Descriptor));
-
+
/*
* Reload the selectors
*/
/*
* @unimplemented
*/
-NTSTATUS
+NTSTATUS
KeI386ReleaseGdtSelectors(
OUT PULONG SelArray,
IN ULONG NumOfSelectors
return 0;
}
-VOID
+VOID
KeSetBaseGdtSelector(ULONG Entry,
PVOID Base)
{
KIRQL oldIrql;
PUSHORT Gdt;
-
+
DPRINT("KeSetBaseGdtSelector(Entry %x, Base %x)\n",
Entry, Base);
-
+
KeAcquireSpinLock(&GdtLock, &oldIrql);
-
+
Gdt = KeGetCurrentKPCR()->GDT;
Entry = (Entry & (~0x3)) / 2;
-
+
Gdt[Entry + 1] = (USHORT)(((ULONG)Base) & 0xffff);
-
+
Gdt[Entry + 2] = Gdt[Entry + 2] & ~(0xff);
Gdt[Entry + 2] = (USHORT)(Gdt[Entry + 2] |
((((ULONG)Base) & 0xff0000) >> 16));
-
+
Gdt[Entry + 3] = Gdt[Entry + 3] & ~(0xff00);
Gdt[Entry + 3] = (USHORT)(Gdt[Entry + 3] |
((((ULONG)Base) & 0xff000000) >> 16));
-
- DPRINT("%x %x %x %x\n",
+
+ DPRINT("%x %x %x %x\n",
Gdt[Entry + 0],
Gdt[Entry + 1],
Gdt[Entry + 2],
Gdt[Entry + 3]);
-
+
KeReleaseSpinLock(&GdtLock, oldIrql);
}
-VOID
+VOID
KeSetGdtSelector(ULONG Entry,
ULONG Value1,
ULONG Value2)
{
KIRQL oldIrql;
- PULONG Gdt;
-
+ PULONG Gdt;
+
DPRINT("KeSetGdtSelector(Entry %x, Value1 %x, Value2 %x)\n",
Entry, Value1, Value2);
-
+
KeAcquireSpinLock(&GdtLock, &oldIrql);
-
- Gdt = (PULONG) KeGetCurrentKPCR()->GDT;;
+
+ Gdt = (PULONG) KeGetCurrentKPCR()->GDT;
Entry = (Entry & (~0x3)) / 4;
Gdt[Entry] = Value1;
Gdt[Entry + 1] = Value2;
- DPRINT("%x %x\n",
+ DPRINT("%x %x\n",
Gdt[Entry + 0],
Gdt[Entry + 1]);
-
+
KeReleaseSpinLock(&GdtLock, oldIrql);
}
-VOID
+VOID
KeDumpGdtSelector(ULONG Entry)
{
USHORT a, b, c, d;
ULONG RawLimit;
-
+
a = KiBootGdt[Entry*4];
b = KiBootGdt[Entry*4 + 1];
c = KiBootGdt[Entry*4 + 2];
d = KiBootGdt[Entry*4 + 3];
-
+
DbgPrint("Base: %x\n", b + ((c & 0xff) * (1 << 16)) +
((d & 0xff00) * (1 << 16)));
RawLimit = a + ((d & 0xf) * (1 << 16));
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/idt.c
* PURPOSE: IDT managment
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/irq.c
* PURPOSE: IRQ handling
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Hartmut Birr
*/
#endif /* CONFIG_SMP */
/*
- * PURPOSE: Object describing each isr
+ * PURPOSE: Object describing each isr
* NOTE: The data in this table is only modified at passsive level but can
* be accessed at any irq level.
*/
}
}
-STATIC VOID
+STATIC VOID
KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
PKTRAP_FRAME TrapFrame)
{
KiReleaseSpinLock(&CurrentIsr->Lock);
}
-VOID
+VOID
KiInterruptDispatch (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
/*
* FUNCTION: Calls the irq specific handler for an irq
* At this point we have interrupts disabled, nothing has been done to
* the PIC.
*/
-
+
KeGetCurrentPrcb()->InterruptCount++;
/*
CurrentThread = KeGetCurrentThread();
if (CurrentThread!=NULL && CurrentThread->Alerted[1])
{
- DPRINT("PID: %d, TID: %d CS %04x/%04x\n",
+ DPRINT("PID: %d, TID: %d CS %04x/%04x\n",
((PETHREAD)CurrentThread)->ThreadsProcess->UniqueProcessId,
((PETHREAD)CurrentThread)->Cid.UniqueThread,
- Trapframe->Cs,
+ Trapframe->Cs,
CurrentThread->TrapFrame ? CurrentThread->TrapFrame->Cs : 0);
if (CurrentThread->TrapFrame == NULL)
{
KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
CurrentThread->TrapFrame = &KernelTrapFrame;
}
-
+
Ke386EnableInterrupts();
KiDeliverApc(KernelMode, NULL, NULL);
Ke386DisableInterrupts();
-
+
ASSERT(KeGetCurrentThread() == CurrentThread);
if (CurrentThread->TrapFrame == &KernelTrapFrame)
{
}
}
-static VOID
+static VOID
KeDumpIrqList(VOID)
{
PKINTERRUPT current;
ULONG i, j;
KIRQL oldlvl;
BOOLEAN printed;
-
+
for (i=0;i<NR_IRQS;i++)
{
printed = FALSE;
*/
KiReleaseSpinLock(&CurrentIsr->Lock);
KeLowerIrql(oldlvl);
-
+
KeDumpIrqList();
KeRevertToUserAffinityThread();
PISR_TABLE CurrentIsr;
DPRINT("KeDisconnectInterrupt\n");
-
+
ASSERT (InterruptObject->ProcessorNumber < KeNumberProcessors);
KeSetSystemAffinityThread(1 << InterruptObject->ProcessorNumber);
*/
KiReleaseSpinLock(&CurrentIsr->Lock);
KeLowerIrql(oldlvl);
-
+
KeRevertToUserAffinityThread();
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/kernel.c
* PURPOSE: Initializes the kernel
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
Flags = OrigFlags ^ X86_EFLAGS_ID;
Ke386RestoreFlags(Flags);
Ke386SaveFlags(FinalFlags);
-
+
Pcr->PrcbData.LogicalProcessorsPerPhysicalProcessor = 1;
Pcr->PrcbData.InitialApicId = 0xff;
-
+
if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID))
{
/* No cpuid supported. */
/* Get the vendor name and the maximum cpuid level supported. */
Ki386Cpuid(0, &MaxCpuidLevel, (PULONG)&Pcr->PrcbData.VendorString[0], (PULONG)&Pcr->PrcbData.VendorString[8], (PULONG)&Pcr->PrcbData.VendorString[4]);
if (MaxCpuidLevel > 0)
- {
+ {
/* Get the feature flags. */
Ki386Cpuid(1, &Eax, &Ke386CpuidExMisc, &Ke386CpuidFlags2, &Pcr->PrcbData.FeatureBits);
/* Get the cache alignment, if it is available */
}
Pcr->PrcbData.CpuType = (Eax >> 8) & 0xf;
Pcr->PrcbData.CpuStep = (Eax & 0xf) | ((Eax << 4) & 0xf00);
-
+
Pcr->PrcbData.InitialApicId = (Ke386CpuidExMisc >> 24) & 0xff;
/* detect Hyper-Threading on Pentium 4 CPUs or later */
IdleProcessorMask |= (1 << KeGetCurrentProcessorNumber());
KeReleaseDispatcherDatabaseLock(oldIrql);
}
-
-VOID
+
+VOID
INIT_FUNCTION
KeCreateApplicationProcessorIdleThread(ULONG Id)
{
PsInitializeIdleOrFirstThread(PsIdleProcess,
&IdleThread,
NULL,
- KernelMode,
+ KernelMode,
FALSE);
IdleThread->Tcb.State = Running;
IdleThread->Tcb.FreezeCount = 0;
Pcr->Irql = SYNCH_LEVEL;
Pcr->PrcbData.MHz = BootPcr->PrcbData.MHz;
- Pcr->StallScaleFactor = BootPcr->StallScaleFactor;
+ Pcr->StallScaleFactor = BootPcr->StallScaleFactor;
/* Mark the end of the exception handler list */
Pcr->Tib.ExceptionList = (PVOID)-1;
/* Enable global pages */
Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
}
-
+
Offset = InterlockedIncrementUL(&PcrsAllocated) - 1;
Pcr = (PKPCR)((ULONG_PTR)KPCR_BASE + Offset * PAGE_SIZE);
/*
* Initialize the initial PCR region. We can't allocate a page
* with MmAllocPage() here because MmInit1() has not yet been
- * called, so we use a predefined page in low memory
+ * called, so we use a predefined page in low memory
*/
KPCR = (PKPCR)KPCR_BASE;
p1 = p2;
}
#if 0
- /*
+ /*
* FIXME:
* Make the detection of the noexecute feature more portable.
*/
Ke386NoExecute = TRUE;
Ke386RestoreFlags(Flags);
}
- }
+ }
else
{
NoExecute=FALSE;
}
#endif
- Ke386Pae = Ke386GetCr4() & X86_CR4_PAE ? TRUE : FALSE;
-#if 0
+ Ke386Pae = Ke386GetCr4() & X86_CR4_PAE ? TRUE : FALSE;
+#if 0
/* Enable PAE mode */
if ((Pae && (KPCR->PrcbData.FeatureBits & X86_FEATURE_PAE)) || NoExecute)
{
(Pcr->PrcbData.FeatureBits & X86_FEATURE_MMX);
SharedUserData->ProcessorFeatures[PF_PPC_MOVEMEM_64BIT_OK] = FALSE;
SharedUserData->ProcessorFeatures[PF_ALPHA_BYTE_INSTRUCTIONS] = FALSE;
- SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
+ SharedUserData->ProcessorFeatures[PF_XMMI_INSTRUCTIONS_AVAILABLE] =
(Pcr->PrcbData.FeatureBits & X86_FEATURE_SSE);
SharedUserData->ProcessorFeatures[PF_3DNOW_INSTRUCTIONS_AVAILABLE] =
(Ke386CpuidExFlags & X86_EXT_FEATURE_3DNOW);
/* Does the CPU Support Fast System Call? */
if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) {
-
+
/* FIXME: Check for Family == 6, Model < 3 and Stepping < 3 and disable */
-
+
/* Make sure it's not disabled in registry */
- RtlRosInitUnicodeStringFromLiteral(&KeyName,
+ RtlRosInitUnicodeStringFromLiteral(&KeyName,
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager\\Kernel");
- RtlRosInitUnicodeStringFromLiteral(&ValueName,
+ RtlRosInitUnicodeStringFromLiteral(&ValueName,
L"FastSystemCallDisable");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
NULL,
NULL);
Status = NtOpenKey(&KeyHandle, KEY_ALL_ACCESS, &ObjectAttributes);
-
+
if (NT_SUCCESS(Status)) {
-
+
/* Read the Value then Close the Key */
Status = NtQueryValueKey(KeyHandle,
&ValueName,
sizeof(ValueData),
&ResultLength);
RtlMoveMemory(&FastSystemCallDisable, ValueData.Data, sizeof(ULONG));
-
+
NtClose(KeyHandle);
}
-
+
} else {
-
+
/* Disable SYSENTER/SYSEXIT, because the CPU doesn't support it */
FastSystemCallDisable = 1;
-
+
}
-
+
if (FastSystemCallDisable) {
-
- /* Use INT2E */
+
+ /* Use INT2E */
SharedUserData->SystemCall[0] = 0x8D;
SharedUserData->SystemCall[1] = 0x54;
SharedUserData->SystemCall[2] = 0x24;
SharedUserData->SystemCall[4] = 0xCD;
SharedUserData->SystemCall[5] = 0x2E;
SharedUserData->SystemCall[6] = 0xC3;
-
+
} else {
-
+
/* Use SYSENTER */
SharedUserData->SystemCall[0] = 0x8B;
SharedUserData->SystemCall[1] = 0xD4;
SharedUserData->SystemCall[2] = 0x0F;
SharedUserData->SystemCall[3] = 0x34;
- SharedUserData->SystemCall[4] = 0xC3;
+ SharedUserData->SystemCall[4] = 0xC3;
/* Enable SYSENTER/SYSEXIT */
KiFastSystemCallDisable = 0;
BOOL PspIsDescriptorValid(PLDT_ENTRY ldt_entry)
{
ULONG Base, SegLimit;
- /*
+ /*
Allow invalid descriptors.
*/
if(!ldt_entry->HighWord.Bits.Type &&
((PULONG) LdtDescriptor)[1]);
#if defined(__GNUC__)
- __asm__("lldtw %%ax"
+ __asm__("lldtw %%ax"
: /* no output */
: "a" (LDT_SELECTOR));
#elif defined(_MSC_VER)
__asm mov ax, LDT_SELECTOR
- __asm lldt ax
+ __asm lldt ax
#else
#error Unknown compiler for inline assembler
#endif
* Set up an a descriptor for the LDT
*/
base = length = 0;
-
+
Gdt[(LDT_SELECTOR / 2) + 0] = (length & 0xFFFF);
Gdt[(LDT_SELECTOR / 2) + 1] = (base & 0xFFFF);
Gdt[(LDT_SELECTOR / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8200;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/thread.c
* PURPOSE: i386 Thread Context Creation
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
-
+
typedef struct _KSHARED_CTXSWITCH_FRAME {
ULONG Esp0;
PVOID ExceptionList;
PKSYSTEM_ROUTINE SystemRoutine;
PKSTART_ROUTINE StartRoutine;
PVOID StartContext;
- BOOLEAN UserThread;
+ BOOLEAN UserThread;
} KSTART_FRAME, *PKSTART_FRAME;
/*
VOID
STDCALL
-Ke386InitThreadWithContext(PKTHREAD Thread,
+Ke386InitThreadWithContext(PKTHREAD Thread,
PKSYSTEM_ROUTINE SystemRoutine,
PKSTART_ROUTINE StartRoutine,
PVOID StartContext,
PKSTART_FRAME StartFrame;
PKSHARED_CTXSWITCH_FRAME CtxSwitchFrame;
PKTRAP_FRAME TrapFrame = NULL;
-
+
/* Check if this is a With-Context Thread */
DPRINT("Ke386InitThreadContext\n");
- if (Context)
+ if (Context)
{
/* Set up the Initial Frame */
PKUINIT_FRAME InitFrame;
InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack - sizeof(KUINIT_FRAME));
DPRINT("Setting up a user-mode thread with the Frame at: %x\n", InitFrame);
-
+
/* Setup the Trap Frame */
TrapFrame = &InitFrame->TrapFrame;
-
+
/* Set up a trap frame from the context. */
if (KeContextToTrapFrame(Context, TrapFrame))
{
Thread->NpxState = NPX_STATE_VALID;
- }
- else
- {
+ }
+ else
+ {
Thread->NpxState = NPX_STATE_INVALID;
}
-
+
/* Enable Interrupts and disable some unsupported flags right now */
TrapFrame->Eflags = Context->EFlags | X86_EFLAGS_IF;
TrapFrame->Eflags &= ~(X86_EFLAGS_VM | X86_EFLAGS_NT | X86_EFLAGS_IOPL);
-
+
/* Set the previous mode as user */
TrapFrame->PreviousMode = UserMode;
-
+
/* Terminate the Exception Handler List */
TrapFrame->ExceptionList = (PVOID)0xFFFFFFFF;
-
+
/* Setup the Stack for KiThreadStartup and Context Switching */
StartFrame = &InitFrame->StartFrame;
CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
-
+
/* Tell the thread it will run in User Mode */
Thread->PreviousMode = UserMode;
-
+
/* Tell KiThreadStartup of that too */
StartFrame->UserThread = TRUE;
- }
- else
+ }
+ else
{
/* No context Thread, meaning System Thread */
-
+
/* Set up the Initial Frame */
PKKINIT_FRAME InitFrame;
InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack - sizeof(KKINIT_FRAME));
DPRINT("Setting up a kernel thread with the Frame at: %x\n", InitFrame);
-
+
/* Setup the Fx Area */
FxSaveArea = &InitFrame->FxSaveArea;
RtlZeroMemory(FxSaveArea, sizeof(FX_SAVE_AREA));
Thread->NpxState = NPX_STATE_INVALID;
-
+
/* Setup the Stack for KiThreadStartup and Context Switching */
StartFrame = &InitFrame->StartFrame;
CtxSwitchFrame = &InitFrame->CtxSwitchFrame;
-
+
/* Tell the thread it will run in Kernel Mode */
Thread->PreviousMode = KernelMode;
-
+
/* Tell KiThreadStartup of that too */
StartFrame->UserThread = FALSE;
}
-
+
/* Now setup the remaining data for KiThreadStartup */
StartFrame->StartContext = StartContext;
StartFrame->StartRoutine = StartRoutine;
StartFrame->SystemRoutine = SystemRoutine;
-
+
/* And set up the Context Switch Frame */
CtxSwitchFrame->RetEip = KiThreadStartup;
CtxSwitchFrame->Esp0 = (ULONG)Thread->InitialStack - sizeof(FX_SAVE_AREA);
CtxSwitchFrame->ExceptionList = (PVOID)0xFFFFFFFF;
-
+
/* Save back the new value of the kernel stack. */
DPRINT("Final Kernel Stack: %x \n", CtxSwitchFrame);
Thread->KernelStack = (PVOID)CtxSwitchFrame;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/tss.c
* PURPOSE: TSS managment
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
Tss->Esp0 = (ULONG)Ki386InitialStackArray[Id] + MM_STACK_SIZE; /* FIXME: - sizeof(FX_SAVE_AREA)? */
Tss->Ss0 = KERNEL_DS;
Tss->IoMapBase = 0xFFFF; /* No i/o bitmap */
- Tss->IoBitmap[8192] = 0xFF;
+ Tss->IoBitmap[8192] = 0xFF;
Tss->Ldt = 0;
/*
*/
base = (ULONG)Tss;
length = sizeof(KTSS) - 1;
-
+
Gdt[(TSS_SELECTOR / 2) + 0] = (USHORT)(length & 0xFFFF);
Gdt[(TSS_SELECTOR / 2) + 1] = (USHORT)(base & 0xFFFF);
Gdt[(TSS_SELECTOR / 2) + 2] = (USHORT)(((base & 0xFF0000) >> 16) | 0x8900);
TrapTss->Es = KERNEL_DS;
TrapTss->Fs = PCR_SELECTOR;
TrapTss->IoMapBase = 0xFFFF; /* No i/o bitmap */
- TrapTss->IoBitmap[0] = 0xFF;
+ TrapTss->IoBitmap[0] = 0xFF;
TrapTss->Ldt = 0;
- TrapTss->Cr3 = cr3_;
+ TrapTss->Cr3 = cr3_;
/*
* Initialize a descriptor for the trap TSS.
* Load the task register
*/
#if defined(__GNUC__)
- __asm__("ltr %%ax"
+ __asm__("ltr %%ax"
: /* no output */
: "a" (TSS_SELECTOR));
#elif defined(_MSC_VER)
KiBootTss.Ss0 = KERNEL_DS;
// KiBootTss.IoMapBase = FIELD_OFFSET(KTSS, IoBitmap);
KiBootTss.IoMapBase = 0xFFFF; /* No i/o bitmap */
- KiBootTss.IoBitmap[8192] = 0xFF;
+ KiBootTss.IoBitmap[8192] = 0xFF;
KiBootTss.Ldt = LDT_SELECTOR;
/*
*/
base = (unsigned int)&KiBootTss;
length = sizeof(KiBootTss) - 1;
-
+
KiBootGdt[(TSS_SELECTOR / 2) + 0] = (length & 0xFFFF);
KiBootGdt[(TSS_SELECTOR / 2) + 1] = (base & 0xFFFF);
KiBootGdt[(TSS_SELECTOR / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8900;
KiBootTrapTss.Es = KERNEL_DS;
KiBootTrapTss.Fs = PCR_SELECTOR;
KiBootTrapTss.IoMapBase = 0xFFFF; /* No i/o bitmap */
- KiBootTrapTss.IoBitmap[0] = 0xFF;
+ KiBootTrapTss.IoBitmap[0] = 0xFF;
KiBootTrapTss.Ldt = 0x0;
KiBootTrapTss.Cr3 = cr3_;
-
+
/*
* Initialize a descriptor for the trap TSS.
*/
* Load the task register
*/
#if defined(__GNUC__)
- __asm__("ltr %%ax"
+ __asm__("ltr %%ax"
: /* no output */
: "a" (TSS_SELECTOR));
#elif defined(_MSC_VER)
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/usertrap.c
* PURPOSE: Handling usermode exceptions.
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* FUNCTIONS ****************************************************************/
-BOOLEAN
+BOOLEAN
print_user_address(PVOID address)
{
PLIST_ENTRY current_entry;
{
Peb = CurrentProcess->Peb;
}
-
+
if (NULL == Peb)
{
DbgPrint("<%x>", address);
return(TRUE);
}
current_entry = Ldr->InLoadOrderModuleList.Flink;
-
+
while (current_entry != &Ldr->InLoadOrderModuleList &&
current_entry != NULL)
{
- current =
+ current =
CONTAINING_RECORD(current_entry, LDR_MODULE, InLoadOrderModuleList);
-
+
if (address >= (PVOID)current->BaseAddress &&
address < (PVOID)((char*)current->BaseAddress + current->ResidentSize))
{
- RelativeAddress =
+ RelativeAddress =
(ULONG_PTR) address - (ULONG_PTR)current->BaseAddress;
DbgPrint("<%wZ: %x>", ¤t->BaseDllName, RelativeAddress);
return(TRUE);
{
Er.NumberParameters = 0;
}
-
+
/* FIXME: Which exceptions are noncontinuable? */
Er.ExceptionFlags = 0;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/v86m.c
* PURPOSE: Support for v86 mode
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
KeV86GPF(PKV86M_TRAP_FRAME VTf, PKTRAP_FRAME Tf)
{
PUCHAR ip;
- PUSHORT sp;
+ PUSHORT sp;
PULONG dsp;
BOOL BigDataPrefix = FALSE;
BOOL BigAddressPrefix = FALSE;
DPRINT("KeV86GPF handling %x at %x:%x ss:sp %x:%x Flags %x\n",
ip[0], Tf->Cs, Tf->Eip, Tf->Ss, Tf->Esp, VTf->regs->Flags);
-
+
while (!Exit)
{
switch (ip[i])
}
Exit = TRUE;
break;
-
+
/* cli */
case 0xFA:
if (BigDataPrefix || BigAddressPrefix || RepPrefix)
}
Exit = TRUE;
break;
-
+
/* pushf */
case 0x9C:
if (RepPrefix)
}
Exit = TRUE;
break;
-
+
/* popf */
case 0x9D:
if (RepPrefix)
else
{
VTf->regs->Vif = 0;
- }
+ }
Tf->Eflags = Tf->Eflags | INTERRUPT_FLAG;
Tf->Esp = Tf->Esp + 2;
}
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
DPRINT("outb %d, %x\n", (ULONG)ip[i + 1], Tf->Eax & 0xFF);
- WRITE_PORT_UCHAR((PUCHAR)(ULONG)ip[i + 1],
+ WRITE_PORT_UCHAR((PUCHAR)(ULONG)ip[i + 1],
(UCHAR)(Tf->Eax & 0xFF));
Tf->Eip = Tf->Eip + 2;
return(0);
}
Exit = TRUE;
break;
-
+
/* out imm8, ax */
case 0xE7:
if (RepPrefix)
}
Exit = TRUE;
break;
-
+
/* out dx, ax */
case 0xEF:
if (RepPrefix)
if (!BigDataPrefix)
{
DPRINT("outw %d, %x\n", Tf->Edx & 0xFFFF, Tf->Eax & 0xFFFF);
- WRITE_PORT_USHORT((PUSHORT)(Tf->Edx & 0xFFFF),
+ WRITE_PORT_USHORT((PUSHORT)(Tf->Edx & 0xFFFF),
(USHORT)(Tf->Eax & 0xFFFF));
}
else
{
DPRINT("outl %d, %x\n", Tf->Edx & 0xFFFF, Tf->Eax);
- WRITE_PORT_ULONG((PULONG)(Tf->Edx & 0xFFFF),
+ WRITE_PORT_ULONG((PULONG)(Tf->Edx & 0xFFFF),
Tf->Eax);
}
Tf->Eip = Tf->Eip + 1;
}
Exit = TRUE;
break;
-
+
/* in al, imm8 */
case 0xE4:
if (RepPrefix)
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
UCHAR v;
-
+
v = READ_PORT_UCHAR((PUCHAR)(ULONG)ip[1]);
DPRINT("inb %d\t%X\n", (ULONG)ip[1], v);
Tf->Eax = Tf->Eax & (~0xFF);
}
Exit = TRUE;
break;
-
+
/* in ax, imm8 */
case 0xE5:
if (RepPrefix)
return(1);
}
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
- {
+ {
if (!BigDataPrefix)
{
USHORT v;
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
{
UCHAR v;
-
+
v = READ_PORT_UCHAR((PUCHAR)(Tf->Edx & 0xFFFF));
DPRINT("inb %d\t%X\n", Tf->Edx & 0xFFFF, v);
Tf->Eax = Tf->Eax & (~0xFF);
}
Exit = TRUE;
break;
-
+
/* in ax, dx */
case 0xED:
if (RepPrefix)
PUCHAR Port;
PUCHAR Buffer;
ULONG Offset;
-
+
Count = 1;
if (RepPrefix)
{
{
Buffer--;
}
- }
+ }
Tf->Eip++;
return(0);
}
PUSHORT BufferS = NULL;
PULONG BufferL = NULL;
ULONG Offset;
-
+
Count = 1;
if (RepPrefix)
{
BufferS--;
}
}
- }
+ }
Tf->Eip++;
return(0);
}
Exit = TRUE;
break;
-
+
/* insb */
case 0x6C:
if (VTf->regs->Flags & KV86M_ALLOW_IO_PORT_ACCESS)
PUCHAR Port;
PUCHAR Buffer;
ULONG Offset;
-
+
Count = 1;
if (RepPrefix)
{
{
Buffer--;
}
- }
+ }
Tf->Eip++;
return(0);
}
PUSHORT BufferS = NULL;
PULONG BufferL = NULL;
ULONG Offset;
-
+
Count = 1;
if (RepPrefix)
{
BufferS--;
}
}
- }
+ }
Tf->Eip++;
return(0);
}
{
unsigned int inum;
unsigned int entry;
-
+
inum = ip[1];
entry = ((unsigned int *)0)[inum];
-
+
Tf->Esp = Tf->Esp - 6;
sp = sp - 3;
-
+
sp[0] = (USHORT)((Tf->Eip & 0xFFFF) + 2);
sp[1] = (USHORT)(Tf->Cs & 0xFFFF);
sp[2] = (USHORT)(Tf->Eflags & 0xFFFF);
Tf->Eip = entry & 0xFFFF;
Tf->Cs = entry >> 16;
Tf->Eflags = Tf->Eflags & (~TRAP_FLAG);
-
+
return(0);
}
}
-
+
/* FIXME: Also emulate ins and outs */
/* FIXME: Handle opcode prefixes */
/* FIXME: Don't allow the BIOS to write to sensitive I/O ports */
}
-
+
DPRINT1("V86GPF unhandled (was %x)\n", ip[i]);
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Segment not present */
case 11:
- *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;;
+ *VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
/* Stack fault */
case 16:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
return(1);
-
+
/* Alignment check */
case 17:
*VTf->regs->PStatus = STATUS_NONCONTINUABLE_EXCEPTION;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/vdm.c
* PURPOSE: Virtual DOS machine support
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/* FIXME: This should use ->VdmObjects */
KeGetCurrentProcess()->Unused = 1;
Ki386RetToV86Mode(&V86Registers, &V86Registers);
-
+
/* FIXME: This should use ->VdmObjects */
KeGetCurrentProcess()->Unused = 0;
* PURPOSE: IPI Routines (Inter-Processor Interrupts). NT5+
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
- * Hartmut Birr
+ * Hartmut Birr
*/
/* INCLUDES *****************************************************************/
/* FUNCTIONS *****************************************************************/
-VOID
+VOID
KiIpiSendRequest(ULONG TargetSet, ULONG IpiRequest)
{
ULONG i;
KiIpiServiceRoutine(IN PKTRAP_FRAME TrapFrame,
IN PKEXCEPTION_FRAME ExceptionFrame)
{
-#ifdef DBG
+#ifdef DBG
LARGE_INTEGER StartTime, CurrentTime, Frequency;
ULONG Count = 5;
-#endif
+#endif
PKPRCB Prcb;
ASSERT(KeGetCurrentIrql() == IPI_LEVEL);
InterlockedDecrementUL(&Prcb->SignalDone->CurrentPacket[1]);
if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
{
-#ifdef DBG
+#ifdef DBG
StartTime = KeQueryPerformanceCounter(&Frequency);
-#endif
+#endif
while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[1], 0, 0))
{
-#ifdef DBG
+#ifdef DBG
CurrentTime = KeQueryPerformanceCounter(NULL);
if (CurrentTime.QuadPart > StartTime.QuadPart + Count * Frequency.QuadPart)
{
DbgPrint("(%s:%d) CPU%d, waiting longer than %d seconds to start the ipi routine\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber(), Count);
KEBUGCHECK(0);
}
-#endif
+#endif
}
}
((VOID STDCALL(*)(PVOID))(Prcb->SignalDone->WorkerRoutine))(Prcb->SignalDone->CurrentPacket[0]);
Ke386TestAndClearBit(KeGetCurrentProcessorNumber(), &Prcb->SignalDone->TargetSet);
if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
{
-#ifdef DBG
+#ifdef DBG
StartTime = KeQueryPerformanceCounter(&Frequency);
-#endif
+#endif
while (0 != InterlockedCompareExchangeUL(&Prcb->SignalDone->TargetSet, 0, 0))
{
-#ifdef DBG
+#ifdef DBG
CurrentTime = KeQueryPerformanceCounter(NULL);
if (CurrentTime.QuadPart > StartTime.QuadPart + Count * Frequency.QuadPart)
{
DbgPrint("(%s:%d) CPU%d, waiting longer than %d seconds after executing the ipi routine\n", __FILE__,__LINE__, KeGetCurrentProcessorNumber(), Count);
KEBUGCHECK(0);
}
-#endif
+#endif
}
}
InterlockedExchangePointer(&Prcb->SignalDone, NULL);
TargetSet = (1 << KeNumberProcessors) - 1;
KiIpiSendPacket(TargetSet, Function, Argument, KeNumberProcessors, TRUE);
-
+
KiReleaseSpinLock(&KiIpiLock);
-
+
KeLowerIrql(oldIrql);
-
+
DPRINT("KeIpiGenericCall on CPU%d done\n", KeGetCurrentProcessorNumber());
}
* PURPOSE: ReactOS kernel
* FILE: ntoskrnl/ke/kqueue.c
* PURPOSE: Implement device queues
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Several optimizations and implement
* usage of Inserted flag + reformat and
* add debug output.
/* Initialize the Header */
DeviceQueue->Type = DeviceQueueObject;
DeviceQueue->Size = sizeof(KDEVICE_QUEUE);
-
+
/* Initialize the Listhead and Spinlock */
InitializeListHead(&DeviceQueue->DeviceListHead);
KeInitializeSpinLock(&DeviceQueue->Lock);
-
+
/* Set it as busy */
DeviceQueue->Busy=FALSE;
}
IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry)
{
BOOLEAN Inserted;
-
+
DPRINT("KeInsertDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
/* Lock the Queue */
KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
-
+
if (!DeviceQueue->Busy) {
-
+
/* Set it as busy */
Inserted = FALSE;
DeviceQueue->Busy = TRUE;
-
+
} else {
/* Insert it into the list */
- Inserted = TRUE;
- InsertTailList(&DeviceQueue->DeviceListHead,
+ Inserted = TRUE;
+ InsertTailList(&DeviceQueue->DeviceListHead,
&DeviceQueueEntry->DeviceListEntry);
-
-
+
+
}
-
+
/* Sert the Insert state into the entry */
DeviceQueueEntry->Inserted = Inserted;
-
+
/* Release lock and return */
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
return Inserted;
/*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
KeInsertByKeyDeviceQueue(IN PKDEVICE_QUEUE DeviceQueue,
IN PKDEVICE_QUEUE_ENTRY DeviceQueueEntry,
IN ULONG SortKey)
{
BOOLEAN Inserted;
-
+
DPRINT("KeInsertByKeyDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
/* Acquire the Lock */
KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
-
+
/* Set the Sort Key */
DeviceQueueEntry->SortKey=SortKey;
-
+
if (!DeviceQueue->Busy) {
-
+
DeviceQueue->Busy=TRUE;
Inserted = FALSE;
-
+
} else {
-
+
/* Insert new entry after the last entry with SortKey less or equal to passed-in SortKey */
InsertAscendingListFIFO(&DeviceQueue->DeviceListHead,
KDEVICE_QUEUE_ENTRY,
SortKey);
Inserted = TRUE;
}
-
+
/* Reset the Inserted State */
DeviceQueueEntry->Inserted = Inserted;
-
+
/* Release Lock and Return */
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
return Inserted;
{
PLIST_ENTRY ListEntry;
PKDEVICE_QUEUE_ENTRY ReturnEntry;
-
+
DPRINT("KeRemoveDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
+
/* Acquire the Lock */
KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
ASSERT(DeviceQueue->Busy);
-
+
/* An attempt to remove an entry from an empty (and busy) queue sets the queue idle */
if (IsListEmpty(&DeviceQueue->DeviceListHead)) {
DeviceQueue->Busy = FALSE;
ReturnEntry = NULL;
-
+
} else {
-
+
/* Remove the Entry from the List */
ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
- ReturnEntry = CONTAINING_RECORD(ListEntry,
+ ReturnEntry = CONTAINING_RECORD(ListEntry,
KDEVICE_QUEUE_ENTRY,
DeviceListEntry);
-
+
/* Set it as non-inserted */
ReturnEntry->Inserted = FALSE;
}
DPRINT("KeRemoveByKeyDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
-
+
/* Acquire the Lock */
KeAcquireSpinLockAtDpcLevel(&DeviceQueue->Lock);
ASSERT(DeviceQueue->Busy);
/* An attempt to remove an entry from an empty (and busy) queue sets the queue idle */
if (IsListEmpty(&DeviceQueue->DeviceListHead)) {
-
+
DeviceQueue->Busy = FALSE;
ReturnEntry = NULL;
-
+
} else {
-
+
/* Find entry with SortKey greater than or equal to the passed-in SortKey */
ListEntry = DeviceQueue->DeviceListHead.Flink;
while (ListEntry != &DeviceQueue->DeviceListHead) {
/* Get Entry */
- ReturnEntry = CONTAINING_RECORD(ListEntry,
+ ReturnEntry = CONTAINING_RECORD(ListEntry,
KDEVICE_QUEUE_ENTRY,
DeviceListEntry);
-
+
/* Check if keys match */
if (ReturnEntry->SortKey >= SortKey) break;
-
+
/* Move to next item */
ListEntry = ListEntry->Flink;
}
-
+
/* Check if we found something */
if (ListEntry == &DeviceQueue->DeviceListHead) {
-
+
/* Not found, return the first entry */
ListEntry = RemoveHeadList(&DeviceQueue->DeviceListHead);
- ReturnEntry = CONTAINING_RECORD(ListEntry,
+ ReturnEntry = CONTAINING_RECORD(ListEntry,
KDEVICE_QUEUE_ENTRY,
DeviceListEntry);
} else {
-
+
/* We found it, so just remove it */
RemoveEntryList(&ReturnEntry->DeviceListEntry);
}
-
+
/* Set it as non-inserted */
ReturnEntry->Inserted = FALSE;
}
-
+
/* Release lock and Return */
KeReleaseSpinLockFromDpcLevel(&DeviceQueue->Lock);
return ReturnEntry;
{
KIRQL OldIrql;
BOOLEAN OldState;
-
+
DPRINT("KeRemoveEntryDeviceQueue(DeviceQueue %x)\n", DeviceQueue);
ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
-
+
/* Acquire the Lock */
KeAcquireSpinLock(&DeviceQueue->Lock, &OldIrql);
-
+
/* Check/Set Old State */
if ((OldState = DeviceQueueEntry->Inserted)) {
-
+
/* Remove it */
DeviceQueueEntry->Inserted = FALSE;
RemoveEntryList(&DeviceQueueEntry->DeviceListEntry);
}
-
+
/* Unlock and return old state */
KeReleaseSpinLock(&DeviceQueue->Lock, OldIrql);
return OldState;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/kthread.c
* PURPOSE: Microkernel thread support
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* David Welch (welch@cwcom.net)
*/
/* FUNCTIONS *****************************************************************/
-STATIC
+STATIC
VOID
KiRequestReschedule(CCHAR Processor)
{
KiIpiSendRequest(1 << Processor, IPI_REQUEST_DPC);
}
-STATIC
+STATIC
VOID
-KiInsertIntoThreadList(KPRIORITY Priority,
+KiInsertIntoThreadList(KPRIORITY Priority,
PKTHREAD Thread)
{
ASSERT(Ready == Thread->State);
ASSERT(Thread->Priority == Priority);
-
+
if (Priority >= MAXIMUM_PRIORITY || Priority < LOW_PRIORITY) {
-
+
DPRINT1("Invalid thread priority (%d)\n", Priority);
KEBUGCHECK(0);
}
-
+
InsertTailList(&PriorityListHead[Priority], &Thread->WaitListEntry);
PriorityListMask |= (1 << Priority);
}
STATIC
-VOID
+VOID
KiRemoveFromThreadList(PKTHREAD Thread)
{
ASSERT(Ready == Thread->State);
RemoveEntryList(&Thread->WaitListEntry);
if (IsListEmpty(&PriorityListHead[(ULONG)Thread->Priority])) {
-
+
PriorityListMask &= ~(1 << Thread->Priority);
}
}
STATIC
-PKTHREAD
-KiScanThreadList(KPRIORITY Priority,
+PKTHREAD
+KiScanThreadList(KPRIORITY Priority,
KAFFINITY Affinity)
{
PLIST_ENTRY current_entry;
ULONG Mask;
Mask = (1 << Priority);
-
+
if (PriorityListMask & Mask) {
-
+
current_entry = PriorityListHead[Priority].Flink;
-
+
while (current_entry != &PriorityListHead[Priority]) {
-
+
current = CONTAINING_RECORD(current_entry, KTHREAD, WaitListEntry);
-
+
if (current->State != Ready) {
-
+
DPRINT1("%d/%d\n", ¤t, current->State);
}
-
+
ASSERT(current->State == Ready);
-
+
if (current->Affinity & Affinity) {
-
+
KiRemoveFromThreadList(current);
return(current);
}
-
+
current_entry = current_entry->Flink;
}
}
-
+
return(NULL);
}
-VOID
+VOID
STDCALL
KiDispatchThreadNoLock(ULONG NewThreadStatus)
{
CurrentThread, NewThreadStatus, CurrentThread->State);
CurrentThread->State = (UCHAR)NewThreadStatus;
-
+
if (NewThreadStatus == Ready) {
-
+
KiInsertIntoThreadList(CurrentThread->Priority,
CurrentThread);
}
Affinity = 1 << KeGetCurrentProcessorNumber();
-
+
for (CurrentPriority = HIGH_PRIORITY; CurrentPriority >= LOW_PRIORITY; CurrentPriority--) {
-
+
Candidate = KiScanThreadList(CurrentPriority, Affinity);
-
+
if (Candidate == CurrentThread) {
Candidate->State = Running;
- KeReleaseDispatcherDatabaseLockFromDpcLevel();
+ KeReleaseDispatcherDatabaseLockFromDpcLevel();
return;
}
-
+
if (Candidate != NULL) {
-
+
PKTHREAD OldThread;
PKTHREAD IdleThread;
IdleThread = KeGetCurrentPrcb()->IdleThread;
if (OldThread == IdleThread) {
-
+
IdleProcessorMask &= ~Affinity;
-
+
} else if (CurrentThread == IdleThread) {
-
+
IdleProcessorMask |= Affinity;
}
return;
}
}
-
+
DPRINT1("CRITICAL: No threads are ready (CPU%d)\n", KeGetCurrentProcessorNumber());
KEBUGCHECK(0);
}
VOID
STDCALL
-KiBlockThread(PNTSTATUS Status,
- UCHAR Alertable,
+KiBlockThread(PNTSTATUS Status,
+ UCHAR Alertable,
ULONG WaitMode,
UCHAR WaitReason)
{
PKWAIT_BLOCK WaitBlock;
if (Thread->ApcState.KernelApcPending) {
-
+
DPRINT("Dispatching Thread as ready (APC!)\n");
-
+
/* Remove Waits */
WaitBlock = Thread->WaitBlockList;
do {
WaitBlock = WaitBlock->NextWaitBlock;
} while (WaitBlock != Thread->WaitBlockList);
Thread->WaitBlockList = NULL;
-
+
/* Dispatch it and return status */
KiDispatchThreadNoLock (Ready);
if (Status != NULL) *Status = STATUS_KERNEL_APC;
Thread->Alertable = Alertable;
Thread->WaitMode = (UCHAR)WaitMode;
Thread->WaitReason = WaitReason;
-
+
/* Dispatch it and return status */
KiDispatchThreadNoLock(Waiting);
DPRINT("Dispatching Thread as blocked: %d\n", Thread->WaitStatus);
if (Status != NULL) *Status = Thread->WaitStatus;
}
-
+
DPRINT("Releasing Dispatcher Lock\n");
KfLowerIrql(Thread->WaitIrql);
}
-VOID
+VOID
STDCALL
KiDispatchThread(ULONG NewThreadStatus)
{
if (!DoneInitYet || KeGetCurrentPrcb()->IdleThread == NULL) {
return;
}
-
+
OldIrql = KeAcquireDispatcherDatabaseLock();
KiDispatchThreadNoLock(NewThreadStatus);
KeLowerIrql(OldIrql);
VOID
STDCALL
-KiUnblockThread(PKTHREAD Thread,
- PNTSTATUS WaitStatus,
+KiUnblockThread(PKTHREAD Thread,
+ PNTSTATUS WaitStatus,
KPRIORITY Increment)
{
if (Terminated == Thread->State) {
DPRINT("Can't unblock thread 0x%x because it's terminating\n",
Thread);
-
+
} else if (Ready == Thread->State ||
Running == Thread->State) {
-
+
DPRINT("Can't unblock thread 0x%x because it's %s\n",
Thread, (Thread->State == Ready ? "ready" : "running"));
-
+
} else {
-
+
ULONG Processor;
KAFFINITY Affinity;
/* No it's not... i'll fix it later-- Alex */
if (Thread->Priority < LOW_REALTIME_PRIORITY &&
Thread->BasePriority < LOW_REALTIME_PRIORITY - 2) {
-
+
if (!Thread->PriorityDecrement && !Thread->DisableBoost) {
-
+
Thread->Priority = Thread->BasePriority + Increment;
Thread->PriorityDecrement = Increment;
}
-
+
} else {
-
+
Thread->Quantum = Thread->QuantumReset;
}
-
+
if (WaitStatus != NULL) {
-
+
Thread->WaitStatus = *WaitStatus;
}
-
+
Thread->State = Ready;
KiInsertIntoThreadList(Thread->Priority, Thread);
Processor = KeGetCurrentProcessorNumber();
Affinity = Thread->Affinity;
-
+
if (!(IdleProcessorMask & (1 << Processor) & Affinity) &&
(IdleProcessorMask & ~(1 << Processor) & Affinity)) {
-
+
ULONG i;
-
+
for (i = 0; i < KeNumberProcessors - 1; i++) {
-
+
Processor++;
-
+
if (Processor >= KeNumberProcessors) {
-
+
Processor = 0;
}
-
+
if (IdleProcessorMask & (1 << Processor) & Affinity) {
-#if 0
+#if 0
/* FIXME:
- * Reschedule the threads on an other processor
+ * Reschedule the threads on an other processor
*/
KeReleaseDispatcherDatabaseLockFromDpcLevel();
KiRequestReschedule(Processor);
break;
}
}
- }
+ }
}
}
-VOID
+VOID
STDCALL
KiSuspendThreadKernelRoutine(PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
{
}
-VOID
+VOID
STDCALL
KiSuspendThreadNormalRoutine(PVOID NormalContext,
PVOID SystemArgument1,
PVOID SystemArgument2)
{
PKTHREAD CurrentThread = KeGetCurrentThread();
-
+
/* Non-alertable kernel-mode suspended wait */
DPRINT("Waiting...\n");
KeWaitForSingleObject(&CurrentThread->SuspendSemaphore,
/*
* @implemented
*/
-PKTHREAD
-STDCALL
+PKTHREAD
+STDCALL
KeGetCurrentThread(VOID)
{
#ifdef CONFIG_SMP
/*
* @implemented
*/
-KPROCESSOR_MODE
+KPROCESSOR_MODE
STDCALL
KeGetPreviousMode(VOID)
{
PKTHREAD Thread = KeGetCurrentThread();
PLIST_ENTRY CurrentEntry;
PKMUTANT Mutant;
-
+
DPRINT("KeRundownThread: %x\n", Thread);
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
while (!IsListEmpty(&Thread->MutantListHead)) {
-
+
/* Get the Mutant */
CurrentEntry = RemoveHeadList(&Thread->MutantListHead);
Mutant = CONTAINING_RECORD(CurrentEntry, KMUTANT, MutantListEntry);
ASSERT(Mutant->ApcDisable == 0);
-
+
/* Uncondtionally abandon it */
DPRINT("Abandonning the Mutant\n");
Mutant->Header.SignalState = 1;
Mutant->Abandoned = TRUE;
Mutant->OwnerThread = NULL;
RemoveEntryList(&Mutant->MutantListEntry);
-
+
/* Check if the Wait List isn't empty */
DPRINT("Checking whether to wake the Mutant\n");
if (!IsListEmpty(&Mutant->Header.WaitListHead)) {
-
+
/* Wake the Mutant */
DPRINT("Waking the Mutant\n");
KiWaitTest(&Mutant->Header, MUTANT_INCREMENT);
}
}
-
+
/* Release the Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
}
{
ULONG PreviousCount;
KIRQL OldIrql;
-
+
DPRINT("KeResumeThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount);
/* Lock the Dispatcher */
/* Check if it existed */
if (PreviousCount) {
-
+
Thread->SuspendCount--;
-
+
/* Decrease the current Suspend Count and Check Freeze Count */
if ((!Thread->SuspendCount) && (!Thread->FreezeCount)) {
-
+
/* Signal the Suspend Semaphore */
Thread->SuspendSemaphore.Header.SignalState++;
KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
}
}
-
+
/* Release Lock and return the Old State */
KeReleaseDispatcherDatabaseLock(OldIrql);
return PreviousCount;
/* Acquire Lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Loop the Process's Threads */
CurrentEntry = Process->ThreadListHead.Flink;
while (CurrentEntry != &Process->ThreadListHead)
{
/* Get the Thread */
Current = CONTAINING_RECORD(CurrentEntry, KTHREAD, ThreadListEntry);
-
+
/* Make sure it's not ours */
if (Current == CurrentThread) continue;
-
+
/* Make sure it wasn't already frozen, and that it's not suspended */
if (!(++Current->FreezeCount) && !(Current->SuspendCount))
{
/* Insert the APC */
- if (!KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT))
+ if (!KiInsertQueueApc(&Current->SuspendApc, IO_NO_INCREMENT))
{
/* Unsignal the Semaphore, the APC already got inserted */
Current->SuspendSemaphore.Header.SignalState--;
/* Release the lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
}
-
+
NTSTATUS
STDCALL
KeSuspendThread(PKTHREAD Thread)
KIRQL OldIrql;
DPRINT("KeSuspendThread (Thread %p called). %x, %x\n", Thread, Thread->SuspendCount, Thread->FreezeCount);
-
+
/* Lock the Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Save the Old Count */
PreviousCount = Thread->SuspendCount;
-
+
/* Increment it */
Thread->SuspendCount++;
-
+
/* Check if we should suspend it */
if (!PreviousCount && !Thread->FreezeCount) {
-
+
/* Insert the APC */
if (!KiInsertQueueApc(&Thread->SuspendApc, IO_NO_INCREMENT)) {
-
+
/* Unsignal the Semaphore, the APC already got inserted */
Thread->SuspendSemaphore.Header.SignalState--;
}
}
-
+
/* Release Lock and return the Old State */
KeReleaseDispatcherDatabaseLock(OldIrql);
return PreviousCount;
{
KIRQL OldIrql;
ULONG PreviousCount;
-
+
/* Lock the Dispatcher Database and the APC Queue */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Save the old Suspend Count */
- PreviousCount = Thread->SuspendCount + Thread->FreezeCount;
-
+ PreviousCount = Thread->SuspendCount + Thread->FreezeCount;
+
/* If the thread is suspended, wake it up!!! */
if (PreviousCount) {
-
+
/* Unwait it completely */
Thread->SuspendCount = 0;
Thread->FreezeCount = 0;
-
+
/* Signal and satisfy */
Thread->SuspendSemaphore.Header.SignalState++;
KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
}
-
+
/* Release Lock and return the Old State */
KeReleaseDispatcherDatabaseLock(OldIrql);
return PreviousCount;
KIRQL OldIrql;
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
-
+
/* Lock the Dispatcher Database and the APC Queue */
OldIrql = KeAcquireDispatcherDatabaseLock();
KiAcquireSpinLock(&Thread->ApcQueueLock);
/* Return if Thread is already alerted. */
if (Thread->Alerted[KernelMode] == FALSE) {
-
+
/* If it's Blocked, unblock if it we should */
if (Thread->State == Waiting && Thread->Alertable) {
-
+
DPRINT("Aborting Wait\n");
KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT);
-
+
} else {
-
+
/* If not, simply Alert it */
Thread->Alerted[KernelMode] = TRUE;
}
}
-
+
/* Save the old Suspend Count */
- PreviousCount = Thread->SuspendCount;
-
+ PreviousCount = Thread->SuspendCount;
+
/* If the thread is suspended, decrease one of the suspend counts */
if (PreviousCount) {
-
+
/* Decrease count. If we are now zero, unwait it completely */
if (--Thread->SuspendCount) {
-
+
/* Signal and satisfy */
Thread->SuspendSemaphore.Header.SignalState++;
KiWaitTest(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT);
BOOLEAN
STDCALL
-KeAlertThread(PKTHREAD Thread,
+KeAlertThread(PKTHREAD Thread,
KPROCESSOR_MODE AlertMode)
{
KIRQL OldIrql;
/* Acquire the Dispatcher Database Lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Save the Previous State */
PreviousState = Thread->Alerted[AlertMode];
-
+
/* Return if Thread is already alerted. */
if (PreviousState == FALSE) {
-
+
/* If it's Blocked, unblock if it we should */
- if (Thread->State == Waiting &&
+ if (Thread->State == Waiting &&
(AlertMode == KernelMode || Thread->WaitMode == AlertMode) &&
Thread->Alertable) {
-
+
DPRINT("Aborting Wait\n");
KiAbortWaitThread(Thread, STATUS_ALERTED, THREAD_ALERT_INCREMENT);
-
+
} else {
-
+
/* If not, simply Alert it */
Thread->Alerted[AlertMode] = TRUE;
}
}
-
+
/* Release the Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
/* Return the old state */
return PreviousState;
}
*/
VOID
STDCALL
-KeInitializeThread(PKPROCESS Process,
- PKTHREAD Thread,
+KeInitializeThread(PKPROCESS Process,
+ PKTHREAD Thread,
PKSYSTEM_ROUTINE SystemRoutine,
PKSTART_ROUTINE StartRoutine,
PVOID StartContext,
PCONTEXT Context,
PVOID Teb,
PVOID KernelStack)
-{
+{
/* Initalize the Dispatcher Header */
DPRINT("Initializing Dispatcher Header for New Thread: %x in Process: %x\n", Thread, Process);
KeInitializeDispatcherHeader(&Thread->DispatcherHeader,
ThreadObject,
sizeof(KTHREAD),
FALSE);
-
+
DPRINT("Thread Header Created. SystemRoutine: %x, StartRoutine: %x with Context: %x\n",
SystemRoutine, StartRoutine, StartContext);
DPRINT("UserMode Information. Context: %x, Teb: %x\n", Context, Teb);
-
+
/* Initialize the Mutant List */
InitializeListHead(&Thread->MutantListHead);
-
+
/* Setup the Service Descriptor Table for Native Calls */
Thread->ServiceTable = KeServiceDescriptorTable;
-
+
/* Setup APC Fields */
InitializeListHead(&Thread->ApcState.ApcListHead[0]);
InitializeListHead(&Thread->ApcState.ApcListHead[1]);
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStateIndex = OriginalApcEnvironment;
KeInitializeSpinLock(&Thread->ApcQueueLock);
-
- /* Initialize the Suspend APC */
+
+ /* Initialize the Suspend APC */
KeInitializeApc(&Thread->SuspendApc,
Thread,
OriginalApcEnvironment,
KiSuspendThreadNormalRoutine,
KernelMode,
NULL);
-
+
/* Initialize the Suspend Semaphore */
- KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
-
+ KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128);
+
/* FIXME OPTIMIZATION OF DOOM. DO NOT ENABLE FIXME */
#if 0
Thread->WaitBlock[3].Object = (PVOID)&Thread->Timer;
&Thread->WaitBlock[3].WaitListEntry);
#endif
KeInitializeTimer(&Thread->Timer);
-
+
/* Set the TEB */
Thread->Teb = Teb;
-
+
/* Set the Thread Stacks */
Thread->InitialStack = (PCHAR)KernelStack + MM_STACK_SIZE;
Thread->StackBase = (PCHAR)KernelStack + MM_STACK_SIZE;
Thread->StackLimit = (ULONG_PTR)KernelStack;
Thread->KernelStackResident = TRUE;
-
- /*
- * Establish the pde's for the new stack and the thread structure within the
+
+ /*
+ * Establish the pde's for the new stack and the thread structure within the
* address space of the new process. They are accessed while taskswitching or
- * while handling page faults. At this point it isn't possible to call the
- * page fault handler for the missing pde's.
+ * while handling page faults. At this point it isn't possible to call the
+ * page fault handler for the missing pde's.
*/
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
-
+
/* Initalize the Thread Context */
DPRINT("Initializing the Context for the thread: %x\n", Thread);
- KiArchInitThreadWithContext(Thread,
+ KiArchInitThreadWithContext(Thread,
SystemRoutine,
StartRoutine,
StartContext,
Context);
-
+
/* Setup scheduler Fields based on Parent */
DPRINT("Thread context created, setting Scheduler Data\n");
Thread->BasePriority = Process->BasePriority;
Thread->DisableBoost = Process->DisableBoost;
Thread->AutoAlignment = Process->AutoAlignment;
Thread->Iopl = Process->Iopl;
-
+
/* Set the Thread to initalized */
Thread->State = Initialized;
-
- /*
- * Insert the Thread into the Process's Thread List
+
+ /*
+ * Insert the Thread into the Process's Thread List
* Note, this is the KTHREAD Thread List. It is removed in
* ke/kthread.c!KeTerminateThread.
*/
{
/* Return the User Time */
*UserTime = Thread->UserTime;
-
+
/* Return the Kernel Time */
return Thread->KernelTime;
}
PKTHREAD Thread = KeGetCurrentThread();
BOOLEAN PreviousState;
KIRQL OldIrql;
-
+
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* No, Release Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
/* Return Old State */
return PreviousState;
}
KIRQL OldIrql;
ASSERT(CurrentThread->SystemAffinityActive != FALSE);
-
+
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Disable System Affinity */
CurrentThread->SystemAffinityActive = FALSE;
-
+
/* Check if we need to Dispatch a New thread */
if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber())) {
-
+
/* No, just release */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
} else {
-
+
/* We need to dispatch a new thread */
CurrentThread->WaitIrql = OldIrql;
KiDispatchThreadNoLock(Ready);
{
CCHAR PreviousIdealProcessor;
KIRQL OldIrql;
-
+
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Set New Ideal Processor */
Thread->IdealProcessor = Processor;
-
+
/* Release Lock */
- KeReleaseDispatcherDatabaseLock(OldIrql);
-
+ KeReleaseDispatcherDatabaseLock(OldIrql);
+
/* Return Old Ideal Processor */
return PreviousIdealProcessor;
}
KIRQL OldIrql;
ASSERT(Affinity & ((1 << KeNumberProcessors) - 1));
-
+
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Enable System Affinity */
CurrentThread->SystemAffinityActive = TRUE;
-
+
/* Check if we need to Dispatch a New thread */
if (Affinity & (1 << KeGetCurrentProcessorNumber())) {
-
+
/* No, just release */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
} else {
-
+
/* We need to dispatch a new thread */
CurrentThread->WaitIrql = OldIrql;
KiDispatchThreadNoLock(Ready);
/*
* @implemented
*/
-KPRIORITY
+KPRIORITY
STDCALL
-KeSetPriorityThread(PKTHREAD Thread,
+KeSetPriorityThread(PKTHREAD Thread,
KPRIORITY Priority)
{
KPRIORITY OldPriority;
PKPCR Pcr;
if (Priority < LOW_PRIORITY || Priority >= MAXIMUM_PRIORITY) {
-
+
KEBUGCHECK(0);
}
OldPriority = Thread->Priority;
if (OldPriority != Priority) {
-
+
CurrentThread = KeGetCurrentThread();
-
+
if (Thread->State == Ready) {
-
+
KiRemoveFromThreadList(Thread);
Thread->BasePriority = Thread->Priority = (CHAR)Priority;
KiInsertIntoThreadList(Priority, Thread);
-
+
if (CurrentThread->Priority < Priority) {
-
+
KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
return (OldPriority);
}
-
+
} else if (Thread->State == Running) {
-
+
Thread->BasePriority = Thread->Priority = (CHAR)Priority;
-
+
if (Priority < OldPriority) {
-
+
/* Check for threads with a higher priority */
Mask = ~((1 << (Priority + 1)) - 1);
if (PriorityListMask & Mask) {
-
+
if (Thread == CurrentThread) {
-
+
KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
return (OldPriority);
-
+
} else {
-
+
for (i = 0; i < KeNumberProcessors; i++) {
-
+
Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
-
+
if (Pcr->Prcb->CurrentThread == Thread) {
KeReleaseDispatcherDatabaseLockFromDpcLevel();
}
}
} else {
-
+
Thread->BasePriority = Thread->Priority = (CHAR)Priority;
}
}
-
+
KeReleaseDispatcherDatabaseLock(OldIrql);
return(OldPriority);
}
*
* Sets thread's affinity
*/
-NTSTATUS
+NTSTATUS
STDCALL
KeSetAffinityThread(PKTHREAD Thread,
KAFFINITY Affinity)
OldIrql = KeAcquireDispatcherDatabaseLock();
Thread->UserAffinity = Affinity;
-
+
if (Thread->SystemAffinityActive == FALSE) {
-
+
Thread->Affinity = Affinity;
-
+
if (Thread->State == Running) {
-
+
ProcessorMask = 1 << KeGetCurrentKPCR()->ProcessorNumber;
if (Thread == KeGetCurrentThread()) {
-
+
if (!(Affinity & ProcessorMask)) {
-
+
KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
return STATUS_SUCCESS;
}
-
+
} else {
-
+
for (i = 0; i < KeNumberProcessors; i++) {
-
+
Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
if (Pcr->Prcb->CurrentThread == Thread) {
-
+
if (!(Affinity & ProcessorMask)) {
-
+
KeReleaseDispatcherDatabaseLockFromDpcLevel();
KiRequestReschedule(i);
KeLowerIrql(OldIrql);
return STATUS_SUCCESS;
}
-
+
break;
}
}
}
}
}
-
+
KeReleaseDispatcherDatabaseLock(OldIrql);
return STATUS_SUCCESS;
}
{
KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread();
-
+
/* Lock the Dispatcher Database and the APC Queue */
DPRINT("Terminating\n");
OldIrql = KeAcquireDispatcherDatabaseLock();
/* Remove the thread from the list */
RemoveEntryList(&Thread->ThreadListEntry);
-
+
/* Insert into the Reaper List */
DPRINT("List: %p\n", PspReaperList);
((PETHREAD)Thread)->ReaperLink = PspReaperList;
PspReaperList = (PETHREAD)Thread;
DPRINT("List: %p\n", PspReaperList);
-
+
/* Check if it's active */
if (PspReaping == FALSE) {
-
+
/* Activate it. We use the internal function for speed, and use the Hyper Critical Queue */
PspReaping = TRUE;
DPRINT("Terminating\n");
&PspReaperWorkItem.List,
FALSE);
}
-
+
/* Handle Kernel Queues */
if (Thread->Queue) {
-
+
DPRINT("Waking Queue\n");
RemoveEntryList(&Thread->QueueListEntry);
KiWakeQueue(Thread->Queue);
}
-
+
/* Signal the thread */
Thread->DispatcherHeader.SignalState = TRUE;
if (IsListEmpty(&Thread->DispatcherHeader.WaitListHead) != TRUE) {
-
+
/* Satisfy waits */
KiWaitTest((PVOID)Thread, Increment);
}
-
+
/* Find a new Thread */
KiDispatchThreadNoLock(Terminated);
}
KIRQL OldIrql;
PKTHREAD Thread = KeGetCurrentThread();
BOOLEAN OldState;
-
+
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
-
+
/* Lock the Dispatcher Database and the APC Queue */
OldIrql = KeAcquireDispatcherDatabaseLock();
KiAcquireSpinLock(&Thread->ApcQueueLock);
-
+
/* Save the old State */
OldState = Thread->Alerted[AlertMode];
-
+
/* If the Thread is Alerted, Clear it */
if (OldState) {
-
+
Thread->Alerted[AlertMode] = FALSE;
-
+
} else if ((AlertMode == UserMode) && (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) {
-
+
/* If the mode is User and the Queue isn't empty, set Pending */
Thread->ApcState.UserApcPending = TRUE;
}
-
+
/* Release Locks and return the Old State */
KiReleaseSpinLock(&Thread->ApcQueueLock);
KeReleaseDispatcherDatabaseLock(OldIrql);
KiServiceCheck (VOID)
{
PKTHREAD Thread = KeGetCurrentThread();
-
+
/* Check if we need to inialize Win32 for this Thread */
if (Thread->ServiceTable != KeServiceDescriptorTableShadow) {
-
- /* We do. Initialize it and save the new table */
+
+ /* We do. Initialize it and save the new table */
PsInitWin32Thread((PETHREAD)Thread);
Thread->ServiceTable = KeServiceDescriptorTableShadow;
}
}
-/*
+/*
*
* NOT EXPORTED
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtAlertResumeThread(IN HANDLE ThreadHandle,
OUT PULONG SuspendCount)
/* Check if parameters are valid */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(SuspendCount,
sizeof(HANDLE),
sizeof(ULONG));
-
+
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
-
+
/* Reference the Object */
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_SUSPEND_RESUME,
PreviousMode,
(PVOID*)&Thread,
NULL);
-
- /* Check for Success */
+
+ /* Check for Success */
if (NT_SUCCESS(Status)) {
-
+
/* Call the Kernel Function */
PreviousState = KeAlertResumeThread(&Thread->Tcb);
-
+
/* Dereference Object */
ObDereferenceObject(Thread);
-
+
if (SuspendCount) {
-
+
_SEH_TRY {
-
+
*SuspendCount = PreviousState;
-
+
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
}
-
+
/* Return status */
return Status;
}
-/*
+/*
* @implemented
*
* EXPORTED
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtAlertThread (IN HANDLE ThreadHandle)
{
PreviousMode,
(PVOID*)&Thread,
NULL);
-
- /* Check for Success */
+
+ /* Check for Success */
if (NT_SUCCESS(Status)) {
-
- /*
+
+ /*
* Do an alert depending on the processor mode. If some kmode code wants to
* enforce a umode alert it should call KeAlertThread() directly. If kmode
* code wants to do a kmode alert it's sufficient to call it with Zw or just
- * use KeAlertThread() directly
+ * use KeAlertThread() directly
*/
KeAlertThread(&Thread->Tcb, PreviousMode);
-
+
/* Dereference Object */
ObDereferenceObject(Thread);
}
-
+
/* Return status */
return Status;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtDelayExecution(IN BOOLEAN Alertable,
IN PLARGE_INTEGER DelayInterval)
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
LARGE_INTEGER SafeInterval;
NTSTATUS Status;
-
+
/* Check if parameters are valid */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForRead(DelayInterval,
sizeof(LARGE_INTEGER),
sizeof(ULONG));
-
+
/* make a copy on the kernel stack and let DelayInterval point to it so
we don't need to wrap KeDelayExecutionThread in SEH! */
SafeInterval = *DelayInterval;
-
+
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
} _SEH_END;
}
Status = KeDelayExecutionThread(PreviousMode,
Alertable,
&SafeInterval);
-
+
/* Return Status */
return Status;
}
KiSystemStartup(BOOLEAN BootProcessor)
{
DPRINT("KiSystemStartup(%d)\n", BootProcessor);
-
+
/* Initialize the Application Processor */
if (!BootProcessor) KeApplicationProcessorInit();
-
+
/* Initialize the Processor with HAL */
HalInitializeProcessor(KeNumberProcessors, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
/* Load the Kernel if this is the Boot CPU, else inialize the App CPU only */
if (BootProcessor) {
-
+
/* Initialize the Kernel Executive */
ExpInitializeExecutive();
-
+
/* Free Initial Memory */
MiFreeInitMemory();
-
+
/* Never returns */
#if 0
/* FIXME:
Timeout.QuadPart = 0x7fffffffffffffffLL;
KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
}
-#endif
+#endif
} else {
-
+
/* Do application processor initialization */
KeApplicationProcessorInitDispatcher();
-
+
/* Lower IRQL and go to Idle Thread */
KeLowerIrql(PASSIVE_LEVEL);
PsIdleThreadMain(NULL);
}
-
+
/* Bug Check and loop forever if anything failed */
KEBUGCHECK(0);
for(;;);
/*
* FUNCTION: Called by the boot loader to start the kernel
* ARGUMENTS:
- * LoaderBlock = Pointer to boot parameters initialized by the boot
+ * LoaderBlock = Pointer to boot parameters initialized by the boot
* loader
* NOTE: The boot parameters are stored in low memory which will become
* invalid after the memory managment is initialized so we make a local copy.
*/
-VOID
+VOID
INIT_FUNCTION
-_main(ULONG MultiBootMagic,
+_main(ULONG MultiBootMagic,
PLOADER_PARAMETER_BLOCK _LoaderBlock)
{
ULONG i;
trap_stack_top = trap_stack + 3 * PAGE_SIZE;
init_stack = PAGE_ROUND_UP(&kernel_stack);
init_stack_top = init_stack + 3 * PAGE_SIZE;
-
+
/* Copy the Loader Block Data locally since Low-Memory will be wiped */
memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
- memcpy(&KeLoaderModules[1],
+ memcpy(&KeLoaderModules[1],
(PVOID)KeLoaderBlock.ModsAddr,
sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
KeLoaderBlock.ModsCount++;
/* Save the Base Address */
MmSystemRangeStart = (PVOID)KeLoaderBlock.KernelBase;
-
+
/* Set the Command Line */
strcpy(KeLoaderCommandLine, (PCHAR)_LoaderBlock->CommandLine);
KeLoaderBlock.CommandLine = (ULONG)KeLoaderCommandLine;
-
+
/* Write the first Module (the Kernel) */
strcpy(KeLoaderModuleStrings[0], "ntoskrnl.exe");
KeLoaderModules[0].String = (ULONG)KeLoaderModuleStrings[0];
KeLoaderModules[0].ModStart = KERNEL_BASE;
-
+
/* Read PE Data */
NtHeader = RtlImageNtHeader((PVOID)KeLoaderModules[0].ModStart);
OptHead = &NtHeader->OptionalHeader;
-
+
/* Set Kernel Ending */
KeLoaderModules[0].ModEnd = KeLoaderModules[0].ModStart + PAGE_ROUND_UP((ULONG)OptHead->SizeOfImage);
-
+
/* Create a block for each module */
- for (i = 1; i < KeLoaderBlock.ModsCount; i++) {
-
+ for (i = 1; i < KeLoaderBlock.ModsCount; i++) {
+
/* Check if we have to copy the path or not */
if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0) {
-
+
strcpy(KeLoaderModuleStrings[i], s + 1);
-
+
} else {
-
+
strcpy(KeLoaderModuleStrings[i], (PCHAR)KeLoaderModules[i].String);
}
-
- /* Substract the base Address in Physical Memory */
+
+ /* Substract the base Address in Physical Memory */
KeLoaderModules[i].ModStart -= 0x200000;
-
+
/* Add the Kernel Base Address in Virtual Memory */
KeLoaderModules[i].ModStart += KERNEL_BASE;
-
- /* Substract the base Address in Physical Memory */
+
+ /* Substract the base Address in Physical Memory */
KeLoaderModules[i].ModEnd -= 0x200000;
-
+
/* Add the Kernel Base Address in Virtual Memory */
KeLoaderModules[i].ModEnd += KERNEL_BASE;
-
+
/* Select the proper String */
KeLoaderModules[i].String = (ULONG)KeLoaderModuleStrings[i];
}
/* Low level architecture specific initialization */
KeInit1((PCHAR)KeLoaderBlock.CommandLine, &LastKernelAddress);
-
+
/* Select the HAL Base */
HalBase = KeLoaderModules[1].ModStart;
-
+
/* Choose Driver Base */
DriverBase = LastKernelAddress;
LdrHalBase = (ULONG_PTR)DriverBase;
-
+
/* Initialize Module Management */
LdrInitModuleManagement();
-
+
/* Load HAL.DLL with the PE Loader */
- LdrSafePEProcessModule((PVOID)HalBase,
- (PVOID)DriverBase,
- (PVOID)KERNEL_BASE,
+ LdrSafePEProcessModule((PVOID)HalBase,
+ (PVOID)DriverBase,
+ (PVOID)KERNEL_BASE,
&DriverSize);
-
+
/* Increase the last kernel address with the size of HAL */
LastKernelAddress += PAGE_ROUND_UP(DriverSize);
/* Load the Kernel with the PE Loader */
- LdrSafePEProcessModule((PVOID)KERNEL_BASE,
- (PVOID)KERNEL_BASE,
+ LdrSafePEProcessModule((PVOID)KERNEL_BASE,
+ (PVOID)KERNEL_BASE,
(PVOID)DriverBase,
&DriverSize);
KeMemoryMapRangeCount = 0;
if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO) {
-
+
/* We have a memory map from the nice BIOS */
size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
i = 0;
-
+
/* Map it until we run out of size */
while (i < KeLoaderBlock.MmapLength) {
-
+
/* Copy into the Kernel Memory Map */
memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
(PVOID)(KeLoaderBlock.MmapAddr + i),
sizeof(ADDRESS_RANGE));
-
+
/* Increase Memory Map Count */
KeMemoryMapRangeCount++;
-
+
/* Increase Size */
i += size;
}
-
+
/* Save data */
KeLoaderBlock.MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
-
+
} else {
-
+
/* Nothing from BIOS */
KeLoaderBlock.MmapLength = 0;
KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
}
-
+
/* Initialize the Debugger */
KdInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-
+
/* Initialize HAL */
HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/mutex.c
* PURPOSE: Implements Mutexes and Mutants (that silly davec...)
- *
- * PROGRAMMERS:
+ *
+ * PROGRAMMERS:
* Alex Ionescu (alex@relsoft.net) - Reorganized/commented some of the code.
* Simplified some functions, fixed some return values and
* corrected some minor bugs, added debug output.
/*
* @implemented
*/
-VOID
+VOID
STDCALL
KeInitializeMutant(IN PKMUTANT Mutant,
IN BOOLEAN InitialOwner)
ULONG Signaled = TRUE;
PKTHREAD CurrentThread = NULL;
KIRQL OldIrql;
-
+
DPRINT("KeInitializeMutant: %x\n", Mutant);
-
+
/* Check if we have an initial owner */
if (InitialOwner == TRUE) {
-
+
/* In this case, the object is not signaled */
Signaled = FALSE;
-
+
/* We also need to associate a thread */
CurrentThread = KeGetCurrentThread();
-
+
/* We're about to touch the Thread, so lock the Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* And insert it into its list */
InsertTailList(&CurrentThread->MutantListHead, &Mutant->MutantListEntry);
-
+
/* Release Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
DPRINT("Mutant with Initial Owner\n");
-
+
} else {
-
+
/* In this case, we don't have an owner yet */
Mutant->OwnerThread = NULL;
}
-
+
/* Now we set up the Dispatcher Header */
KeInitializeDispatcherHeader(&Mutant->Header,
MutantObject,
/*
* @implemented
*/
-VOID
+VOID
STDCALL
KeInitializeMutex(IN PKMUTEX Mutex,
IN ULONG Level)
{
DPRINT("KeInitializeMutex: %x\n", Mutex);
-
-
+
+
/* Set up the Dispatcher Header */
KeInitializeDispatcherHeader(&Mutex->Header,
MutantObject,
sizeof(KMUTEX) / sizeof(ULONG),
1);
-
+
/* Initialize the default data */
Mutex->OwnerThread = NULL;
Mutex->Abandoned = FALSE;
/*
* @implemented
*/
-LONG
+LONG
STDCALL
KeReadStateMutant(IN PKMUTANT Mutant)
{
/*
* @implemented
*/
-LONG
+LONG
STDCALL
KeReleaseMutant(IN PKMUTANT Mutant,
IN KPRIORITY Increment,
KIRQL OldIrql;
LONG PreviousState;
PKTHREAD CurrentThread = KeGetCurrentThread();
-
+
DPRINT("KeReleaseMutant: %x\n", Mutant);
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Save the Previous State */
PreviousState = Mutant->Header.SignalState;
-
+
/* Check if it is to be abandonned */
if (Abandon == FALSE) {
/* Make sure that the Owner Thread is the current Thread */
if (Mutant->OwnerThread != CurrentThread) {
-
+
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
DPRINT1("Trying to touch a Mutant that the caller doesn't own!\n");
ExRaiseStatus(STATUS_MUTANT_NOT_OWNED);
}
/* If the thread owns it, then increase the signal state */
Mutant->Header.SignalState++;
-
+
} else {
-
+
/* It's going to be abandonned */
DPRINT("Abandonning the Mutant\n");
Mutant->Header.SignalState = 1;
Mutant->Abandoned = TRUE;
}
-
+
/* Check if the signal state is only single */
if (Mutant->Header.SignalState == 1) {
-
+
/* Check if it's below 0 now */
if (PreviousState <= 0) {
-
+
/* Remove the mutant from the list */
DPRINT("Removing Mutant\n");
RemoveEntryList(&Mutant->MutantListEntry);
-
+
/* Reenable APCs */
DPRINT("Re-enabling APCs\n");
CurrentThread->KernelApcDisable += Mutant->ApcDisable;
-
+
/* Force an Interrupt if Apcs are pending */
if (!IsListEmpty(&CurrentThread->ApcState.ApcListHead[KernelMode])) {
-
+
/* Make sure they aren't disabled though */
if (!CurrentThread->KernelApcDisable) {
-
+
/* Request the Interrupt */
DPRINT("Requesting APC Interupt\n");
HalRequestSoftwareInterrupt(APC_LEVEL);
}
}
}
-
+
/* Remove the Owning Thread and wake it */
Mutant->OwnerThread = NULL;
-
+
/* Check if the Wait List isn't empty */
DPRINT("Checking whether to wake the Mutant\n");
if (!IsListEmpty(&Mutant->Header.WaitListHead)) {
-
+
/* Wake the Mutant */
DPRINT("Waking the Mutant\n");
KiWaitTest(&Mutant->Header, Increment);
/* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */
if (Wait == FALSE) {
-
+
/* Release the Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
} else {
-
+
/* Set a wait */
CurrentThread->WaitNext = TRUE;
CurrentThread->WaitIrql = OldIrql;
/*
* @implemented
*/
-LONG
+LONG
STDCALL
KeReleaseMutex(IN PKMUTEX Mutex,
IN BOOLEAN Wait)
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
KeWaitForMutexObject(IN PKMUTEX Mutex,
IN KWAIT_REASON WaitReason,
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/process.c
* PURPOSE: Attaching/Detaching and System Call Tables
- *
+ *
* PROGRAMMERS: Alex Ionescu (Implemented Attach/Detach and KeRemoveSystemServiceTable)
* Gregor Anich (Bugfixes to Attach Functions)
*/
{ NULL, NULL, 0, NULL }
};
-SSDT_ENTRY
+SSDT_ENTRY
KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] = {
{ MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
{ NULL, NULL, 0, NULL },
static inline void
UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process)
{
- /*
- * The stack and the thread structure of the current process may be
- * located in a page which is not present in the page directory of
- * the process we're attaching to. That would lead to a page fault
- * when this function returns. However, since the processor can't
- * call the page fault handler 'cause it can't push EIP on the stack,
+ /*
+ * The stack and the thread structure of the current process may be
+ * located in a page which is not present in the page directory of
+ * the process we're attaching to. That would lead to a page fault
+ * when this function returns. However, since the processor can't
+ * call the page fault handler 'cause it can't push EIP on the stack,
* this will show up as a stack fault which will crash the entire system.
* To prevent this, make sure the page directory of the process we're
- * attaching to is up-to-date.
+ * attaching to is up-to-date.
*/
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE);
MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
LARGE_INTEGER DirectoryTableBase)
{
DPRINT("KeInitializeProcess. Process: %x, DirectoryTableBase: %x\n", Process, DirectoryTableBase);
-
+
/* Initialize the Dispatcher Header */
KeInitializeDispatcherHeader(&Process->Header,
ProcessObject,
sizeof(KPROCESS),
FALSE);
-
+
/* Initialize Scheduler Data, Disable Alignment Faults and Set the PDE */
Process->Affinity = Affinity;
Process->BasePriority = Priority;
Process->AutoAlignment = TRUE;
Process->IopmOffset = 0xFFFF;
Process->State = PROCESS_STATE_ACTIVE;
-
+
/* Initialize the Thread List */
- InitializeListHead(&Process->ThreadListHead);
+ InitializeListHead(&Process->ThreadListHead);
DPRINT("The Process has now been initalized with the Kernel\n");
}
ULONG
STDCALL
-KeSetProcess(PKPROCESS Process,
+KeSetProcess(PKPROCESS Process,
KPRIORITY Increment)
{
KIRQL OldIrql;
ULONG OldState;
-
+
/* Lock Dispatcher */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Get Old State */
OldState = Process->Header.SignalState;
-
+
/* Signal the Process */
Process->Header.SignalState = TRUE;
if ((OldState == 0) && IsListEmpty(&Process->Header.WaitListHead) != TRUE) {
-
+
/* Satisfy waits */
KiWaitTest((PVOID)Process, Increment);
}
-
- /* Release Dispatcher Database */
+
+ /* Release Dispatcher Database */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
/* Return the previous State */
- return OldState;
+ return OldState;
}
/*
* @implemented
*/
-VOID
+VOID
STDCALL
KeAttachProcess(PKPROCESS Process)
{
/* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) {
-
+
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
}
/* Check if the Target Process is already attached */
if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) {
-
+
DPRINT("Process already Attached. Exitting\n");
KeReleaseDispatcherDatabaseLock(OldIrql);
- } else {
-
+ } else {
+
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
}
}
STDCALL
KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE SavedApcState)
{
-
+
DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", Thread, Process, SavedApcState);
-
+
/* Increase Stack Count */
Process->StackCount++;
/* Swap the APC Environment */
KiMoveApcState(&Thread->ApcState, SavedApcState);
-
+
/* Reinitialize Apc State */
InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]);
InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]);
Thread->ApcState.KernelApcInProgress = FALSE;
Thread->ApcState.KernelApcPending = FALSE;
Thread->ApcState.UserApcPending = FALSE;
-
+
/* Update Environment Pointers if needed*/
if (SavedApcState == &Thread->SavedApcState) {
-
+
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState;
Thread->ApcStateIndex = AttachedApcEnvironment;
}
-
+
/* Swap the Processes */
DPRINT("Swapping\n");
KiSwapProcess(Process, SavedApcState->Process);
-
+
/* Return to old IRQL*/
KeReleaseDispatcherDatabaseLock(ApcLock);
-
+
DPRINT("KiAttachProcess Completed Sucesfully\n");
}
VOID
STDCALL
-KiSwapProcess(PKPROCESS NewProcess,
- PKPROCESS OldProcess)
+KiSwapProcess(PKPROCESS NewProcess,
+ PKPROCESS OldProcess)
{
/* FIXME: Write this in ASM. Much easier */
DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart);
UpdatePageDirs(Thread, Process);
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Crash system if DPC is being executed! */
if (KeIsExecutingDpc()) {
-
+
DPRINT1("Invalid attach (Thread is executing a DPC!)\n");
KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT);
}
-
+
/* Check if the Target Process is already attached */
if (Thread->ApcState.Process == Process) {
-
+
ApcState->Process = (PKPROCESS)1; /* Meaning already attached to the same Process */
-
- } else {
-
+
+ } else {
+
/* Check if the Current Thread is already attached and call the Internal Function*/
if (Thread->ApcStateIndex != OriginalApcEnvironment) {
-
+
KiAttachProcess(Thread, Process, OldIrql, ApcState);
} else {
-
+
KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState);
- ApcState->Process = NULL;
+ ApcState->Process = NULL;
}
}
}
{
PKTHREAD Thread;
KIRQL OldIrql;
-
+
DPRINT("KeDetachProcess()\n");
-
+
/* Get Current Thread and Lock */
Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Check if it's attached */
DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex);
-
+
if (Thread->ApcStateIndex == OriginalApcEnvironment) {
-
+
DPRINT1("Invalid detach (thread was not attached)\n");
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
}
-
+
/* Decrease Stack Count */
Thread->ApcState.Process->StackCount--;
-
+
/* Restore the APC State */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState;
Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState;
Thread->ApcStateIndex = OriginalApcEnvironment;
-
+
/* Swap Processes */
KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process);
KIRQL OldIrql;
PKTHREAD Thread;
- /*
- * If the special "We tried to attach to the process already being
- * attached to" flag is there, don't do anything
+ /*
+ * If the special "We tried to attach to the process already being
+ * attached to" flag is there, don't do anything
*/
if (ApcState->Process == (PKPROCESS)1) return;
-
+
Thread = KeGetCurrentThread();
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Sorry Buddy, can't help you if you've got APCs or just aren't attached */
if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) {
-
+
DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n");
KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT);
}
-
+
/* Restore the Old APC State if a Process was present */
if (ApcState->Process) {
-
+
KiMoveApcState(ApcState, &Thread->ApcState);
-
+
} else {
-
+
/* The ApcState parameter is useless, so use the saved data and reset it */
KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState);
Thread->SavedApcState.Process = NULL;
ULONG TableIndex)
{
/* check if descriptor table entry is free */
- if ((TableIndex > SSDT_MAX_ENTRIES - 1) ||
+ if ((TableIndex > SSDT_MAX_ENTRIES - 1) ||
(KeServiceDescriptorTable[TableIndex].SSDT != NULL) ||
(KeServiceDescriptorTableShadow[TableIndex].SSDT != NULL))
return FALSE;
KeServiceDescriptorTableShadow[TableIndex].SSPT = SSPT;
KeServiceDescriptorTableShadow[TableIndex].NumberOfServices = NumberOfServices;
KeServiceDescriptorTableShadow[TableIndex].ServiceCounterTable = ServiceCounterTable;
-
+
return TRUE;
}
{
/* Make sure the Index is valid */
if (TableIndex > SSDT_MAX_ENTRIES - 1) return FALSE;
-
+
/* Is there a Normal Descriptor Table? */
if (!KeServiceDescriptorTable[TableIndex].SSDT) {
-
+
/* Not with the index, is there a shadow at least? */
if (!KeServiceDescriptorTableShadow[TableIndex].SSDT) return FALSE;
}
-
+
/* Now clear from the Shadow Table. */
KeServiceDescriptorTableShadow[TableIndex].SSDT = NULL;
KeServiceDescriptorTableShadow[TableIndex].SSPT = NULL;
KeServiceDescriptorTableShadow[TableIndex].NumberOfServices = 0;
KeServiceDescriptorTableShadow[TableIndex].ServiceCounterTable = NULL;
-
+
/* Check if we should clean from the Master one too */
if (TableIndex == 1) {
-
+
KeServiceDescriptorTable[TableIndex].SSDT = NULL;
KeServiceDescriptorTable[TableIndex].SSPT = NULL;
KeServiceDescriptorTable[TableIndex].NumberOfServices = 0;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/profile.c
* PURPOSE: Kernel Profiling
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* FUNCTIONS *****************************************************************/
-STDCALL
+STDCALL
VOID
KeInitializeProfile(PKPROFILE Profile,
PKPROCESS Process,
/* Initialize the Header */
Profile->Type = ProfileObject;
Profile->Size = sizeof(KPROFILE);
-
+
/* Copy all the settings we were given */
Profile->Process = Process;
Profile->RegionStart = ImageBase;
Profile->RegionEnd = (PVOID)(ULONG_PTR)ImageBase + ImageSize;
Profile->Active = FALSE;
Profile->Source = ProfileSource;
- Profile->Affinity = Affinity;
+ Profile->Affinity = Affinity;
}
STDCALL
BOOLEAN FreeBuffer = TRUE;
PKPROCESS ProfileProcess;
PLIST_ENTRY ListEntry;
-
+
/* Allocate a buffer first, before we raise IRQL */
- SourceBuffer = ExAllocatePoolWithTag(NonPagedPool,
+ SourceBuffer = ExAllocatePoolWithTag(NonPagedPool,
sizeof(KPROFILE_SOURCE_OBJECT),
TAG('P', 'r', 'o', 'f'));
RtlZeroMemory(Source, sizeof(KPROFILE_SOURCE_OBJECT));
-
+
/* Raise to PROFILE_LEVEL */
KeRaiseIrql(PROFILE_LEVEL, &OldIrql);
KeAcquireSpinLockAtDpcLevel(&KiProfileLock);
-
+
/* Make sure it's not running */
if (!Profile->Active) {
-
+
/* Set it as active */
Profile->Buffer = Buffer;
Profile->Active = TRUE;
-
+
/* Get the process, if any */
ProfileProcess = Profile->Process;
-
+
/* Insert it into the Process List or Global List */
if (ProfileProcess) {
-
+
InsertTailList(&ProfileProcess->ProfileListHead, &Profile->ListEntry);
-
+
} else {
-
+
InsertTailList(&KiProfileListHead, &Profile->ListEntry);
}
-
+
/* Check if this type of profile (source) is already running */
- for (ListEntry = KiProfileSourceListHead.Flink;
- ListEntry != &KiProfileSourceListHead;
+ for (ListEntry = KiProfileSourceListHead.Flink;
+ ListEntry != &KiProfileSourceListHead;
ListEntry = ListEntry->Flink) {
-
+
/* Get the Source Object */
- CurrentSource = CONTAINING_RECORD(ListEntry,
+ CurrentSource = CONTAINING_RECORD(ListEntry,
KPROFILE_SOURCE_OBJECT,
ListEntry);
-
+
/* Check if it's the same as the one being requested now */
if (CurrentSource->Source == Profile->Source) {
-
+
Source = CurrentSource;
break;
}
}
-
+
/* See if the loop found something */
if (!Source) {
-
+
/* Nothing found, use our allocated buffer */
Source = SourceBuffer;
-
+
/* Set up the Source Object */
Source->Source = Profile->Source;
InsertHeadList(&KiProfileSourceListHead, &Source->ListEntry);
-
+
/* Don't free the pool later on */
FreeBuffer = FALSE;
}
}
-
+
/* Lower the IRQL */
KeReleaseSpinLockFromDpcLevel(&KiProfileLock);
KeLowerIrql(OldIrql);
-
+
/* FIXME: Tell HAL to Start the Profile Interrupt */
//HalStartProfileInterrupt(Profile->Source);
-
+
/* Free the pool */
if (!FreeBuffer) ExFreePool(SourceBuffer);
}
KIRQL OldIrql;
PLIST_ENTRY ListEntry;
PKPROFILE_SOURCE_OBJECT CurrentSource = NULL;
-
+
/* Raise to PROFILE_LEVEL and acquire spinlock */
KeRaiseIrql(PROFILE_LEVEL, &OldIrql);
KeAcquireSpinLockAtDpcLevel(&KiProfileLock);
-
+
/* Make sure it's running */
if (Profile->Active) {
-
+
/* Remove it from the list and disable */
RemoveEntryList(&Profile->ListEntry);
Profile->Active = FALSE;
-
+
/* Find the Source Object */
- for (ListEntry = KiProfileSourceListHead.Flink;
- CurrentSource->Source != Profile->Source;
+ for (ListEntry = KiProfileSourceListHead.Flink;
+ CurrentSource->Source != Profile->Source;
ListEntry = ListEntry->Flink) {
-
+
/* Get the Source Object */
- CurrentSource = CONTAINING_RECORD(ListEntry,
+ CurrentSource = CONTAINING_RECORD(ListEntry,
KPROFILE_SOURCE_OBJECT,
ListEntry);
}
-
+
/* Remove it */
RemoveEntryList(&CurrentSource->ListEntry);
}
-
+
/* Lower IRQL */
KeReleaseSpinLockFromDpcLevel(&KiProfileLock);
KeLowerIrql(OldIrql);
-
+
/* Stop Profiling. FIXME: Implement in HAL */
//HalStopProfileInterrupt(Profile->Source);
-
+
/* Free the Source Object */
if (CurrentSource) ExFreePool(CurrentSource);
}
{
/* Check if this is the timer profile */
if (ProfileSource == ProfileTime) {
-
+
/* Return the good old 100ns sampling interval */
return KiProfileTimeInterval;
-
+
} else {
-
+
/* Request it from HAL. FIXME: What structure is used? */
HalQuerySystemInformation(HalProfileSourceInformation,
sizeof(NULL),
NULL,
NULL);
-
+
return 0;
}
}
-STDCALL
-VOID
+STDCALL
+VOID
KeSetIntervalProfile(KPROFILE_SOURCE ProfileSource,
ULONG Interval)
{
/* Check if this is the timer profile */
if (ProfileSource == ProfileTime) {
-
+
/* Set the good old 100ns sampling interval */
KiProfileTimeInterval = Interval;
-
+
} else {
-
+
/* Set it with HAL. FIXME: What structure is used? */
HalSetSystemInformation(HalProfileSourceInformation,
sizeof(NULL),
NULL);
-
+
}
}
PULONG BucketValue;
PKPROFILE Profile;
PLIST_ENTRY NextEntry;
-
+
/* Loop the List */
for (NextEntry = ListHead->Flink; NextEntry != ListHead; NextEntry = NextEntry->Flink) {
-
+
/* Get the Current Profile in the List */
Profile = CONTAINING_RECORD(NextEntry, KPROFILE, ListEntry);
-
+
/* Check if the source is good, and if it's within the range */
- if ((Profile->Source != Source) ||
- (TrapFrame->Eip < (ULONG_PTR)Profile->RegionStart) ||
+ if ((Profile->Source != Source) ||
+ (TrapFrame->Eip < (ULONG_PTR)Profile->RegionStart) ||
(TrapFrame->Eip > (ULONG_PTR)Profile->RegionEnd)) {
-
+
continue;
- }
+ }
/* Get the Pointer to the Bucket Value representing this EIP */
- BucketValue = (PULONG)(((ULONG_PTR)(Profile->Buffer +
+ BucketValue = (PULONG)(((ULONG_PTR)(Profile->Buffer +
(TrapFrame->Eip - (ULONG_PTR)Profile->RegionStart))
>> Profile->BucketShift) &~ 0x3);
-
+
/* Increment the value */
++BucketValue;
}
IN KPROFILE_SOURCE Source)
{
PKPROCESS Process = KeGetCurrentThread()->ApcState.Process;
-
+
/* We have to parse 2 lists. Per-Process and System-Wide */
KiParseProfileList(TrapFrame, Source, &Process->ProfileListHead);
KiParseProfileList(TrapFrame, Source, &KiProfileListHead);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/queue.c
* PURPOSE: Implements kernel queues
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* Gunnar Dalsnes
* Eric Kohl (ekohl@rz-online.de)
/* FUNCTIONS *****************************************************************/
LONG STDCALL KiInsertQueue(IN PKQUEUE Queue, IN PLIST_ENTRY Entry, BOOLEAN Head);
-
+
/*
* @implemented
*/
-VOID
+VOID
STDCALL
KeInitializeQueue(IN PKQUEUE Queue,
IN ULONG Count OPTIONAL)
{
DPRINT("KeInitializeQueue %x\n", Queue);
-
+
/* Initialize the Header */
KeInitializeDispatcherHeader(&Queue->Header,
QueueObject,
sizeof(KQUEUE)/sizeof(ULONG),
0);
-
+
/* Initialize the Lists */
InitializeListHead(&Queue->EntryListHead);
InitializeListHead(&Queue->ThreadListHead);
-
+
/* Set the Current and Maximum Count */
Queue->CurrentCount = 0;
Queue->MaximumCount = (Count == 0) ? (ULONG) KeNumberProcessors : Count;
{
LONG PreviousState;
KIRQL OldIrql;
-
+
DPRINT("KeInsertHeadQueue %x\n", Queue);
-
+
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Insert the Queue */
PreviousState = KiInsertQueue(Queue, Entry, TRUE);
-
+
/* Release the Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
/* Return previous State */
return PreviousState;
}
{
LONG PreviousState;
KIRQL OldIrql;
-
+
DPRINT("KeInsertQueue %x\n", Queue);
-
+
/* Lock the Dispatcher Database */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Insert the Queue */
PreviousState = KiInsertQueue(Queue, Entry, FALSE);
-
+
/* Release the Dispatcher Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
/* Return previous State */
return PreviousState;
}
/*
* @implemented
*/
-PLIST_ENTRY
+PLIST_ENTRY
STDCALL
KeRemoveQueue(IN PKQUEUE Queue,
IN KPROCESSOR_MODE WaitMode,
IN PLARGE_INTEGER Timeout OPTIONAL)
{
-
+
PLIST_ENTRY ListEntry;
NTSTATUS Status;
PKTHREAD Thread = KeGetCurrentThread();
PKTIMER Timer;
DPRINT("KeRemoveQueue %x\n", Queue);
-
+
/* Check if the Lock is already held */
if (Thread->WaitNext) {
-
+
DPRINT("Lock is already held\n");
-
+
} else {
-
+
/* Lock the Dispatcher Database */
DPRINT("Lock not held, acquiring\n");
OldIrql = KeAcquireDispatcherDatabaseLock();
PreviousQueue = Thread->Queue;
Thread->Queue = Queue;
- /* Check if this is a different queue */
+ /* Check if this is a different queue */
if (Queue != PreviousQueue) {
-
+
/*
* INVESTIGATE: What is the Thread->QueueListEntry used for? It's linked it into the
* Queue->ThreadListHead when the thread registers with the queue and unlinked when
*/
DPRINT("Different Queue\n");
if (PreviousQueue) {
-
+
/* Remove from this list */
DPRINT("Removing Old Queue\n");
RemoveEntryList(&Thread->QueueListEntry);
-
+
/* Wake the queue */
DPRINT("Activating new thread\n");
KiWakeQueue(PreviousQueue);
/* Insert in this new Queue */
DPRINT("Inserting new Queue!\n");
InsertTailList(&Queue->ThreadListHead, &Thread->QueueListEntry);
-
+
} else {
-
+
/* Same queue, decrement waiting threads */
DPRINT("Same Queue!\n");
Queue->CurrentCount--;
}
-
+
/* Loop until the queue is processed */
while (TRUE) {
-
+
/* Get the Entry */
ListEntry = Queue->EntryListHead.Flink;
-
+
/* Check if the counts are valid and if there is still a queued entry */
- if ((Queue->CurrentCount < Queue->MaximumCount) &&
+ if ((Queue->CurrentCount < Queue->MaximumCount) &&
(ListEntry != &Queue->EntryListHead)) {
-
+
/* Remove the Entry and Save it */
- DPRINT("Removing Queue Entry. CurrentCount: %d, Maximum Count: %d\n",
+ DPRINT("Removing Queue Entry. CurrentCount: %d, Maximum Count: %d\n",
Queue->CurrentCount, Queue->MaximumCount);
ListEntry = RemoveHeadList(&Queue->EntryListHead);
-
+
/* Decrease the number of entries */
Queue->Header.SignalState--;
-
+
/* Increase numbef of running threads */
Queue->CurrentCount++;
-
+
/* Check if the entry is valid. If not, bugcheck */
if (!ListEntry->Flink || !ListEntry->Blink) {
-
+
KEBUGCHECK(INVALID_WORK_QUEUE_ITEM);
}
-
+
/* Remove the Entry */
RemoveEntryList(ListEntry);
ListEntry->Flink = NULL;
-
+
/* Nothing to wait on */
break;
-
+
} else {
-
+
/* Do the wait */
- DPRINT("Waiting on Queue Entry. CurrentCount: %d, Maximum Count: %d\n",
+ DPRINT("Waiting on Queue Entry. CurrentCount: %d, Maximum Count: %d\n",
Queue->CurrentCount, Queue->MaximumCount);
-
+
/* Use the Thread's Wait Block, it's big enough */
Thread->WaitBlockList = &Thread->WaitBlock[0];
-
+
/* Fail if there's an APC Pending */
if (WaitMode == UserMode && Thread->ApcState.UserApcPending) {
-
+
/* Return the status and increase the pending threads */
ListEntry = (PLIST_ENTRY)STATUS_USER_APC;
Queue->CurrentCount++;
-
+
/* Nothing to wait on */
break;
}
-
+
/* Build the Wait Block */
WaitBlock = &Thread->WaitBlock[0];
WaitBlock->Object = (PVOID)Queue;
WaitBlock->WaitType = WaitAny;
WaitBlock->Thread = Thread;
WaitBlock->NextWaitBlock = WaitBlock;
-
+
Thread->WaitStatus = STATUS_SUCCESS;
-
+
/* We need to wait for the object... check if we have a timeout */
if (Timeout) {
-
+
/* If it's zero, then don't do any waiting */
if (!Timeout->QuadPart) {
-
+
/* Instant Timeout, return the status and increase the pending threads */
DPRINT("Queue Wait has timed out\n");
ListEntry = (PLIST_ENTRY)STATUS_TIMEOUT;
Queue->CurrentCount++;
-
+
/* Nothing to wait on */
break;
}
-
- /*
+
+ /*
* Set up the Timer. We'll use the internal function so that we can
* hold on to the dispatcher lock.
*/
TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
TimerWaitBlock->WaitType = WaitAny;
TimerWaitBlock->NextWaitBlock = TimerWaitBlock;
-
+
/* Link the timer to this Wait Block */
InitializeListHead(&Timer->Header.WaitListHead);
InsertTailList(&Timer->Header.WaitListHead, &TimerWaitBlock->WaitListEntry);
-
+
/* Create Timer */
DPRINT("Creating Timer with timeout %I64d\n", *Timeout);
KiInsertTimer(Timer, *Timeout);
}
-
+
/* Insert the wait block into the Queues's wait list */
WaitBlock = Thread->WaitBlockList;
InsertTailList(&Queue->Header.WaitListHead, &WaitBlock->WaitListEntry);
-
+
/* Block the Thread */
DPRINT("Blocking the Thread: %x %x!\n", KeGetCurrentThread(), Thread);
- KiBlockThread(&Status,
- FALSE,
+ KiBlockThread(&Status,
+ FALSE,
WaitMode,
WrQueue);
-
+
/* Reset the wait reason */
Thread->WaitReason = 0;
-
+
/* Check if we were executing an APC */
if (Status != STATUS_KERNEL_APC) {
-
+
/* Done Waiting */
DPRINT("Done waking queue. Thread: %x %x!\n", KeGetCurrentThread(), Thread);
return (PLIST_ENTRY)Status;
}
-
+
/* Acquire again the lock */
DPRINT("Looping again\n");
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Save the new IRQL and decrease number of waiting threads */
Thread->WaitIrql = OldIrql;
Queue->CurrentCount--;
}
}
-
+
/* Unlock Database and return */
KeReleaseDispatcherDatabaseLock(Thread->WaitIrql);
- DPRINT("Returning. CurrentCount: %d, Maximum Count: %d\n",
+ DPRINT("Returning. CurrentCount: %d, Maximum Count: %d\n",
Queue->CurrentCount, Queue->MaximumCount);
return ListEntry;
}
/*
* @implemented
*/
-PLIST_ENTRY
+PLIST_ENTRY
STDCALL
KeRundownQueue(IN PKQUEUE Queue)
{
/* Get the First Empty Entry */
FirstEntry = Queue->EntryListHead.Flink;
-
+
/* Make sure the list is not empty */
if (FirstEntry == &Queue->EntryListHead) {
-
+
/* It is, so don't return anything */
EnumEntry = NULL;
-
+
} else {
-
+
/* Remove it */
RemoveEntryList(&Queue->EntryListHead);
}
-
+
/* Unlink threads and clear their Thread->Queue */
while (!IsListEmpty(&Queue->ThreadListHead)) {
-
+
/* Get the Entry and Remove it */
EnumEntry = RemoveHeadList(&Queue->ThreadListHead);
-
+
/* Get the Entry's Thread */
Thread = CONTAINING_RECORD(EnumEntry, KTHREAD, QueueListEntry);
-
+
/* Kill its Queue */
Thread->Queue = NULL;
}
PLIST_ENTRY QueueEntry;
PLIST_ENTRY WaitEntry;
PKWAIT_BLOCK WaitBlock;
-
+
/* Decrement the number of active threads */
DPRINT("KiWakeQueue: %x. Thread: %x\n", Queue, KeGetCurrentThread());
Queue->CurrentCount--;
-
+
/* Make sure the counts are OK */
if (Queue->CurrentCount < Queue->MaximumCount) {
-
+
/* Get the Queue Entry */
QueueEntry = Queue->EntryListHead.Flink;
-
+
/* Get the Wait Entry */
WaitEntry = Queue->Header.WaitListHead.Blink;
DPRINT("Queue Count is ok, Queue entries: %x, %x\n", QueueEntry, WaitEntry);
-
+
/* Make sure that the Queue List isn't empty and that this entry is valid */
- if (!IsListEmpty(&Queue->Header.WaitListHead) &&
+ if (!IsListEmpty(&Queue->Header.WaitListHead) &&
(QueueEntry != &Queue->EntryListHead)) {
-
+
/* Remove this entry */
DPRINT("Queue in List, removing it\n");
RemoveEntryList(QueueEntry);
QueueEntry->Flink = NULL;
-
+
/* Decrease the Signal State */
Queue->Header.SignalState--;
-
+
/* Unwait the Thread */
DPRINT("Unwaiting Thread\n");
WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
KiAbortWaitThread(WaitBlock->Thread, (NTSTATUS)QueueEntry, IO_NO_INCREMENT);
}
- }
+ }
}
/*
* Returns the previous number of entries in the queue
*/
-LONG
+LONG
STDCALL
KiInsertQueue(IN PKQUEUE Queue,
IN PLIST_ENTRY Entry,
PKTHREAD Thread = KeGetCurrentThread();
PKWAIT_BLOCK WaitBlock;
PLIST_ENTRY WaitEntry;
-
+
DPRINT("KiInsertQueue(Queue %x, Entry %x)\n", Queue, Entry);
-
+
/* Save the old state */
InitialState = Queue->Header.SignalState;
-
+
/* Get the Entry */
WaitEntry = Queue->Header.WaitListHead.Blink;
DPRINT("Initial State, WaitEntry: %d, %x\n", InitialState, WaitEntry);
-
+
/*
* Why the KeGetCurrentThread()->Queue != Queue?
- * KiInsertQueue might be called from an APC for the current thread.
+ * KiInsertQueue might be called from an APC for the current thread.
* -Gunnar
*/
- if ((Queue->CurrentCount < Queue->MaximumCount) &&
+ if ((Queue->CurrentCount < Queue->MaximumCount) &&
(WaitEntry != &Queue->Header.WaitListHead) &&
((Thread->Queue != Queue) || (Thread->WaitReason != WrQueue))) {
-
+
/* Remove the wait entry */
DPRINT("Removing Entry\n");
RemoveEntryList(WaitEntry);
-
+
/* Get the Wait Block and Thread */
WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
DPRINT("Got wait block: %x\n", WaitBlock);
Thread = WaitBlock->Thread;
-
+
/* Reset the wait reason */
Thread->WaitReason = 0;
-
+
/* Increase the waiting threads */
Queue->CurrentCount++;
-
+
/* Check if there's a Thread Timer */
if (Thread->Timer.Header.Inserted) {
-
+
/* Cancel the Thread Timer with the no-lock fastpath */
DPRINT("Removing the Thread's Timer\n");
Thread->Timer.Header.Inserted = FALSE;
RemoveEntryList(&Thread->Timer.TimerListEntry);
}
-
+
/* Reschedule the Thread */
DPRINT("Unblocking the Thread\n");
KiUnblockThread(Thread, (PNTSTATUS)&Entry, 0);
-
+
} else {
-
+
/* Increase the Entries */
DPRINT("Adding new Queue Entry: %d %d\n", Head, Queue->Header.SignalState);
Queue->Header.SignalState++;
-
+
if (Head) {
-
+
InsertHeadList(&Queue->EntryListHead, Entry);
-
+
} else {
-
+
InsertTailList(&Queue->EntryListHead, Entry);
}
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/sem.c
* PURPOSE: Implements kernel semaphores
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
{
DPRINT("KeInitializeSemaphore Sem: %x\n", Semaphore);
-
+
/* Simply Initialize the Header */
KeInitializeDispatcherHeader(&Semaphore->Header,
SemaphoreObject,
Count);
/* Set the Limit */
- Semaphore->Limit = Limit;
+ Semaphore->Limit = Limit;
}
/*
* @implemented
*/
-LONG
+LONG
STDCALL
KeReadStateSemaphore(PKSEMAPHORE Semaphore)
{
* Semaphore = Points to an initialized semaphore object for which the
* caller provides the storage.
* Increment = Specifies the priority increment to be applied if
- * releasing the semaphore causes a wait to be
+ * releasing the semaphore causes a wait to be
* satisfied.
* Adjustment = Specifies a value to be added to the current semaphore
* count. This value must be positive
* RETURNS: If the return value is zero, the previous state of the semaphore
* object is Not-Signaled.
*/
-LONG
+LONG
STDCALL
KeReleaseSemaphore(PKSEMAPHORE Semaphore,
KPRIORITY Increment,
KIRQL OldIrql;
PKTHREAD CurrentThread;
- DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, Wait %d)\n",
- Semaphore,
- Increment,
- Adjustment,
+ DPRINT("KeReleaseSemaphore(Semaphore %x, Increment %d, Adjustment %d, Wait %d)\n",
+ Semaphore,
+ Increment,
+ Adjustment,
Wait);
/* Lock the Dispatcher Database */
/* Save the Old State */
InitialState = Semaphore->Header.SignalState;
-
+
/* Check if the Limit was exceeded */
- if (Semaphore->Limit < (LONG) InitialState + Adjustment ||
+ if (Semaphore->Limit < (LONG) InitialState + Adjustment ||
InitialState > InitialState + Adjustment) {
-
+
/* Raise an error if it was exceeded */
KeReleaseDispatcherDatabaseLock(OldIrql);
ExRaiseStatus(STATUS_SEMAPHORE_LIMIT_EXCEEDED);
/* Now set the new state */
Semaphore->Header.SignalState += Adjustment;
-
+
/* Check if we should wake it */
if (InitialState == 0 && !IsListEmpty(&Semaphore->Header.WaitListHead)) {
-
+
/* Wake the Semaphore */
KiWaitTest(&Semaphore->Header, Increment);
}
/* If the Wait is true, then return with a Wait and don't unlock the Dispatcher Database */
if (Wait == FALSE) {
-
+
/* Release the Lock */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
} else {
-
+
/* Set a wait */
CurrentThread = KeGetCurrentThread();
CurrentThread->WaitNext = TRUE;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/spinlock.c
* PURPOSE: Implements spinlocks
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
* of a given interrupt object
* ARGUMENTS:
* Interrupt = Interrupt object to synchronize with
- * SynchronizeRoutine = Routine to call whose execution is
+ * SynchronizeRoutine = Routine to call whose execution is
* synchronized with the ISR
* SynchronizeContext = Parameter to pass to the synchronized routine
* RETURNS: TRUE if the operation succeeded
{
KIRQL oldlvl;
BOOLEAN ret;
-
+
oldlvl = KeAcquireInterruptSpinLock(Interrupt);
-
+
ret = SynchronizeRoutine(SynchronizeContext);
-
+
KeReleaseInterruptSpinLock(Interrupt, oldlvl);
-
+
return(ret);
}
)
{
KIRQL oldIrql;
-
+
KeRaiseIrql(Interrupt->SynchLevel, &oldIrql);
KiAcquireSpinLock(Interrupt->ActualLock);
return oldIrql;
VOID STDCALL
KeAcquireSpinLockAtDpcLevel (PKSPIN_LOCK SpinLock)
/*
- * FUNCTION: Acquires a spinlock when the caller is already running at
+ * FUNCTION: Acquires a spinlock when the caller is already running at
* dispatch level
* ARGUMENTS:
* SpinLock = Spinlock to acquire
KefReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock)
{
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
- KiReleaseSpinLock(SpinLock);
+ KiReleaseSpinLock(SpinLock);
}
#undef KeReleaseSpinLockFromDpcLevel
/*
* FUNCTION: Releases a spinlock when the caller was running at dispatch
* level before acquiring it
- * ARGUMENTS:
+ * ARGUMENTS:
* SpinLock = Spinlock to release
*/
{
* the spinlock's value.
*/
ASSERT(*SpinLock < 2);
-
+
while ((i = InterlockedExchangeUL(SpinLock, 1)) == 1)
{
#ifdef CONFIG_SMP
"jne 1b\n\t"
:
: "r" (SpinLock));
-#else
+#else
while (0 != *(volatile KSPIN_LOCK*)SpinLock);
#endif
#else
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/timer.c
* PURPOSE: Handle Kernel Timers (Kernel-part of Executive Timers)
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Reimplemented some parts, fixed many bugs.
* David Welch (welch@mcmail.com) & Phillip Susi - Original Implementation.
*/
* RETURNS: True if the timer was running
* False otherwise
*/
-BOOLEAN
+BOOLEAN
STDCALL
KeCancelTimer(PKTIMER Timer)
{
KIRQL OldIrql;
BOOLEAN Inserted = FALSE;
-
+
DPRINT("KeCancelTimer(Timer %x)\n",Timer);
/* Lock the Database and Raise IRQL */
/* Check if it's inserted, and remove it if it is */
if ((Inserted = Timer->Header.Inserted)) {
-
+
/* Remove from list */
DPRINT("Timer was inserted, removing\n");
RemoveEntryList(&Timer->TimerListEntry);
Timer->Header.Inserted = FALSE;
-
+
} else {
-
+
DPRINT("Timer was not inserted\n");
}
* Timer = caller supplied storage for the timer
* NOTE: This function initializes a notification timer
*/
-VOID
+VOID
STDCALL
KeInitializeTimer (PKTIMER Timer)
* Timer = caller supplied storage for the timer
* Type = the type of timer (notification or synchronization)
* NOTE: When a notification type expires all waiting threads are released
- * and the timer remains signalled until it is explicitly reset. When a
+ * and the timer remains signalled until it is explicitly reset. When a
* syncrhonization timer expires its state is set to signalled until a
* single waiting thread is released and then the timer is reset.
*/
-VOID
+VOID
STDCALL
KeInitializeTimerEx (PKTIMER Timer,
TIMER_TYPE Type)
{
DPRINT("KeInitializeTimerEx(%x, %d)\n", Timer, Type);
-
+
/* Initialize the Dispatch Header */
KeInitializeDispatcherHeader(&Timer->Header,
TimerNotificationObject + Type,
sizeof(KTIMER) / sizeof(ULONG),
FALSE);
-
+
/* Initalize the Other data */
Timer->DueTime.QuadPart = 0;
Timer->Period = 0;
/*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
KeReadStateTimer (PKTIMER Timer)
{
* @implemented
*
* FUNCTION: Sets the absolute or relative interval at which a timer object
- * is to be set to the signaled state and optionally supplies a
+ * is to be set to the signaled state and optionally supplies a
* CustomTimerDpc to be executed when the timer expires.
* ARGUMENTS:
* Timer = Points to a previously initialized timer object
* RETURNS: True if the timer was already in the system timer queue
* False otherwise
*/
-BOOLEAN
+BOOLEAN
STDCALL
KeSetTimer (PKTIMER Timer,
LARGE_INTEGER DueTime,
* @implemented
*
* FUNCTION: Sets the absolute or relative interval at which a timer object
- * is to be set to the signaled state and optionally supplies a
+ * is to be set to the signaled state and optionally supplies a
* CustomTimerDpc to be executed when the timer expires.
* ARGUMENTS:
* Timer = Points to a previously initialized timer object
* RETURNS: True if the timer was already in the system timer queue
* False otherwise
*/
-BOOLEAN
+BOOLEAN
STDCALL
KeSetTimerEx (PKTIMER Timer,
LARGE_INTEGER DueTime,
/* Check if it's inserted, and remove it if it is */
if ((Inserted = Timer->Header.Inserted)) {
-
+
/* Remove from list */
DPRINT("Timer was already inserted\n");
RemoveEntryList(&Timer->TimerListEntry);
- Timer->Header.Inserted = FALSE;
+ Timer->Header.Inserted = FALSE;
}
-
- /* Set Default Timer Data */
+
+ /* Set Default Timer Data */
Timer->Dpc = Dpc;
Timer->Period = Period;
Timer->Header.SignalState = FALSE;
-
+
/* Insert it */
if (!KiInsertTimer(Timer, DueTime)) {
KIRQL OldIrql;
DPRINT("KiExpireTimers(Dpc: %x)\n", Dpc);
-
+
/* Initialize the Expired Timer List */
InitializeListHead(&ExpiredTimerList);
/* Lock the Database and Raise IRQL */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
- /* Query Interrupt Times */
+
+ /* Query Interrupt Times */
InterruptTime = KeQueryInterruptTime();
/* Loop through the Timer List and remove Expired Timers. Insert them into the Expired Listhead */
CurrentEntry = KiTimerListHead.Flink;
while (CurrentEntry != &KiTimerListHead) {
-
+
/* Get the Current Timer */
Timer = CONTAINING_RECORD(CurrentEntry, KTIMER, TimerListEntry);
DPRINT("Looping for Timer: %x. Duetime: %I64d. InterruptTime %I64d \n", Timer, Timer->DueTime.QuadPart, InterruptTime);
-
+
/* Check if we have to Expire it */
if (InterruptTime < Timer->DueTime.QuadPart) break;
-
+
CurrentEntry = CurrentEntry->Flink;
-
+
/* Remove it from the Timer List, add it to the Expired List */
RemoveEntryList(&Timer->TimerListEntry);
InsertTailList(&ExpiredTimerList, &Timer->TimerListEntry);
}
-
+
/* Expire the Timers */
while ((CurrentEntry = RemoveHeadList(&ExpiredTimerList)) != &ExpiredTimerList) {
-
+
/* Get the Timer */
Timer = CONTAINING_RECORD(CurrentEntry, KTIMER, TimerListEntry);
DPRINT("Expiring Timer: %x\n", Timer);
-
+
/* Expire it */
KiHandleExpiredTimer(Timer);
}
* We enter this function at IRQL DISPATCH_LEVEL, and with the
* Dispatcher Lock held!
*/
-VOID
+VOID
STDCALL
KiHandleExpiredTimer(PKTIMER Timer)
{
LARGE_INTEGER DueTime;
DPRINT("HandleExpiredTime(Timer %x)\n", Timer);
-
+
if(Timer->Header.Inserted) {
/* First of all, remove the Timer */
Timer->Header.Inserted = FALSE;
RemoveEntryList(&Timer->TimerListEntry);
}
-
+
/* Set it as Signaled */
DPRINT("Setting Timer as Signaled\n");
Timer->Header.SignalState = TRUE;
- KiWaitTest(&Timer->Header, IO_NO_INCREMENT);
+ KiWaitTest(&Timer->Header, IO_NO_INCREMENT);
/* If the Timer is periodic, reinsert the timer with the new due time */
if (Timer->Period) {
-
+
/* Reinsert the Timer */
DueTime.QuadPart = Timer->Period * -SYSTEM_TIME_UNITS_PER_MSEC;
if (!KiInsertTimer(Timer, DueTime)) {
DPRINT("CRITICAL UNHANDLED CASE: TIMER ALREADY EXPIRED!!!\n");
};
}
-
+
/* Check if the Timer has a DPC */
if (Timer->Dpc) {
DPRINT("Timer->Dpc %x Timer->Dpc->DeferredRoutine %x\n", Timer->Dpc, Timer->Dpc->DeferredRoutine);
-
+
/* Insert the DPC */
KeInsertQueueDpc(Timer->Dpc,
NULL,
NULL);
-
+
DPRINT("Finished dpc routine\n");
}
}
LARGE_INTEGER SystemTime;
LARGE_INTEGER DifferenceTime;
ULONGLONG InterruptTime;
-
+
DPRINT("KiInsertTimer(Timer %x DueTime %I64d)\n", Timer, DueTime.QuadPart);
-
+
/* Set default data */
Timer->Header.Inserted = TRUE;
Timer->Header.Absolute = FALSE;
if (!Timer->Period) Timer->Header.SignalState = FALSE;
-
+
/* Convert to relative time if needed */
if (DueTime.u.HighPart >= 0) {
-
+
/* Get System Time */
KeQuerySystemTime(&SystemTime);
-
+
/* Do the conversion */
DifferenceTime.QuadPart = SystemTime.QuadPart - DueTime.QuadPart;
DPRINT("Time Difference is: %I64d\n", DifferenceTime.QuadPart);
-
+
/* Make sure it hasn't already expired */
if (DifferenceTime.u.HighPart >= 0) {
-
+
/* Cancel everything */
DPRINT("Timer already expired: %d\n", DifferenceTime.u.HighPart);
Timer->Header.SignalState = TRUE;
Timer->Header.Inserted = FALSE;
return FALSE;
}
-
+
/* Set the time as Absolute */
Timer->Header.Absolute = TRUE;
DueTime = DifferenceTime;
}
-
+
/* Get the Interrupt Time */
InterruptTime = KeQueryInterruptTime();
-
+
/* Set the Final Due Time */
Timer->DueTime.QuadPart = InterruptTime - DueTime.QuadPart;
DPRINT("Final Due Time is: %I64d\n", Timer->DueTime.QuadPart);
-
- /* Now insert it into the Timer List */
+
+ /* Now insert it into the Timer List */
DPRINT("Inserting Timer into list\n");
- InsertAscendingList(&KiTimerListHead,
+ InsertAscendingList(&KiTimerListHead,
KTIMER,
- TimerListEntry,
+ TimerListEntry,
Timer,
DueTime.QuadPart);
-
+
return TRUE;
}
/* EOF */
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/usercall.c
* PURPOSE: User-Mode callbacks. Portable part.
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
#if ALEX_CB_REWRITE
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
KiSwitchToUserMode(IN PVOID *OutputBuffer,
IN PULONG OutputLength);
}
VOID STATIC
-PsFreeCallbackStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
- PFN_TYPE Page, SWAPENTRY SwapEntry,
+PsFreeCallbackStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
+ PFN_TYPE Page, SWAPENTRY SwapEntry,
BOOLEAN Dirty)
{
ASSERT(SwapEntry == 0);
IN ULONG ArgumentLength,
OUT PVOID *Result,
OUT PULONG ResultLength)
-{
+{
PETHREAD Thread;
PVOID NewStack;
ULONG_PTR StackSize;
NTSTATUS CallbackStatus;
NTW32CALL_SAVED_STATE SavedState;
PNTW32CALL_CALLBACK_STACK AssignedStack;
-
+
PAGED_CODE();
DPRINT("KeUserModeCallback(RoutineIndex %d, Argument %X, ArgumentLength %d)\n",
KeGetCurrentKPCR()->TSS->Esp0 = (ULONG)Thread->Tcb.InitialStack - sizeof(FX_SAVE_AREA);
KePushAndStackSwitchAndSysRet((ULONG)&SavedState, Thread->Tcb.KernelStack);
- /*
- * The callback return will have already restored most of the state we
+ /*
+ * The callback return will have already restored most of the state we
* modified.
*/
KeLowerIrql(DISPATCH_LEVEL);
KeReleaseSpinLock(&CallbackStackListLock, PASSIVE_LEVEL);
return(CallbackStatus);
}
-
+
/* EOF */
* PROJECT: ReactOS project
* FILE: ntoskrnl/ke/wait.c
* PURPOSE: Manages non-busy waiting
- *
+ *
* PROGRAMMERS: Alex Ionescu - Fixes and optimization.
* Gunnar Dalsnes - Implementation
*/
{
/* At this point, we have to do a wait, so make sure we can make the thread Alertable if requested */
if (Alertable) {
-
- /* If the Thread is Alerted, set the Wait Status accordingly */
+
+ /* If the Thread is Alerted, set the Wait Status accordingly */
if (CurrentThread->Alerted[(int)WaitMode]) {
-
+
CurrentThread->Alerted[(int)WaitMode] = FALSE;
DPRINT("Thread was Alerted\n");
*Status = STATUS_ALERTED;
-
+
/* If there are User APCs Pending, then we can't really be alertable */
- } else if ((!IsListEmpty(&CurrentThread->ApcState.ApcListHead[UserMode])) &&
+ } else if ((!IsListEmpty(&CurrentThread->ApcState.ApcListHead[UserMode])) &&
(WaitMode == UserMode)) {
-
+
DPRINT("APCs are Pending\n");
CurrentThread->ApcState.UserApcPending = TRUE;
*Status = STATUS_USER_APC;
}
-
+
/* If there are User APCs Pending and we are waiting in usermode, then we must notify the caller */
} else if ((CurrentThread->ApcState.UserApcPending) && (WaitMode == UserMode)) {
DPRINT("APCs are Pending\n");
/*
* @implemented
*
- * FUNCTION: Puts the current thread into an alertable or nonalertable
+ * FUNCTION: Puts the current thread into an alertable or nonalertable
* wait state for a given internal
* ARGUMENTS:
* WaitMode = Processor mode in which the caller is waiting
* Interval = Specifies the interval to wait
* RETURNS: Status
*/
-NTSTATUS
+NTSTATUS
STDCALL
KeDelayExecutionThread(KPROCESSOR_MODE WaitMode,
BOOLEAN Alertable,
/* Check if the lock is already held */
if (CurrentThread->WaitNext) {
-
+
/* Lock is held, disable Wait Next */
DPRINT("Lock is held\n");
CurrentThread->WaitNext = FALSE;
-
+
} else {
-
+
/* Lock not held, acquire it */
DPRINT("Lock is not held, acquiring\n");
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
}
-
+
/* Use built-in Wait block */
TimerWaitBlock = &CurrentThread->WaitBlock[TIMER_WAIT_BLOCK];
-
+
/* Start Wait Loop */
do {
-
+
/* We are going to wait no matter what (that's the point), so test Alertability */
KiCheckAlertability(Alertable, CurrentThread, KernelMode, &Status);
-
+
/* Set Timer */
ThreadTimer = &CurrentThread->Timer;
-
+
/* Setup the Wait Block */
CurrentThread->WaitBlockList = TimerWaitBlock;
TimerWaitBlock->Object = (PVOID)ThreadTimer;
TimerWaitBlock->Thread = CurrentThread;
TimerWaitBlock->WaitKey = (USHORT)STATUS_TIMEOUT;
- TimerWaitBlock->WaitType = WaitAny;
+ TimerWaitBlock->WaitType = WaitAny;
TimerWaitBlock->NextWaitBlock = TimerWaitBlock;
-
+
/* Link the timer to this Wait Block */
InitializeListHead(&ThreadTimer->Header.WaitListHead);
InsertTailList(&ThreadTimer->Header.WaitListHead, &TimerWaitBlock->WaitListEntry);
/* Insert the Timer into the Timer Lists and enable it */
- if (!KiInsertTimer(ThreadTimer, *Interval)) {
+ if (!KiInsertTimer(ThreadTimer, *Interval)) {
/* FIXME: The timer already expired, we should find a new ready thread */
Status = STATUS_SUCCESS;
break;
- }
-
+ }
+
/* Handle Kernel Queues */
if (CurrentThread->Queue) {
-
+
DPRINT("Waking Queue\n");
KiWakeQueue(CurrentThread->Queue);
}
/* Block the Thread */
DPRINT("Blocking the Thread: %d, %d, %x\n", Alertable, WaitMode, KeGetCurrentThread());
- KiBlockThread(&Status,
- Alertable,
- WaitMode,
+ KiBlockThread(&Status,
+ Alertable,
+ WaitMode,
DelayExecution);
-
+
/* Check if we were executing an APC or if we timed out */
if (Status != STATUS_KERNEL_APC) {
-
+
/* This is a good thing */
if (Status == STATUS_TIMEOUT) Status = STATUS_SUCCESS;
-
+
/* Return Status */
return Status;
}
-
+
DPRINT("Looping Again\n");
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
-
+
} while (TRUE);
-
+
/* Release the Lock, we are done */
DPRINT("Returning from KeDelayExecutionThread(), %x. Status: %d\n", KeGetCurrentThread(), Status);
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
- return Status;
+ return Status;
}
/*
* Timeout = Optional timeout value
* RETURNS: Status
*/
-NTSTATUS
+NTSTATUS
STDCALL
KeWaitForSingleObject(PVOID Object,
KWAIT_REASON WaitReason,
NTSTATUS WaitStatus;
DPRINT("Entering KeWaitForSingleObject\n");
-
+
/* Check if the lock is already held */
if (CurrentThread->WaitNext) {
-
+
/* Lock is held, disable Wait Next */
DPRINT("Lock is held\n");
CurrentThread->WaitNext = FALSE;
-
+
} else {
-
+
/* Lock not held, acquire it */
DPRINT("Lock is not held, acquiring\n");
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
/* Start the actual Loop */
do {
-
+
/* Get the current Wait Status */
WaitStatus = CurrentThread->WaitStatus;
-
+
/* Append wait block to the KTHREAD wait block list */
CurrentThread->WaitBlockList = WaitBlock = &CurrentThread->WaitBlock[0];
-
+
/* Get the Current Object */
CurrentObject = (PDISPATCHER_HEADER)Object;
-
- /* FIXME:
+
+ /* FIXME:
* Temporary hack until my Object Manager re-write. Basically some objects, like
* the File Object, but also LPCs and others, are actually waitable on their event.
* The Object Manager sets this up in The ObjectTypeInformation->DefaultObject member,
* -- Alex Ionescu 24/02/05
*/
if (CurrentObject->Type == IO_TYPE_FILE) {
-
+
DPRINT1("Hack used: %x\n", &((PFILE_OBJECT)CurrentObject)->Event);
CurrentObject = (PDISPATCHER_HEADER)(&((PFILE_OBJECT)CurrentObject)->Event);
}
/* Check if the Object is Signaled */
if (KiIsObjectSignaled(CurrentObject, CurrentThread)) {
-
+
/* Just unwait this guy and exit */
if (CurrentObject->SignalState != MINLONG) {
-
+
/* It has a normal signal state, so unwait it and return */
KiSatisfyObjectWait(CurrentObject, CurrentThread);
Status = STATUS_WAIT_0;
goto WaitDone;
-
+
} else {
-
+
/* Is this a Mutant? */
if (CurrentObject->Type == MutantObject) {
-
+
/* According to wasm.ru, we must raise this exception (tested and true) */
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
- ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
- }
+ ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
+ }
}
}
-
+
/* Set up the Wait Block */
WaitBlock->Object = CurrentObject;
WaitBlock->Thread = CurrentThread;
WaitBlock->WaitKey = (USHORT)(STATUS_WAIT_0);
- WaitBlock->WaitType = WaitAny;
+ WaitBlock->WaitType = WaitAny;
WaitBlock->NextWaitBlock = WaitBlock;
-
+
/* Make sure we can satisfy the Alertable request */
KiCheckAlertability(Alertable, CurrentThread, WaitMode, &Status);
-
+
/* Set the Wait Status */
CurrentThread->WaitStatus = Status;
-
+
/* Enable the Timeout Timer if there was any specified */
if (Timeout != NULL) {
-
+
/* However if 0 timeout was specified, then we must fail since we need to peform a wait */
if (!Timeout->QuadPart) {
-
+
/* Return a timeout */
Status = STATUS_TIMEOUT;
goto WaitDone;
}
-
+
/* Point to Timer Wait Block and Thread Timer */
TimerWaitBlock = &CurrentThread->WaitBlock[TIMER_WAIT_BLOCK];
ThreadTimer = &CurrentThread->Timer;
/* Connect the Timer Wait Block */
WaitBlock->NextWaitBlock = TimerWaitBlock;
-
+
/* Set up the Timer Wait Block */
TimerWaitBlock->Object = (PVOID)ThreadTimer;
TimerWaitBlock->Thread = CurrentThread;
TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
TimerWaitBlock->WaitType = WaitAny;
TimerWaitBlock->NextWaitBlock = WaitBlock;
-
+
/* Link the timer to this Wait Block */
InitializeListHead(&ThreadTimer->Header.WaitListHead);
InsertTailList(&ThreadTimer->Header.WaitListHead, &TimerWaitBlock->WaitListEntry);
/* Insert the Timer into the Timer Lists and enable it */
- if (!KiInsertTimer(ThreadTimer, *Timeout)) {
+ if (!KiInsertTimer(ThreadTimer, *Timeout)) {
/* Return a timeout if we couldn't insert the timer for some reason */
Status = STATUS_TIMEOUT;
goto WaitDone;
- }
+ }
}
/* Link the Object to this Wait Block */
- InsertTailList(&CurrentObject->WaitListHead, &WaitBlock->WaitListEntry);
-
+ InsertTailList(&CurrentObject->WaitListHead, &WaitBlock->WaitListEntry);
+
/* Handle Kernel Queues */
if (CurrentThread->Queue) {
-
+
DPRINT("Waking Queue\n");
KiWakeQueue(CurrentThread->Queue);
}
/* Block the Thread */
DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, WaitReason, KeGetCurrentThread());
- KiBlockThread(&Status,
- Alertable,
- WaitMode,
+ KiBlockThread(&Status,
+ Alertable,
+ WaitMode,
(UCHAR)WaitReason);
-
+
/* Check if we were executing an APC */
if (Status != STATUS_KERNEL_APC) {
-
+
/* Return Status */
return Status;
}
-
+
DPRINT("Looping Again\n");
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
-
+
} while (TRUE);
-
+
WaitDone:
/* Release the Lock, we are done */
DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n", KeGetCurrentThread(), Status);
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
- return Status;
+ return Status;
}
/*
/* Set the Current Thread */
CurrentThread = KeGetCurrentThread();
-
+
/* Check if the lock is already held */
if (CurrentThread->WaitNext) {
-
+
/* Lock is held, disable Wait Next */
DPRINT("Lock is held\n");
CurrentThread->WaitNext = FALSE;
-
+
} else {
-
+
/* Lock not held, acquire it */
DPRINT("Lock is not held, acquiring\n");
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
/* Make sure the Wait Count is valid for the Thread and Maximum Wait Objects */
if (!WaitBlockArray) {
-
+
/* Check in regards to the Thread Object Limit */
if (Count > THREAD_WAIT_OBJECTS) {
-
+
KEBUGCHECK(MAXIMUM_WAIT_OBJECTS_EXCEEDED);
}
-
+
/* Use the Thread's Wait Block */
WaitBlockArray = &CurrentThread->WaitBlock[0];
-
+
} else {
-
+
/* Using our own Block Array. Check in regards to System Object Limit */
if (Count > MAXIMUM_WAIT_OBJECTS) {
-
+
KEBUGCHECK(MAXIMUM_WAIT_OBJECTS_EXCEEDED);
}
}
-
+
/* Start the actual Loop */
do {
-
+
/* Get the current Wait Status */
WaitStatus = CurrentThread->WaitStatus;
-
+
/* Append wait block to the KTHREAD wait block list */
CurrentThread->WaitBlockList = WaitBlock = WaitBlockArray;
-
+
/* Check if the wait is (already) satisfied */
AllObjectsSignaled = TRUE;
-
+
/* First, we'll try to satisfy the wait directly */
for (WaitIndex = 0; WaitIndex < Count; WaitIndex++) {
-
+
/* Get the Current Object */
CurrentObject = (PDISPATCHER_HEADER)Object[WaitIndex];
-
- /* FIXME:
+
+ /* FIXME:
* Temporary hack until my Object Manager re-write. Basically some objects, like
* the File Object, but also LPCs and others, are actually waitable on their event.
* The Object Manager sets this up in The ObjectTypeInformation->DefaultObject member,
* -- Alex Ionescu 24/02/05
*/
if (CurrentObject->Type == IO_TYPE_FILE) {
-
+
CurrentObject = (PDISPATCHER_HEADER)(&((PFILE_OBJECT)CurrentObject)->Event);
}
/* Check if the Object is Signaled */
if (KiIsObjectSignaled(CurrentObject, CurrentThread)) {
-
- /* Check what kind of wait this is */
+
+ /* Check what kind of wait this is */
if (WaitType == WaitAny) {
-
+
/* This is a Wait Any, so just unwait this guy and exit */
if (CurrentObject->SignalState != MINLONG) {
-
+
/* It has a normal signal state, so unwait it and return */
KiSatisfyObjectWait(CurrentObject, CurrentThread);
Status = STATUS_WAIT_0 | WaitIndex;
goto WaitDone;
-
+
} else {
-
+
/* Is this a Mutant? */
if (CurrentObject->Type == MutantObject) {
-
+
/* According to wasm.ru, we must raise this exception (tested and true) */
KeReleaseDispatcherDatabaseLock(CurrentThread->WaitIrql);
- ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
- }
+ ExRaiseStatus(STATUS_MUTANT_LIMIT_EXCEEDED);
+ }
}
}
-
+
} else {
-
+
/* One of the objects isn't signaled... if this is a WaitAll, we will fail later */
AllObjectsSignaled = FALSE;
}
WaitBlock->Object = CurrentObject;
WaitBlock->Thread = CurrentThread;
WaitBlock->WaitKey = (USHORT)(STATUS_WAIT_0 + WaitIndex);
- WaitBlock->WaitType = (USHORT)WaitType;
+ WaitBlock->WaitType = (USHORT)WaitType;
WaitBlock->NextWaitBlock = WaitBlock + 1;
-
+
/* Move to the next Wait Block */
WaitBlock = WaitBlock->NextWaitBlock;
}
-
+
/* Return to the Root Wait Block */
WaitBlock--;
WaitBlock->NextWaitBlock = WaitBlockArray;
-
+
/* Check if this is a Wait All and all the objects are signaled */
if ((WaitType == WaitAll) && (AllObjectsSignaled)) {
-
+
/* Return to the Root Wait Block */
WaitBlock = CurrentThread->WaitBlockList;
-
+
/* Satisfy their Waits and return to the caller */
KiSatisifyMultipleObjectWaits(WaitBlock);
Status = STATUS_WAIT_0;
goto WaitDone;
}
-
+
/* Make sure we can satisfy the Alertable request */
KiCheckAlertability(Alertable, CurrentThread, WaitMode, &Status);
-
+
/* Set the Wait Status */
CurrentThread->WaitStatus = Status;
-
+
/* Enable the Timeout Timer if there was any specified */
if (Timeout != NULL) {
-
+
/* However if 0 timeout was specified, then we must fail since we need to peform a wait */
if (!Timeout->QuadPart) {
-
+
/* Return a timeout */
Status = STATUS_TIMEOUT;
goto WaitDone;
}
-
+
/* Point to Timer Wait Block and Thread Timer */
TimerWaitBlock = &CurrentThread->WaitBlock[TIMER_WAIT_BLOCK];
ThreadTimer = &CurrentThread->Timer;
/* Connect the Timer Wait Block */
WaitBlock->NextWaitBlock = TimerWaitBlock;
-
+
/* Set up the Timer Wait Block */
TimerWaitBlock->Object = (PVOID)ThreadTimer;
TimerWaitBlock->Thread = CurrentThread;
TimerWaitBlock->WaitKey = STATUS_TIMEOUT;
TimerWaitBlock->WaitType = WaitAny;
TimerWaitBlock->NextWaitBlock = WaitBlockArray;
-
+
/* Link the timer to this Wait Block */
InitializeListHead(&ThreadTimer->Header.WaitListHead);
/* Insert the Timer into the Timer Lists and enable it */
- if (!KiInsertTimer(ThreadTimer, *Timeout)) {
+ if (!KiInsertTimer(ThreadTimer, *Timeout)) {
/* Return a timeout if we couldn't insert the timer for some reason */
Status = STATUS_TIMEOUT;
/* Insert into Object's Wait List*/
WaitBlock = CurrentThread->WaitBlockList;
do {
-
+
/* Get the Current Object */
CurrentObject = WaitBlock->Object;
-
+
/* Link the Object to this Wait Block */
InsertTailList(&CurrentObject->WaitListHead, &WaitBlock->WaitListEntry);
-
+
/* Move to the next Wait Block */
WaitBlock = WaitBlock->NextWaitBlock;
} while (WaitBlock != WaitBlockArray);
-
+
/* Handle Kernel Queues */
if (CurrentThread->Queue) {
-
+
DPRINT("Waking Queue\n");
KiWakeQueue(CurrentThread->Queue);
}
-
+
/* Block the Thread */
DPRINT("Blocking the Thread: %d, %d, %d, %x\n", Alertable, WaitMode, WaitReason, KeGetCurrentThread());
- KiBlockThread(&Status,
- Alertable,
+ KiBlockThread(&Status,
+ Alertable,
WaitMode,
(UCHAR)WaitReason);
-
+
/* Check if we were executing an APC */
if (Status != STATUS_KERNEL_APC) {
-
+
/* Return Status */
return Status;
}
-
+
DPRINT("Looping Again\n");
CurrentThread->WaitIrql = KeAcquireDispatcherDatabaseLock();
-
+
} while (TRUE);
-
+
WaitDone:
/* Release the Lock, we are done */
DPRINT("Returning from KeWaitForMultipleObjects(), %x. Status: %d\n", KeGetCurrentThread(), Status);
{
/* Special case for Mutants */
if (Object->Type == MutantObject) {
-
+
/* Decrease the Signal State */
Object->SignalState--;
-
+
/* Check if it's now non-signaled */
if (Object->SignalState == 0) {
-
+
/* Set the Owner Thread */
((PKMUTANT)Object)->OwnerThread = Thread;
-
+
/* Disable APCs if needed */
Thread->KernelApcDisable -= ((PKMUTANT)Object)->ApcDisable;
-
+
/* Check if it's abandoned */
if (((PKMUTANT)Object)->Abandoned) {
-
+
/* Unabandon it */
((PKMUTANT)Object)->Abandoned = FALSE;
-
+
/* Return Status */
Thread->WaitStatus = STATUS_ABANDONED;
}
-
+
/* Insert it into the Mutant List */
InsertHeadList(&Thread->MutantListHead, &((PKMUTANT)Object)->MutantListEntry);
}
-
+
} else if ((Object->Type & TIMER_OR_EVENT_TYPE) == EventSynchronizationObject) {
-
+
/* These guys (Syncronization Timers and Events) just get un-signaled */
Object->SignalState = 0;
-
+
} else if (Object->Type == SemaphoreObject) {
/* These ones can have multiple signalings, so we only decrease it */
Object->SignalState--;
- }
+ }
}
VOID
PKWAIT_BLOCK CurrentWaitBlock;
PKWAIT_BLOCK NextWaitBlock;
PKTHREAD WaitThread;
-
+
/* Loop the Wait Entries */
DPRINT("KiWaitTest for Object: %x\n", Object);
WaitList = &Object->WaitListHead;
WaitEntry = WaitList->Flink;
while ((WaitEntry != WaitList) && (Object->SignalState > 0)) {
-
+
/* Get the current wait block */
CurrentWaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
WaitThread = CurrentWaitBlock->Thread;
-
+
/* Check the current Wait Mode */
if (CurrentWaitBlock->WaitType == WaitAny) {
-
+
/* Easy case, satisfy only this wait */
DPRINT("Satisfiying a Wait any\n");
WaitEntry = WaitEntry->Blink;
KiSatisfyObjectWait(Object, WaitThread);
-
+
} else {
-
+
/* Everything must be satisfied */
DPRINT("Checking for a Wait All\n");
NextWaitBlock = CurrentWaitBlock->NextWaitBlock;
-
+
/* Loop first to make sure they are valid */
while (NextWaitBlock != CurrentWaitBlock) {
-
+
/* Check if the object is signaled */
DPRINT("Checking: %x %d\n", NextWaitBlock->Object, Object->SignalState);
if (!KiIsObjectSignaled(NextWaitBlock->Object, WaitThread)) {
-
+
/* It's not, move to the next one */
DPRINT("One of the object is non-signaled, sorry.\n");
goto SkipUnwait;
}
-
+
/* Go to the next Wait block */
NextWaitBlock = NextWaitBlock->NextWaitBlock;
}
-
+
/* All the objects are signaled, we can satisfy */
DPRINT("Satisfiying a Wait All\n");
WaitEntry = WaitEntry->Blink;
KiSatisifyMultipleObjectWaits(CurrentWaitBlock);
}
-
+
/* All waits satisfied, unwait the thread */
DPRINT("Unwaiting the Thread\n");
KiAbortWaitThread(WaitThread, CurrentWaitBlock->WaitKey, Increment);
/* Next entry */
WaitEntry = WaitEntry->Flink;
}
-
+
DPRINT("Done\n");
-}
+}
/* Must be called with the dispatcher lock held */
VOID
-FASTCALL
-KiAbortWaitThread(PKTHREAD Thread,
+FASTCALL
+KiAbortWaitThread(PKTHREAD Thread,
NTSTATUS WaitStatus,
KPRIORITY Increment)
{
DPRINT("Removing waits\n");
WaitBlock = Thread->WaitBlockList;
do {
-
+
/* Remove it */
DPRINT("Removing Waitblock: %x, %x\n", WaitBlock, WaitBlock->NextWaitBlock);
RemoveEntryList(&WaitBlock->WaitListEntry);
-
+
/* Go to the next one */
WaitBlock = WaitBlock->NextWaitBlock;
} while (WaitBlock != Thread->WaitBlockList);
-
+
/* Check if there's a Thread Timer */
if (Thread->Timer.Header.Inserted) {
-
+
/* Cancel the Thread Timer with the no-lock fastpath */
DPRINT("Removing the Thread's Timer\n");
Thread->Timer.Header.Inserted = FALSE;
RemoveEntryList(&Thread->Timer.TimerListEntry);
}
-
+
/* Increment the Queue's active threads */
if (Thread->Queue) {
-
+
DPRINT("Incrementing Queue's active threads\n");
Thread->Queue->CurrentCount++;
}
/* Mutants are...well...mutants! */
if (Object->Type == MutantObject) {
- /*
+ /*
* Because Cutler hates mutants, they are actually signaled if the Signal State is <= 0
* Well, only if they are recursivly acquired (i.e if we own it right now).
* Of course, they are also signaled if their signal state is 1.
*/
- if ((Object->SignalState <= 0 && ((PKMUTANT)Object)->OwnerThread == Thread) ||
+ if ((Object->SignalState <= 0 && ((PKMUTANT)Object)->OwnerThread == Thread) ||
(Object->SignalState == 1)) {
-
+
/* Signaled Mutant */
return (TRUE);
-
+
} else {
-
+
/* Unsignaled Mutant */
return (FALSE);
}
}
-
+
/* Any other object is not a mutated freak, so let's use logic */
return (!Object->SignalState <= 0);
}
{
POBJECT_HEADER Header;
Header = BODY_TO_HEADER(Object);
-
+
if (Header->ObjectType == ExEventObjectType ||
Header->ObjectType == ExIoCompletionType ||
Header->ObjectType == ExMutantObjectType ||
Header->ObjectType == PsProcessType ||
Header->ObjectType == PsThreadType ||
Header->ObjectType == IoFileObjectType) {
-
+
return TRUE;
-
+
} else {
-
+
return FALSE;
}
}
{
PKWAIT_BLOCK FirstBlock = WaitBlock;
PKTHREAD WaitThread = WaitBlock->Thread;
-
+
/* Loop through all the Wait Blocks, and wake each Object */
do {
-
+
/* Wake the Object */
KiSatisfyObjectWait(WaitBlock->Object, WaitThread);
WaitBlock = WaitBlock->NextWaitBlock;
KeAcquireSpinLockAtDpcLevel (&DispatcherDatabaseLock);
}
-VOID
+VOID
inline
FASTCALL
KeInitializeDispatcher(VOID)
KeReleaseDispatcherDatabaseLock(KIRQL OldIrql)
{
/* If it's the idle thread, dispatch */
- if (!KeIsExecutingDpc() && OldIrql < DISPATCH_LEVEL && KeGetCurrentThread() != NULL &&
+ if (!KeIsExecutingDpc() && OldIrql < DISPATCH_LEVEL && KeGetCurrentThread() != NULL &&
KeGetCurrentThread() == KeGetCurrentPrcb()->IdleThread) {
-
+
KiDispatchThreadNoLock(Ready);
KeLowerIrql(OldIrql);
-
+
} else {
-
+
/* Just release the spin lock */
KeReleaseSpinLock(&DispatcherDatabaseLock, OldIrql);
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ldr/init.c
* PURPOSE: Loaders for PE executables
- *
+ *
* PROGRAMMERS: Jean Michault
* Rex Jolliff (rex@lvcablemodem.com)
*/
#include <internal/debug.h>
-/*
+/*
* HACK! No matter what i did, i couldnt get it working when i put these into ntos\rtl.h
* (got redefinition problems, since ntdll\rtl.h somehow include ntos\rtl.h).
* We need to merge ntos\rtl.h and ntdll\rtl.h to get this working. -Gunnar
return Status;
}
-
+
Status = RtlCreateProcessParameters(
&Params,
&ImagePath,
NULL,
NULL
);
-
+
if(!NT_SUCCESS(Status))
{
DPRINT1("Failed to create ppb!\n");
ZwClose(SystemProcessHandle);
return Status;
}
-
+
DPRINT("Creating process\n");
ZwClose(SystemProcessHandle);
RtlDestroyProcessParameters(Params);
-
+
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreateProcess() failed (Status %lx)\n", Status);
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ldr/resource.c
/* get the pointer to the export directory */
ExportDir = (PIMAGE_EXPORT_DIRECTORY)
- RtlImageDirectoryEntryToData (BaseAddress, TRUE,
+ RtlImageDirectoryEntryToData (BaseAddress, TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT, &i);
if (!ExportDir || !i || !ProcedureAddress)
{
return(STATUS_INVALID_PARAMETER);
}
-
+
AddressPtr = (PULONG)RVA((char*)BaseAddress, ExportDir->AddressOfFunctions);
if (Name && Name->Length)
{
LONG minn, maxn;
/* by name */
- OrdinalPtr =
+ OrdinalPtr =
(PUSHORT)RVA((char*)BaseAddress, ExportDir->AddressOfNameOrdinals);
NamePtr = (PULONG)RVA((char*)BaseAddress, ExportDir->AddressOfNames);
Name->Length);
if (res == 0)
{
- *ProcedureAddress =
+ *ProcedureAddress =
(PVOID)RVA((char*)BaseAddress, AddressPtr[OrdinalPtr[mid]]);
return(STATUS_SUCCESS);
}
for (i = 0; i < ExportDir->NumberOfNames; i++, NamePtr++, OrdinalPtr++)
{
- if (!_strnicmp(Name->Buffer,
+ if (!_strnicmp(Name->Buffer,
(char*)((char*)BaseAddress + *NamePtr), Name->Length))
{
- *ProcedureAddress =
- (PVOID)((ULONG)BaseAddress +
+ *ProcedureAddress =
+ (PVOID)((ULONG)BaseAddress +
(ULONG)AddressPtr[*OrdinalPtr]);
return STATUS_SUCCESS;
}
Ordinal &= 0x0000FFFF;
if (Ordinal - ExportDir->Base < ExportDir->NumberOfFunctions)
{
- *ProcedureAddress =
- (PVOID)((ULONG)BaseAddress +
+ *ProcedureAddress =
+ (PVOID)((ULONG)BaseAddress +
(ULONG)AddressPtr[Ordinal - ExportDir->Base]);
return STATUS_SUCCESS;
}
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ldr/sysdll.c
* PURPOSE: Loaders for PE executables
- *
+ *
* PROGRAMMERS: Jean Michault
* Rex Jolliff (rex@lvcablemodem.com)
* Skywing
{
ANSI_STRING ProcedureName;
NTSTATUS Status;
-
+
/* Retrieve ntdll's startup address */
DPRINT("Getting Entrypoint: %p\n", LdrpSystemDllBase);
RtlInitAnsiString(&ProcedureName, "LdrInitializeThunk");
&ProcedureName,
0,
&SystemDllEntryPoint);
-
+
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
&ProcedureName,
0,
&SystemDllApcDispatcher);
-
+
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
-
+
/* Get Exception Dispatcher */
DPRINT("Getting Entrypoint\n");
RtlInitAnsiString(&ProcedureName, "KiUserExceptionDispatcher");
&ProcedureName,
0,
&SystemDllExceptionDispatcher);
-
+
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
-
+
/* Get Callback Dispatcher */
DPRINT("Getting Entrypoint\n");
RtlInitAnsiString(&ProcedureName, "KiUserCallbackDispatcher");
&ProcedureName,
0,
&SystemDllCallbackDispatcher);
-
+
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
-
+
/* Get Raise Exception Dispatcher */
DPRINT("Getting Entrypoint\n");
RtlInitAnsiString(&ProcedureName, "KiRaiseUserExceptionDispatcher");
&ProcedureName,
0,
&SystemDllRaiseExceptionDispatcher);
-
+
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1 ("LdrGetProcedureAddress failed (Status %x)\n", Status);
return (Status);
}
NTSTATUS
STDCALL
-LdrpMapSystemDll(PEPROCESS Process,
+LdrpMapSystemDll(PEPROCESS Process,
PVOID *DllBase)
{
NTSTATUS Status;
ULONG ViewSize = 0;
PVOID ImageBase = 0;
-
+
/* Map the System DLL */
DPRINT("Mapping System DLL\n");
Status = MmMapViewOfSection(LdrpSystemDllSection,
0,
MEM_COMMIT,
PAGE_READWRITE);
-
+
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1("Failed to map System DLL Into Process\n");
}
-
+
if (DllBase) *DllBase = ImageBase;
-
+
return Status;
}
CHAR BlockBuffer[1024];
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NTHeaders;
-
+
/* Locate and open NTDLL to determine ImageBase and LdrStartup */
InitializeObjectAttributes(&FileObjectAttributes,
&DllPathname,
0,
NULL,
NULL);
-
+
DPRINT("Opening NTDLL\n");
Status = ZwOpenFile(&FileHandle,
FILE_READ_ACCESS,
&Iosb,
FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT);
-
+
if (!NT_SUCCESS(Status)) {
DPRINT1("NTDLL open failed (Status %x)\n", Status);
return Status;
}
-
+
/* Load NTDLL is valid */
DPRINT("Reading NTDLL\n");
Status = ZwReadFile(FileHandle,
0,
0);
if (!NT_SUCCESS(Status) || Iosb.Information != sizeof(BlockBuffer)) {
-
+
DPRINT1("NTDLL header read failed (Status %x)\n", Status);
ZwClose(FileHandle);
return Status;
}
-
+
/* Check if it's valid */
DosHeader = (PIMAGE_DOS_HEADER)BlockBuffer;
NTHeaders = (PIMAGE_NT_HEADERS)(BlockBuffer + DosHeader->e_lfanew);
-
- if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE) ||
- (DosHeader->e_lfanew == 0L) ||
+
+ if ((DosHeader->e_magic != IMAGE_DOS_SIGNATURE) ||
+ (DosHeader->e_lfanew == 0L) ||
(*(PULONG) NTHeaders != IMAGE_NT_SIGNATURE)) {
-
+
DPRINT1("NTDLL format invalid\n");
- ZwClose(FileHandle);
+ ZwClose(FileHandle);
return(STATUS_UNSUCCESSFUL);
}
-
+
/* Create a section for NTDLL */
DPRINT("Creating section\n");
Status = ZwCreateSection(&NTDllSectionHandle,
SEC_IMAGE | SEC_COMMIT,
FileHandle);
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1("NTDLL create section failed (Status %x)\n", Status);
- ZwClose(FileHandle);
+ ZwClose(FileHandle);
return(Status);
}
- ZwClose(FileHandle);
-
+ ZwClose(FileHandle);
+
/* Reference the Section */
DPRINT("ObReferenceObjectByHandle section: %d\n", NTDllSectionHandle);
Status = ObReferenceObjectByHandle(NTDllSectionHandle,
(PVOID*)&LdrpSystemDllSection,
NULL);
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1("NTDLL section reference failed (Status %x)\n", Status);
return(Status);
}
-
+
/* Map it */
LdrpMapSystemDll(PsGetCurrentProcess(), &LdrpSystemDllBase);
DPRINT("LdrpSystemDllBase: %x\n", LdrpSystemDllBase);
-
+
/* Now get the Entrypoints */
LdrpGetSystemDllEntryPoints();
-
+
return STATUS_SUCCESS;
}
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ldr/userldr.c
* PURPOSE: Loaders for PE executables
- *
+ *
* PROGRAMMERS: Jean Michault
* Rex Jolliff (rex@lvcablemodem.com)
*/
* PARAMETERS:
* ProcessHandle
* Points to the process to map the image into
- *
+ *
* SectionHandle
* Points to the section to map
- *
+ *
* RETURNS: Status
*/
-{
+{
ULONG ViewSize;
PVOID ImageBase;
NTSTATUS Status;
ViewSize = 0;
ImageBase = 0;
-
+
Status = ZwMapViewOfSection(SectionHandle,
ProcessHandle,
(PVOID*)&ImageBase,
CPRINT("Image map view of section failed (Status %x)", Status);
return(Status);
}
-
+
*ReturnedImageBase = ImageBase;
-
+
return(STATUS_SUCCESS);
}
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/close.c
* PURPOSE: Communication mechanism
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
NiDeletePort (PVOID ObjectBody)
{
// PEPORT Port = (PEPORT)ObjectBody;
-
+
// DPRINT1("Deleting port %x\n", Port);
}
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/complete.c
* PURPOSE: Communication mechanism
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
{
NTSTATUS Status;
PEPORT ReplyPort;
-
+
DPRINT("NtCompleteConnectPort(hServerSideCommPort %x)\n", hServerSideCommPort);
-
+
/*
* Ask Ob to translate the port handle to EPORT
*/
* otherwise tell the caller the port handle is not
* valid.
*/
- if (ReplyPort->Type != EPORT_TYPE_SERVER_COMM_PORT)
+ if (ReplyPort->Type != EPORT_TYPE_SERVER_COMM_PORT)
{
ObDereferenceObject (ReplyPort);
return STATUS_INVALID_PORT_HANDLE;
}
-
+
ReplyPort->State = EPORT_CONNECTED_SERVER;
/*
* Wake up the client thread that issued NtConnectPort.
- */
- KeReleaseSemaphore(&ReplyPort->OtherPort->Semaphore, IO_NO_INCREMENT, 1,
+ */
+ KeReleaseSemaphore(&ReplyPort->OtherPort->Semaphore, IO_NO_INCREMENT, 1,
FALSE);
/*
* Tell Ob we are no more interested in ReplyPort
- */
+ */
ObDereferenceObject (ReplyPort);
-
+
return (STATUS_SUCCESS);
}
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/connect.c
* PURPOSE: Communication mechanism
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/*
* Allocate a request message.
*/
- RequestMessage = ExAllocatePool(NonPagedPool,
- sizeof(EPORT_CONNECT_REQUEST_MESSAGE) +
+ RequestMessage = ExAllocatePool(NonPagedPool,
+ sizeof(EPORT_CONNECT_REQUEST_MESSAGE) +
RequestConnectDataLength);
if (RequestMessage == NULL)
{
/*
* Initialize the request message.
*/
- RequestMessage->MessageHeader.DataSize =
+ RequestMessage->MessageHeader.DataSize =
sizeof(EPORT_CONNECT_REQUEST_MESSAGE) + RequestConnectDataLength -
sizeof(LPC_MESSAGE);
- RequestMessage->MessageHeader.MessageSize =
+ RequestMessage->MessageHeader.MessageSize =
sizeof(EPORT_CONNECT_REQUEST_MESSAGE) + RequestConnectDataLength;
DPRINT("RequestMessageSize %d\n",
RequestMessage->MessageHeader.MessageSize);
memcpy(RequestMessage->ConnectData, ConnectData,
RequestConnectDataLength);
}
-
+
/*
* Queue the message to the named port
*/
OurPort);
KeReleaseSemaphore(&NamedPort->Semaphore, IO_NO_INCREMENT, 1, FALSE);
ExFreePool(RequestMessage);
-
+
/*
* Wait for them to accept our connection
*/
FALSE,
NULL);
- /*
+ /*
* Dequeue the response
*/
KeAcquireSpinLock (&OurPort->Lock, &oldIrql);
/**********************************************************************
* NAME EXPORTED
* NtConnectPort/8
- *
+ *
* DESCRIPTION
- * Connect to a named port and wait for the other side to
+ * Connect to a named port and wait for the other side to
* accept or reject the connection request.
*
* ARGUMENTS
* MaxMessageSize
* ConnectInfo
* UserConnectInfoLength
- *
+ *
* RETURN VALUE
- *
+ *
* @unimplemented
*/
NTSTATUS STDCALL
PEPORT ConnectedPort;
NTSTATUS Status;
PEPORT NamedPort;
-
+
/*
* Copy in write map and partially validate.
*/
}
ObDereferenceObject(NamedPort);
NamedPort = NULL;
-
+
/*
* Copy the data back to the caller.
*/
{
return(STATUS_NO_MEMORY);
}
-
+
Status = ObReferenceObjectByHandle(NamedPortHandle,
PORT_ALL_ACCESS,
LpcPortObjectType,
ConnectionRequest = EiDequeueConnectMessagePort (NamedPort);
KeReleaseSpinLock(&NamedPort->Lock, oldIrql);
CRequest = (PEPORT_CONNECT_REQUEST_MESSAGE)(&ConnectionRequest->Message);
-
+
/*
* Prepare the reply.
*/
if (LpcMessage != NULL)
{
memcpy(&CReply->MessageHeader, LpcMessage, sizeof(LPC_MESSAGE));
- memcpy(&CReply->ConnectData, (PVOID)(LpcMessage + 1),
+ memcpy(&CReply->ConnectData, (PVOID)(LpcMessage + 1),
LpcMessage->DataSize);
CReply->MessageHeader.MessageSize =
sizeof(EPORT_CONNECT_REPLY_MESSAGE) + LpcMessage->DataSize;
CReply->ConnectDataLength = 0;
}
if (!AcceptIt)
- {
+ {
EiReplyOrRequestPort(ConnectionRequest->Sender,
&CReply->MessageHeader,
LPC_CONNECTION_REFUSED,
1,
FALSE);
ObDereferenceObject(ConnectionRequest->Sender);
- ExFreePool(ConnectionRequest);
+ ExFreePool(ConnectionRequest);
ExFreePool(CReply);
ObDereferenceObject(NamedPort);
return (STATUS_SUCCESS);
}
-
+
/*
* Prepare the connection.
*/
if (!NT_SUCCESS(Status))
{
return(Status);
- }
+ }
WriteMap->ViewBase = 0;
Status = MmMapViewOfSection(SectionObject,
if (!NT_SUCCESS(Status))
{
return(Status);
- }
-
+ }
+
ObDereferenceObject(SectionObject);
}
if (ReadMap != NULL && CRequest->SendSectionObject != NULL)
OurPort);
ExFreePool(ConnectionRequest);
ExFreePool(CReply);
-
+
ObDereferenceObject(OurPort);
ObDereferenceObject(NamedPort);
-
+
return (STATUS_SUCCESS);
}
/**********************************************************************
* NAME EXPORTED
* NtSecureConnectPort/9
- *
+ *
* DESCRIPTION
- * Connect to a named port and wait for the other side to
+ * Connect to a named port and wait for the other side to
* accept the connection. Possibly verify that the server
* matches the ServerSid (trusted server).
* Present in w2k+.
* MaxMessageSize
* ConnectInfo
* UserConnectInfoLength
- *
+ *
* RETURN VALUE
*/
NTSTATUS STDCALL
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/create.c
* PURPOSE: Communication mechanism
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
*
* RETURN VALUE
*/
-STATIC NTSTATUS STDCALL
+STATIC NTSTATUS STDCALL
LpcpVerifyCreateParameters (IN PHANDLE PortHandle,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG MaxConnectInfoLength,
{
return (STATUS_SUCCESS);
}
-
+
if (wcschr(RemainingPath+1, '\\') != NULL)
{
return (STATUS_UNSUCCESSFUL);
}
-
+
return (STATUS_SUCCESS);
}
/**********************************************************************
* NAME EXPORTED
* NtCreatePort/5
- *
+ *
* DESCRIPTION
*
* ARGUMENTS
* MaxConnectInfoLength,
* MaxDataLength,
* MaxPoolUsage: size of NP zone the NP part of msgs is kept in
- *
+ *
* RETURN VALUE
*/
-/*EXPORTED*/ NTSTATUS STDCALL
+/*EXPORTED*/ NTSTATUS STDCALL
NtCreatePort (PHANDLE PortHandle,
POBJECT_ATTRIBUTES ObjectAttributes,
ULONG MaxConnectInfoLength,
{
PEPORT Port;
NTSTATUS Status;
-
+
DPRINT("NtCreatePort() Name %x\n", ObjectAttributes->ObjectName->Buffer);
-
+
/* Verify parameters */
Status = LpcpVerifyCreateParameters (PortHandle,
ObjectAttributes,
Port->MaxConnectInfoLength = PORT_MAX_DATA_LENGTH;
Port->MaxDataLength = PORT_MAX_MESSAGE_LENGTH;
Port->MaxPoolUsage = MaxPoolUsage;
-
+
ObDereferenceObject (Port);
-
+
return (Status);
}
/**********************************************************************
* NAME EXPORTED
* NtCreateWaitablePort/5
- *
+ *
* DESCRIPTION
* Waitable ports can be connected to with NtSecureConnectPort.
* No port interface can be used with waitable ports but
* MaxConnectInfoLength,
* MaxDataLength,
* MaxPoolUsage
- *
+ *
* RETURN VALUE
*/
/*EXPORTED*/ NTSTATUS STDCALL
IN ULONG MaxPoolUsage)
{
NTSTATUS Status;
-
+
/* Verify parameters */
Status = LpcpVerifyCreateParameters (PortHandle,
ObjectAttributes,
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/listen.c
* PURPOSE: Communication mechanism
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
IN PLPC_MESSAGE ConnectMsg)
{
NTSTATUS Status;
-
+
/*
* Wait forever for a connection request.
*/
* Accept only LPC_CONNECTION_REQUEST requests.
* Drop any other message.
*/
- if (!NT_SUCCESS(Status) ||
+ if (!NT_SUCCESS(Status) ||
LPC_CONNECTION_REQUEST == ConnectMsg->MessageType)
{
DPRINT("Got message (type %x)\n", LPC_CONNECTION_REQUEST);
}
DPRINT("Got message (type %x)\n", ConnectMsg->MessageType);
}
-
+
return (Status);
}
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/port.c
* PURPOSE: Communication mechanism
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* Allocate Memory for the LPC Object */
LpcPortObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
RtlZeroMemory (LpcPortObjectType, sizeof (OBJECT_TYPE));
-
+
RtlInitUnicodeString(&LpcPortObjectType->TypeName,L"Port");
-
+
LpcPortObjectType->Tag = TAG('L', 'P', 'R', 'T');
LpcPortObjectType->PeakObjects = 0;
LpcPortObjectType->PeakHandles = 0;
LpcPortObjectType->DuplicationNotify = NULL;
ObpCreateTypeObject(LpcPortObjectType);
-
+
LpcpNextMessageId = 0;
ExInitializeFastMutex (& LpcpLock);
-
+
return(STATUS_SUCCESS);
}
/**********************************************************************
* NAME INTERNAL
* NiInitializePort/3
- *
+ *
* DESCRIPTION
* Initialize the EPORT object attributes. The Port
* object enters the inactive state.
Port->State = EPORT_INACTIVE;
InitializeListHead (& Port->QueueListHead);
InitializeListHead (& Port->ConnectQueueListHead);
-
+
return (STATUS_SUCCESS);
}
/**********************************************************************
* NAME SYSTEM
* NtImpersonateClientOfPort/2
- *
+ *
* DESCRIPTION
*
* ARGUMENTS
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/query.c
* PURPOSE: Communication mechanism
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/**********************************************************************
* NAME EXPORTED
* NtQueryInformationPort@20
- *
+ *
* DESCRIPTION
*
* ARGUMENTS
*/
/*EXPORTED*/ NTSTATUS STDCALL
NtQueryInformationPort (IN HANDLE PortHandle,
- IN CINT PortInformationClass,
- OUT PVOID PortInformation,
+ IN CINT PortInformationClass,
+ OUT PVOID PortInformation,
IN ULONG PortInformationLength,
OUT PULONG ReturnLength)
{
NTSTATUS Status;
PEPORT Port;
-
+
Status = ObReferenceObjectByHandle (PortHandle,
PORT_ALL_ACCESS, /* AccessRequired */
LpcPortObjectType,
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/queue.c
* PURPOSE: Communication mechanism
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
{
PQUEUEDMESSAGE Message;
PLIST_ENTRY entry;
-
+
if (IsListEmpty(&Port->QueueListHead))
{
return(NULL);
entry = RemoveHeadList (&Port->QueueListHead);
Message = CONTAINING_RECORD (entry, QUEUEDMESSAGE, QueueListEntry);
Port->QueueLength--;
-
+
return (Message);
}
{
PQUEUEDMESSAGE Message;
PLIST_ENTRY entry;
-
+
if (IsListEmpty(&Port->ConnectQueueListHead))
{
return(NULL);
entry = RemoveHeadList (&Port->ConnectQueueListHead);
Message = CONTAINING_RECORD (entry, QUEUEDMESSAGE, QueueListEntry);
Port->ConnectQueueLength--;
-
+
return (Message);
}
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/receive.c
* PURPOSE: Communication mechanism
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/reply.c
* REVISIONS
*/
NTSTATUS STDCALL
-EiReplyOrRequestPort (IN PEPORT Port,
- IN PLPC_MESSAGE LpcReply,
+EiReplyOrRequestPort (IN PEPORT Port,
+ IN PLPC_MESSAGE LpcReply,
IN ULONG MessageType,
IN PEPORT Sender)
{
KIRQL oldIrql;
PQUEUEDMESSAGE MessageReply;
-
+
if (Port == NULL)
{
KEBUGCHECK(0);
MessageReply = ExAllocatePoolWithTag(NonPagedPool, sizeof(QUEUEDMESSAGE),
TAG_LPC_MESSAGE);
MessageReply->Sender = Sender;
-
+
if (LpcReply != NULL)
{
memcpy(&MessageReply->Message, LpcReply, LpcReply->MessageSize);
}
-
+
MessageReply->Message.ClientId.UniqueProcess = PsGetCurrentProcessId();
MessageReply->Message.ClientId.UniqueThread = PsGetCurrentThreadId();
MessageReply->Message.MessageType = MessageType;
MessageReply->Message.MessageId = InterlockedIncrementUL(&LpcpNextMessageId);
-
+
KeAcquireSpinLock(&Port->Lock, &oldIrql);
EiEnqueueMessagePort(Port, MessageReply);
KeReleaseSpinLock(&Port->Lock, oldIrql);
-
+
return(STATUS_SUCCESS);
}
{
NTSTATUS Status;
PEPORT Port;
-
+
DPRINT("NtReplyPort(PortHandle %x, LpcReply %x)\n", PortHandle, LpcReply);
-
+
Status = ObReferenceObjectByHandle(PortHandle,
PORT_ALL_ACCESS, /* AccessRequired */
LpcPortObjectType,
ObDereferenceObject(Port);
return STATUS_PORT_DISCONNECTED;
}
-
- Status = EiReplyOrRequestPort(Port->OtherPort,
- LpcReply,
+
+ Status = EiReplyOrRequestPort(Port->OtherPort,
+ LpcReply,
LPC_REPLY,
Port);
KeReleaseSemaphore(&Port->OtherPort->Semaphore, IO_NO_INCREMENT, 1, FALSE);
-
+
ObDereferenceObject(Port);
-
+
return(Status);
}
/**********************************************************************
* NAME EXPORTED
* NtReplyWaitReceivePortEx
- *
+ *
* DESCRIPTION
* Can be used with waitable ports.
* Present only in w2k+.
- *
+ *
* ARGUMENTS
* PortHandle
* PortId
NTSTATUS STDCALL
NtReplyWaitReceivePortEx(IN HANDLE PortHandle,
OUT PULONG PortId,
- IN PLPC_MESSAGE LpcReply,
+ IN PLPC_MESSAGE LpcReply,
OUT PLPC_MESSAGE LpcMessage,
IN PLARGE_INTEGER Timeout)
{
PQUEUEDMESSAGE Request;
BOOLEAN Disconnected;
LARGE_INTEGER to;
-
+
DPRINT("NtReplyWaitReceivePortEx(PortHandle %x, LpcReply %x, "
"LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage);
-
+
Status = ObReferenceObjectByHandle(PortHandle,
PORT_ALL_ACCESS,
LpcPortObjectType,
Timeout = &to;
}
else Disconnected = FALSE;
-
+
/*
* Send the reply, only if port is connected
*/
if (LpcReply != NULL && !Disconnected)
{
- Status = EiReplyOrRequestPort(Port->OtherPort,
+ Status = EiReplyOrRequestPort(Port->OtherPort,
LpcReply,
LPC_REPLY,
Port);
- KeReleaseSemaphore(&Port->OtherPort->Semaphore, IO_NO_INCREMENT, 1,
+ KeReleaseSemaphore(&Port->OtherPort->Semaphore, IO_NO_INCREMENT, 1,
FALSE);
-
+
if (!NT_SUCCESS(Status))
{
ObDereferenceObject(Port);
return(Status);
}
}
-
+
/*
* Want for a message to be received
*/
ObDereferenceObject(Port);
return(Disconnected ? STATUS_PORT_DISCONNECTED : STATUS_TIMEOUT);
}
-
+
if (!NT_SUCCESS(Status))
{
if (STATUS_THREAD_IS_TERMINATING != Status)
if (!NT_SUCCESS(Status))
{
/*
- * Copying the message to the caller's buffer failed so
+ * Copying the message to the caller's buffer failed so
* undo what we did and return.
* FIXME: Also increment semaphore.
*/
{
ExFreePool(Request);
}
-
+
/*
* Dereference the port
*/
/**********************************************************************
* NAME EXPORTED
* NtReplyWaitReceivePort
- *
+ *
* DESCRIPTION
* Can be used with waitable ports.
- *
+ *
* ARGUMENTS
* PortHandle
* PortId
NTSTATUS STDCALL
NtReplyWaitReceivePort (IN HANDLE PortHandle,
OUT PULONG PortId,
- IN PLPC_MESSAGE LpcReply,
+ IN PLPC_MESSAGE LpcReply,
OUT PLPC_MESSAGE LpcMessage)
{
return(NtReplyWaitReceivePortEx (PortHandle,
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/lpc/send.c
* PURPOSE: Communication mechanism
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
*
* REVISIONS
*/
-NTSTATUS STDCALL
+NTSTATUS STDCALL
LpcSendTerminationPort (IN PEPORT Port,
IN LARGE_INTEGER CreationTime)
{
NTSTATUS Status;
LPC_TERMINATION_MESSAGE Msg;
-
+
#ifdef __USE_NT_LPC__
Msg.Header.MessageType = LPC_NEW_MESSAGE;
#endif
*
* REVISIONS
*/
-NTSTATUS STDCALL
+NTSTATUS STDCALL
LpcSendDebugMessagePort (IN PEPORT Port,
IN PLPC_DBG_MESSAGE Message,
OUT PLPC_DBG_MESSAGE Reply)
NTSTATUS Status;
KIRQL oldIrql;
PQUEUEDMESSAGE ReplyMessage;
-
- Status = EiReplyOrRequestPort(Port,
- &Message->Header,
+
+ Status = EiReplyOrRequestPort(Port,
+ &Message->Header,
LPC_REQUEST,
Port);
if (!NT_SUCCESS(Status))
UserMode,
FALSE,
NULL);
-
+
/*
* Dequeue the reply
*/
/**********************************************************************
* NAME
* LpcRequestPort/2
- *
+ *
* DESCRIPTION
*
* ARGUMENTS
* REVISIONS
* 2002-03-01 EA
* I investigated this function a bit more in depth.
- * It looks like the legal values for the MessageType field in the
+ * It looks like the legal values for the MessageType field in the
* message to send are in the range LPC_NEW_MESSAGE .. LPC_CLIENT_DIED,
* but LPC_DATAGRAM is explicitly forbidden.
*
IN PLPC_MESSAGE LpcMessage)
{
NTSTATUS Status;
-
+
DPRINT("LpcRequestPort(PortHandle %08x, LpcMessage %08x)\n", Port, LpcMessage);
#ifdef __USE_NT_LPC__
}
#endif
- Status = EiReplyOrRequestPort(Port,
- LpcMessage,
+ Status = EiReplyOrRequestPort(Port,
+ LpcMessage,
LPC_DATAGRAM,
Port);
KeReleaseSemaphore( &Port->Semaphore, IO_NO_INCREMENT, 1, FALSE );
{
NTSTATUS Status;
PEPORT Port;
-
- DPRINT("NtRequestPort(PortHandle %x LpcMessage %x)\n", PortHandle,
+
+ DPRINT("NtRequestPort(PortHandle %x LpcMessage %x)\n", PortHandle,
LpcMessage);
-
+
Status = ObReferenceObjectByHandle(PortHandle,
PORT_ALL_ACCESS,
LpcPortObjectType,
return(Status);
}
- Status = LpcRequestPort(Port->OtherPort,
+ Status = LpcRequestPort(Port->OtherPort,
LpcMessage);
-
+
ObDereferenceObject(Port);
return(Status);
}
*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS STDCALL
NtRequestWaitReplyPort (IN HANDLE PortHandle,
- PLPC_MESSAGE UnsafeLpcRequest,
+ PLPC_MESSAGE UnsafeLpcRequest,
PLPC_MESSAGE UnsafeLpcReply)
{
PETHREAD CurrentThread;
"LpcReply %x)\n", PortHandle, UnsafeLpcRequest, UnsafeLpcReply);
Status = ObReferenceObjectByHandle(PortHandle,
- PORT_ALL_ACCESS,
+ PORT_ALL_ACCESS,
LpcPortObjectType,
UserMode,
(PVOID*)&Port,
return(STATUS_PORT_MESSAGE_TOO_LONG);
}
- Status = EiReplyOrRequestPort(Port->OtherPort,
- LpcRequest,
+ Status = EiReplyOrRequestPort(Port->OtherPort,
+ LpcRequest,
LPC_REQUEST,
Port);
if (!NT_SUCCESS(Status))
return(Status);
}
ExFreePool(LpcRequest);
- KeReleaseSemaphore (&Port->OtherPort->Semaphore, IO_NO_INCREMENT,
- 1, FALSE);
-
+ KeReleaseSemaphore (&Port->OtherPort->Semaphore, IO_NO_INCREMENT,
+ 1, FALSE);
+
/*
* Wait for a reply
*/
NULL);
if (Status == STATUS_SUCCESS)
{
-
+
/*
* Dequeue the reply
*/
{
DPRINT("Message->Message.MessageSize %d\n",
Message->Message.MessageSize);
- Status = MmCopyToCaller(UnsafeLpcReply, &Message->Message,
+ Status = MmCopyToCaller(UnsafeLpcReply, &Message->Message,
Message->Message.MessageSize);
ExFreePool(Message);
}
KeAttachProcess(AttachedProcess);
}
ObDereferenceObject(Port);
-
+
return(Status);
}
/**********************************************************************
* NAME
* NtWriteRequestData/6
- *
+ *
* DESCRIPTION
*
* ARGUMENTS
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mkconfig.c
}
/*
- * Paging out non-dirty data is easy.
+ * Paging out non-dirty data is easy.
*/
if (!WasDirty)
{
* FUNCTION: Allocates a block of virtual memory in the process address space
* ARGUMENTS:
* ProcessHandle = The handle of the process which owns the virtual memory
- * BaseAddress = A pointer to the virtual memory allocated. If you
- * supply a non zero value the system will try to
- * allocate the memory at the address supplied. It round
+ * BaseAddress = A pointer to the virtual memory allocated. If you
+ * supply a non zero value the system will try to
+ * allocate the memory at the address supplied. It round
* it down to a multiple of the page size.
- * ZeroBits = (OPTIONAL) You can specify the number of high order bits
- * that must be zero, ensuring that the memory will be
+ * ZeroBits = (OPTIONAL) You can specify the number of high order bits
+ * that must be zero, ensuring that the memory will be
* allocated at a address below a certain value.
* RegionSize = The number of bytes to allocate
- * AllocationType = Indicates the type of virtual memory you like to
- * allocated, can be a combination of MEM_COMMIT,
+ * AllocationType = Indicates the type of virtual memory you like to
+ * allocated, can be a combination of MEM_COMMIT,
* MEM_RESERVE, MEM_RESET, MEM_TOP_DOWN.
* Protect = Indicates the protection type of the pages allocated, can be
- * a combination of PAGE_READONLY, PAGE_READWRITE,
- * PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD,
+ * a combination of PAGE_READONLY, PAGE_READWRITE,
+ * PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_GUARD,
* PAGE_NOACCESS
* RETURNS: Status
*/
MemoryAreaLength = (ULONG_PTR)MemoryArea->EndingAddress -
(ULONG_PTR)MemoryArea->StartingAddress;
-
+
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
MemoryAreaLength, Type, Protect);
/*
* FUNCTION: Frees a range of virtual memory
* ARGUMENTS:
- * ProcessHandle = Points to the process that allocated the virtual
+ * ProcessHandle = Points to the process that allocated the virtual
* memory
- * BaseAddress = Points to the memory address, rounded down to a
+ * BaseAddress = Points to the memory address, rounded down to a
* multiple of the pagesize
- * RegionSize = Limits the range to free, rounded up to a multiple of
+ * RegionSize = Limits the range to free, rounded up to a multiple of
* the paging size
* FreeType = Can be one of the values: MEM_DECOMMIT, or MEM_RELEASE
- * RETURNS: Status
+ * RETURNS: Status
*/
{
MEMORY_AREA* MemoryArea;
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/aspace.c
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/balance.c
* PURPOSE: kernel memory managment functions
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
}
/*
- * Allocate always memory for the non paged pool and for the pager thread.
+ * Allocate always memory for the non paged pool and for the pager thread.
*/
if (Consumer == MC_NPPOOL || MiIsBalancerThread())
{
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/cont.c
* DESCRIPTION
* Allocates a range of physically contiguous cache aligned
* memory from the non-paged pool.
- *
+ *
* ARGUMENTS
* NumberOfBytes
* Size of the memory block to allocate;
- *
+ *
* HighestAcceptableAddress
* Highest address valid for the caller.
- *
+ *
* RETURN VALUE
* The virtual address of the memory block on success;
* NULL on error.
* DESCRIPTION
* Releases a range of physically contiguous memory allocated
* with MmAllocateContiguousMemory.
- *
+ *
* ARGUMENTS
* BaseAddress
* Virtual address of the memory to be freed.
* DESCRIPTION
* Allocates a range of physically contiguous memory
* with a cache parameter.
- *
+ *
* ARGUMENTS
* NumberOfBytes
* Size of the memory block to allocate;
- *
+ *
* LowestAcceptableAddress
* Lowest address valid for the caller.
- *
+ *
* HighestAcceptableAddress
* Highest address valid for the caller.
- *
+ *
* BoundaryAddressMultiple
* Address multiple not to be crossed by allocated buffer (optional).
- *
+ *
* CacheType
* Type of caching to use.
- *
+ *
* RETURN VALUE
* The virtual address of the memory block on success;
* NULL on error.
* DESCRIPTION
* Releases a range of physically contiguous memory allocated
* with MmAllocateContiguousMemorySpecifyCache.
- *
+ *
* ARGUMENTS
* BaseAddress
* Virtual address of the memory to be freed.
*
* NumberOfBytes
* Size of the memory block to free.
- *
+ *
* CacheType
* Type of caching used.
- *
+ *
* RETURN VALUE
* None.
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/drvlck.c
* PURPOSE: Managing driver managing
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
MmUnlockPagableImageSection(IN PVOID ImageSectionHandle)
/*
* FUNCTION: Releases a section of driver code or driver data, previously
- * locked into system space with MmLockPagableCodeSection,
+ * locked into system space with MmLockPagableCodeSection,
* MmLockPagableDataSection or MmLockPagableSectionByHandle
* ARGUMENTS:
* ImageSectionHandle = Handle returned by MmLockPagableCodeSection or
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/elf32.c
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/elf64.c
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/freelist.c
* PURPOSE: Handle the list of free physical pages
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
* Robert Bergkvist
*/
MmPageArray[i].Flags.Zero = 0;
}
}
-
+
return start;
}
}
return TRUE;
}
-
+
PVOID INIT_FUNCTION
MmInitializePageList(ULONG_PTR FirstPhysKernelAddress,
MmSetPageProtect(NULL, Address, PAGE_READWRITE);
}
memset(Address, 0, PAGE_SIZE);
-
+
start = ((ULONG_PTR)Address - (ULONG_PTR)MmPageArray) / sizeof(PHYSICAL_PAGE);
end = ((ULONG_PTR)Address - (ULONG_PTR)MmPageArray + PAGE_SIZE) / sizeof(PHYSICAL_PAGE);
{
KEBUGCHECK(0);
}
-
+
MmLockPageUnsafe(Pfn);
}
HighestPage = HighestAddress.QuadPart / PAGE_SIZE;
if ((HighestAddress.u.LowPart % PAGE_SIZE) != 0)
HighestPage++;
-
+
if (LowestPage >= MmPageArraySize)
{
DPRINT1("MmAllocPagesSpecifyRange(): Out of memory\n");
{
NTSTATUS Status;
HANDLE ThreadHandle;
-
+
ZeroPageThreadShouldTerminate = FALSE;
Status = PsCreateSystemThread(&ThreadHandle,
THREAD_ALL_ACCESS,
#define PAE_PAGEDIRECTORY_MAP (0xf0000000 + (PAGETABLE_MAP / (512)))
-#define HYPERSPACE (0xf0800000)
+#define HYPERSPACE (0xf0800000)
#define IS_HYPERSPACE(v) (((ULONG)(v) >= 0xF0800000 && (ULONG)(v) < 0xF0C00000))
ULONG MmGlobalKernelPageDirectory[1024];
ULONGLONG MmGlobalKernelPageDirectoryForPAE[2048];
#define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT)
-#define PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
+#define PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
#define PAE_PTE_TO_PFN(X) (PAE_PAGE_MASK(X) >> PAGE_SHIFT)
#define PAE_PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
DPRINT1("Unknown main protection type.\n");
KEBUGCHECK(0);
}
- if (Ke386NoExecute &&
+ if (Ke386NoExecute &&
!(flProtect & PAGE_IS_EXECUTABLE))
{
Attributes = Attributes | 0x80000000;
#define ADDR_TO_PDE_OFFSET(v) ((((ULONG)(v)) / (1024 * PAGE_SIZE)))
-#define ADDR_TO_PTE_OFFSET(v) ((((ULONG)(v)) % (1024 * PAGE_SIZE)) / PAGE_SIZE)
+#define ADDR_TO_PTE_OFFSET(v) ((((ULONG)(v)) % (1024 * PAGE_SIZE)) / PAGE_SIZE)
#define PAE_ADDR_TO_PAGE_TABLE(v) (((ULONG)(v)) / (512 * PAGE_SIZE))
{
if (PageDir[j] != 0LL)
{
- DPRINT1("ProcessId %d, Pde for %08x - %08x is not freed, RefCount %d\n",
+ DPRINT1("ProcessId %d, Pde for %08x - %08x is not freed, RefCount %d\n",
Process->UniqueProcessId,
- (i * 512 + j) * 512 * PAGE_SIZE, (i * 512 + j + 1) * 512 * PAGE_SIZE - 1,
+ (i * 512 + j) * 512 * PAGE_SIZE, (i * 512 + j + 1) * 512 * PAGE_SIZE - 1,
Process->AddressSpace.PageTableRefCountTable[i*512 + j]);
Pde = MmCreateHyperspaceMapping(PAE_PTE_TO_PFN(PageDir[j]));
for (k = 0; k < 512; k++)
{
if (PageDir[i] != 0)
{
- DPRINT1("Pde for %08x - %08x is not freed, RefCount %d\n",
- i * 4 * 1024 * 1024, (i + 1) * 4 * 1024 * 1024 - 1,
+ DPRINT1("Pde for %08x - %08x is not freed, RefCount %d\n",
+ i * 4 * 1024 * 1024, (i + 1) * 4 * 1024 * 1024 - 1,
Process->AddressSpace.PageTableRefCountTable[i]);
Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(PageDir[i]));
for (j = 0; j < 1024; j++)
return(STATUS_SUCCESS);
}
-NTSTATUS
+NTSTATUS
STDCALL
-MmCopyMmInfo(PEPROCESS Src,
- PEPROCESS Dest,
+MmCopyMmInfo(PEPROCESS Src,
+ PEPROCESS Dest,
PPHYSICAL_ADDRESS DirectoryTableBase)
{
NTSTATUS Status;
ULONG i, j;
PFN_TYPE Pfn[7];
ULONG Count;
-
+
DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
Count = Ke386Pae ? 7 : 2;
{
KEBUGCHECK(0);
}
- Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER;
+ Entry = PFN_TO_PTE(Pfn) | PA_PRESENT | PA_READWRITE | PA_USER;
Entry = ExfInterlockedCompareExchange64UL(PageDir, &Entry, &ZeroEntry);
if (Entry != 0LL)
{
}
}
}
- return (PULONGLONG)PAE_ADDR_TO_PTE(Address);
+ return (PULONGLONG)PAE_ADDR_TO_PTE(Address);
}
-static PULONG
+static PULONG
MmGetPageTableForProcess(PEPROCESS Process, PVOID Address, BOOLEAN Create)
{
ULONG PdeOffset = ADDR_TO_PDE_OFFSET(Address);
PFN_TYPE Pfn;
ULONG Entry;
PULONG Pt, PageDir;
-
+
if (Address < (PVOID)KERNEL_BASE && Process && Process != PsGetCurrentProcess())
{
PageDir = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase.QuadPart));
}
}
}
- return (PULONG)ADDR_TO_PTE(Address);
+ return (PULONG)ADDR_TO_PTE(Address);
}
BOOLEAN MmUnmapPageTable(PULONG Pt)
}
return 0;
}
-
+
PFN_TYPE
MmGetPfnForProcess(PEPROCESS Process,
PVOID Address)
VOID
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOL* WasDirty, PPFN_TYPE Page)
/*
- * FUNCTION: Delete a virtual mapping
+ * FUNCTION: Delete a virtual mapping
*/
{
BOOLEAN WasValid;
{
Pte = *Pt;
tmpPte = Pte & ~PA_PRESENT;
- } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
+ } while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
MiFlushTlb((PULONG)Pt, Address);
WasValid = PAE_PAGE_MASK(Pte) != 0LL ? TRUE : FALSE;
do
{
Pte = *Pt;
- } while (Pte != InterlockedCompareExchangeUL(Pt, Pte & ~PA_PRESENT, Pte));
+ } while (Pte != InterlockedCompareExchangeUL(Pt, Pte & ~PA_PRESENT, Pte));
MiFlushTlb(Pt, Address);
WasValid = (PAGE_MASK(Pte) != 0);
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOL FreePage,
BOOL* WasDirty, PPFN_TYPE Page)
/*
- * FUNCTION: Delete a virtual mapping
+ * FUNCTION: Delete a virtual mapping
*/
{
BOOLEAN WasValid = FALSE;
{
PUSHORT Ptrc;
ULONG Idx;
-
+
Ptrc = Process->AddressSpace.PageTableRefCountTable;
Idx = Ke386Pae ? PAE_ADDR_TO_PAGE_TABLE(Address) : ADDR_TO_PAGE_TABLE(Address);
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
SWAPENTRY* SwapEntry)
/*
- * FUNCTION: Delete a virtual mapping
+ * FUNCTION: Delete a virtual mapping
*/
{
if (Ke386Pae)
PULONG Pt;
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
-
+
if (Pt == NULL)
{
*SwapEntry = 0;
{
KEBUGCHECK(0);
}
-
+
do
{
Pte = *Pt;
{
KEBUGCHECK(0);
}
-
+
do
{
Pte = *Pt;
do
{
Pte = *Pt;
- tmpPte = Pte | PA_DIRTY;
+ tmpPte = Pte | PA_DIRTY;
} while (Pte != ExfInterlockedCompareExchange64UL(Pt, &tmpPte, &Pte));
if (!(Pte & PA_DIRTY))
{
MmMarkPageUnmapped(PAE_PTE_TO_PFN((Pte)));
}
- if (Pte != 0)
+ if (Pte != 0)
{
MiFlushTlb((PULONG)Pt, Address);
}
MmMarkPageUnmapped(PTE_TO_PFN((Pte)));
}
InterlockedExchangeUL(Pt, SwapEntry << 1);
- if (Pte != 0)
+ if (Pte != 0)
{
MiFlushTlb(Pt, Address);
}
DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
Process, Address, flProtect, Pages, *Pages, PageCount);
-
+
if (Process == NULL)
{
if (Address < (PVOID)KERNEL_BASE)
DPRINT1("No process\n");
KEBUGCHECK(0);
}
- if (PageCount > 0x10000 ||
+ if (PageCount > 0x10000 ||
(ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
{
DPRINT1("Page count to large\n");
{
Protect = PAGE_NOACCESS;
}
- else
+ else
{
if (Entry & PA_READWRITE)
{
{
Protect |= PAGE_SYSTEM;
}
-
+
}
return(Protect);
}
}
}
}
- else
+ else
{
for (i = Page %1024; i >= 0; i--, Pte--)
{
return Address;
}
-PFN_TYPE
+PFN_TYPE
MmChangeHyperspaceMapping(PVOID Address, PFN_TYPE NewPage)
{
PFN_TYPE Pfn;
VOID MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size)
{
- ULONG StartOffset, EndOffset, Offset;
+ ULONG StartOffset, EndOffset, Offset;
if (Address < (PVOID)KERNEL_BASE)
{
Pde = (PULONGLONG)PAE_PAGEDIRECTORY_MAP + i*512;
}
- for (Offset = StartOffset; Offset <= EndOffset; Offset++)
+ for (Offset = StartOffset; Offset <= EndOffset; Offset++)
{
if (i * 512 + Offset < PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP) || i * 512 + Offset >= PAE_ADDR_TO_PDE_OFFSET(PAGETABLE_MAP)+4)
{
PULONG Pde;
StartOffset = ADDR_TO_PDE_OFFSET(Address);
EndOffset = ADDR_TO_PDE_OFFSET(Address + Size);
-
+
if (Process != NULL && Process != PsGetCurrentProcess())
{
Pde = MmCreateHyperspaceMapping(PTE_TO_PFN(Process->Pcb.DirectoryTableBase.u.LowPart));
{
Pde = (PULONG)PAGEDIRECTORY_MAP;
}
- for (Offset = StartOffset; Offset <= EndOffset; Offset++)
+ for (Offset = StartOffset; Offset <= EndOffset; Offset++)
{
if (Offset != ADDR_TO_PDE_OFFSET(PAGETABLE_MAP))
{
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/i386/pfault.c
* PURPOSE: Paging file functions
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
Cs != KERNEL_CS)
{
KIRQL oldIrql;
-
+
KeRaiseIrql(APC_LEVEL, &oldIrql);
KiDeliverApc(KernelMode, NULL, NULL);
KeLowerIrql(oldIrql);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/iospace.c
* PURPOSE: Mapping I/O space
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/**********************************************************************
* NAME EXPORTED
* MmMapIoSpace@16
- *
+ *
* DESCRIPTION
* Maps a physical memory range into system space.
- *
+ *
* ARGUMENTS
* PhysicalAddress
* First physical address to map;
- *
+ *
* NumberOfBytes
* Number of bytes to map;
- *
+ *
* CacheEnable
* Type of memory caching.
*
/**********************************************************************
* NAME EXPORTED
* MmUnmapIoSpace@8
- *
+ *
* DESCRIPTION
* Unmaps a physical memory range from system space.
- *
+ *
* ARGUMENTS
* BaseAddress
- * The base virtual address which maps the region;
- *
+ * The base virtual address which maps the region;
+ *
* NumberOfBytes
* Number of bytes to unmap.
*
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/marea.c
* PURPOSE: Implements memory areas
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
PPFN_NUMBER MdlPages;
PFN_NUMBER Page;
- /*
+ /*
* MmProbeAndLockPages MUST have been called to lock this mdl!
*
- * Windows will bugcheck if you pass MmUnlockPages an mdl that hasn't been
+ * Windows will bugcheck if you pass MmUnlockPages an mdl that hasn't been
* locked with MmLockAndProbePages, but (for now) we'll be more forgiving...
*/
if (!(Mdl->MdlFlags & MDL_PAGES_LOCKED))
DPRINT1("MmUnlockPages called for non-locked mdl!\n");
return;
}
-
+
/* If mdl buffer is mapped io space -> do nothing */
if (Mdl->MdlFlags & MDL_IO_SPACE)
{
Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
return;
}
-
+
/* Automagically undo any calls to MmGetSystemAddressForMdl's for this mdl */
if (Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA)
{
}
/*
- * FIXME: I don't know whether this right, but it looks sensible
+ * FIXME: I don't know whether this right, but it looks sensible
*/
if ((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) ||
(Mdl->MdlFlags & MDL_IO_PAGE_READ))
MmUnlockPage(Page);
MmDereferencePage(Page);
}
-
+
Mdl->MdlFlags &= ~MDL_PAGES_LOCKED;
}
* ARGUMENTS:
* BaseAddress = Base virtual address to which the pages were mapped
* MemoryDescriptorList = MDL describing the mapped pages
- *
+ *
* User space unmappings _must_ be done from the original process context!
*/
{
PageCount = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
/*
- * Docs says that BaseAddress should be a _base_ address, but every example
+ * Docs says that BaseAddress should be a _base_ address, but every example
* I've seen pass the actual address. -Gunnar
*/
BaseAddress = PAGE_ALIGN(BaseAddress);
-
+
/* Unmap all the pages. */
for (i = 0; i < PageCount; i++)
{
if ((ULONG_PTR)BaseAddress >= KERNEL_BASE)
{
ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
-
+
KeAcquireSpinLock(&MiMdlMappingRegionLock, &oldIrql);
/* Deallocate all the pages used. */
Base = (ULONG)((char*)BaseAddress - (char*)MiMdlMappingRegionBase) / PAGE_SIZE;
MiMdlMappingRegionHint = min (MiMdlMappingRegionHint, Base);
KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
-
+
/* Reset the MDL state. */
Mdl->MdlFlags &= ~MDL_MAPPED_TO_SYSTEM_VA;
Mdl->MappedSystemVa = NULL;
-
+
}
else
{
MEMORY_AREA *Marea;
-
+
ASSERT(Mdl->Process == PsGetCurrentProcess());
Marea = MmLocateMemoryAreaByAddress( &Mdl->Process->AddressSpace, BaseAddress );
* Operation = Operation to probe for
*
* This function can be seen as a safe version of MmBuildMdlForNonPagedPool
- * used in cases where you know that the mdl address is paged memory or
+ * used in cases where you know that the mdl address is paged memory or
* you don't know where the mdl address comes from. MmProbeAndLockPages will
* work no matter what kind of mdl address you have.
*/
MdlPages = (PPFN_TYPE)(Mdl + 1);
NrPages = PAGE_ROUND_UP(Mdl->ByteOffset + Mdl->ByteCount) / PAGE_SIZE;
-
+
/* mdl must have enough page entries */
ASSERT(NrPages <= (Mdl->Size - sizeof(MDL))/sizeof(PFN_TYPE));
MmGetPfnForProcess(NULL, Mdl->StartVa) >= MmPageArraySize)
{
/* phys addr is not phys memory so this must be io memory */
-
+
for (i = 0; i < NrPages; i++)
{
MdlPages[i] = MmGetPfnForProcess(NULL, (char*)Mdl->StartVa + (i*PAGE_SIZE));
}
-
+
Mdl->MdlFlags |= MDL_PAGES_LOCKED|MDL_IO_SPACE;
return;
}
{
/* FIXME: why isn't AccessMode used? */
Mode = UserMode;
- Mdl->Process = CurrentProcess;
+ Mdl->Process = CurrentProcess;
AddressSpace = &CurrentProcess->AddressSpace;
}
* FIXME: skip the probing/access stuff if buffer is nonpaged kernel space?
* -Gunnar
*/
-
+
if (!MmIsPagePresent(NULL, Address))
{
Status = MmNotPresentFault(Mode, (ULONG_PTR)Address, TRUE);
{
MmLockPage(MmGetPfnForProcess(NULL, Address));
}
-
+
if ((Operation == IoWriteAccess || Operation == IoModifyAccess) &&
(!(MmGetPageProtect(NULL, (PVOID)Address) & PAGE_READWRITE)))
{
else
MmReferencePage(Page);
}
-
+
MmUnlockAddressSpace(AddressSpace);
Mdl->MdlFlags |= MDL_PAGES_LOCKED;
}
/*
* @unimplemented
*/
-VOID
+VOID
STDCALL
MmProbeAndLockSelectedPages(
IN OUT PMDL MemoryDescriptorList,
VOID STDCALL
MmBuildMdlForNonPagedPool (PMDL Mdl)
/*
- * FUNCTION: Fills in the corresponding physical page array of a given
+ * FUNCTION: Fills in the corresponding physical page array of a given
* MDL for a buffer in nonpaged system space
* ARGUMENTS:
- * Mdl = Points to an MDL that supplies a virtual address,
+ * Mdl = Points to an MDL that supplies a virtual address,
* byte offset and length
*
* This function can be seen as a fast version of MmProbeAndLockPages in case
- * you _know_ that the mdl address is within nonpaged kernel space.
+ * you _know_ that the mdl address is within nonpaged kernel space.
*/
{
ULONG i;
ULONG PageCount;
PPFN_TYPE MdlPages;
-
- /*
- * mdl buffer must (at least) be in kernel space, thou this doesn't
+
+ /*
+ * mdl buffer must (at least) be in kernel space, thou this doesn't
* necesarely mean that the buffer in within _nonpaged_ kernel space...
*/
ASSERT((ULONG_PTR)Mdl->StartVa >= KERNEL_BASE);
-
+
PageCount = PAGE_ROUND_UP(Mdl->ByteOffset + Mdl->ByteCount) / PAGE_SIZE;
MdlPages = (PPFN_TYPE)(Mdl + 1);
-
+
/* mdl must have enough page entries */
ASSERT(PageCount <= (Mdl->Size - sizeof(MDL))/sizeof(PFN_TYPE));
-
+
for (i=0; i < PageCount; i++)
{
*MdlPages++ = MmGetPfnForProcess(NULL, (char*)Mdl->StartVa + (i * PAGE_SIZE));
}
-
+
Mdl->MdlFlags |= MDL_SOURCE_IS_NONPAGED_POOL;
Mdl->Process = NULL;
Mdl->MappedSystemVa = (char*)Mdl->StartVa + Mdl->ByteOffset;
{
/*
MmAllocatePagesForMdl allocates zero-filled, nonpaged, physical memory pages to an MDL
-
- MmAllocatePagesForMdlSearch the PFN database for free, zeroed or standby
+
+ MmAllocatePagesForMdlSearch the PFN database for free, zeroed or standby
pagesAllocates pages and puts in MDLDoes not map pages (caller responsibility)
Designed to be used by an AGP driver
-
+
LowAddress is the lowest acceptable physical address it wants to allocate
and HighAddress is the highest. SkipBytes are the number of bytes that the
kernel should keep free above LowAddress and below the address at which it
from the returned MDL that describe appropriate portions of the physical
memory. When a driver wants to access physical memory described by a
sub-MDL it must map the sub-MDL using MmGetSystemAddressForMdlSafe.
-
+
Konstantin Gusev
*/
-
+
PMDL Mdl;
PPFN_TYPE Pages;
ULONG NumberOfPagesWanted, NumberOfPagesAllocated;
ULONG Ret;
-
+
DPRINT("MmAllocatePagesForMdl - LowAddress = 0x%I64x, HighAddress = 0x%I64x, "
"SkipBytes = 0x%I64x, Totalbytes = 0x%x\n",
LowAddress.QuadPart, HighAddress.QuadPart,
SkipBytes.QuadPart, Totalbytes);
-
+
/* SkipBytes must be a multiple of the page size */
if ((SkipBytes.QuadPart % PAGE_SIZE) != 0)
{
Drivers use the MmFreePagesFromMdl, the kernel-mode equivalent of
FreeUserPhysicalPages, to free the physical memory it has allocated with
MmAllocatePagesForMdl. This function is also prototyped in ntddk.h:
-
+
Note that a driver is responsible for deallocating the MDL returned by
MmAllocatePagesForMdl with a call to ExFreePool, since MmFreePagesFromMdl
does not free the MDL.
-
+
Konstantin Gusev
-
+
*/
PPFN_TYPE Pages;
LONG NumberOfPages;
-
+
NumberOfPages = PAGE_ROUND_UP(Mdl->ByteCount + Mdl->ByteOffset) / PAGE_SIZE;
Pages = (PPFN_TYPE)(Mdl + 1);
-
+
while (--NumberOfPages >= 0)
{
MmDereferencePage(Pages[NumberOfPages]);
}
KeReleaseSpinLock(&MiMdlMappingRegionLock, oldIrql);
-
+
Mdl->Process = NULL;
}
/* $Id$
*
* COPYRIGHT: See COPYING in the top directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/mm.c
* PURPOSE: Kernel memory managment functions
* PROGRAMMERS: David Welch (welch@cwcom.net)
PVOID ProcAddress;
ANSI_STRING AnsiRoutineName;
NTSTATUS Status;
-
+
if(!NT_SUCCESS(RtlUnicodeStringToAnsiString(&AnsiRoutineName,
SystemRoutineName,
TRUE)))
{
return NULL;
}
-
+
Status = LdrGetProcedureAddress(NtoskrnlModuleObject.Base,
&AnsiRoutineName,
0,
&ProcAddress);
-
+
if(!NT_SUCCESS(Status))
{
Status = LdrGetProcedureAddress(HalModuleObject.Base,
0,
&ProcAddress);
}
-
+
RtlFreeAnsiString(&AnsiRoutineName);
-
+
return (NT_SUCCESS(Status) ? ProcAddress : NULL);
}
/* $Id$
*
* COPYRIGHT: See COPYING in the top directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/mminit.c
* PURPOSE: Kernel memory managment initialization functions
*
* Initialize the kernel address space
*/
MmInitializeKernelAddressSpace();
-
+
MmInitGlobalKernelPageDirectory();
-
+
DbgPrint("Used memory %dKb\n", (MmStats.NrTotalPages * PAGE_SIZE) / 1024);
DPRINT1("Kernel Stack Limits. InitTop = 0x%x, Init = 0x%x\n", init_stack_top, init_stack);
#ifdef CONFIG_SMP
/* In SMP mode we unmap the low memory pagetable in MmInit3.
The APIC needs the mapping of the first pages
- while the processors are starting up.
+ while the processors are starting up.
We unmap all pages except page 2 and 3. */
for (MappingAddress = 0;
MappingAddress < 1024 * PAGE_SIZE;
MappingAddress += PAGE_SIZE)
{
- if (MappingAddress != 2 * PAGE_SIZE &&
+ if (MappingAddress != 2 * PAGE_SIZE &&
MappingAddress != 3 * PAGE_SIZE)
{
MmRawDeleteVirtualMapping((PVOID)MappingAddress);
* FILE: ntoskrnl/mm/mpw.c
* PURPOSE: Writes data that has been modified in memory but not on
* the disk
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/ncache.c
* PURPOSE: Manages non-cached memory
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
* DESCRIPTION
* Allocates a virtual address range of noncached and cache
* aligned memory.
- *
+ *
* ARGUMENTS
* NumberOfBytes
* Size of region to allocate.
- *
+ *
* RETURN VALUE
* The base address of the range on success;
* NULL on failure.
* MmFreeNonCachedMemory@8
*
* DESCRIPTION
- * Releases a range of noncached memory allocated with
+ * Releases a range of noncached memory allocated with
* MmAllocateNonCachedMemory.
- *
+ *
* ARGUMENTS
* BaseAddress
* Virtual address to be freed;
- *
+ *
* NumberOfBytes
* Size of the region to be freed.
- *
+ *
* RETURN VALUE
* None.
*
PFN_TYPE Page[32];
ULONG_PTR StartIndex, EndIndex;
ULONG i, j, k;
-
+
StartIndex = (ULONG_PTR)(PAGE_ROUND_UP((ULONG_PTR)blk + BLOCK_HDR_SIZE - (ULONG_PTR)MiNonPagedPoolStart)) / PAGE_SIZE;
EndIndex = ((ULONG_PTR)PAGE_ROUND_UP(end) - (ULONG_PTR)MiNonPagedPoolStart) / PAGE_SIZE;
UNIMPLEMENTED;
return 0;
-
+
#else /* not WHOLE_PAGE_ALLOCATIONS */
BLOCK_HDR* blk=address_to_block(Addr);
-
+
if (blk->Magic != BLOCK_HDR_USED_MAGIC)
KEBUGCHECK(0);
if (blk->Magic == BLOCK_HDR_FREE_MAGIC)
KEBUGCHECK(0);
-
+
return blk->Used.Tag;
#endif /* WHOLE_PAGE_ALLOCATIONS */
}
Address += PAGE_SIZE;
}
- RtlInitializeBitMap(&NonPagedPoolAllocMap, MiNonPagedPoolStart,
+ RtlInitializeBitMap(&NonPagedPoolAllocMap, MiNonPagedPoolStart,
MiNonPagedPoolLength / PAGE_SIZE);
RtlClearAllBits(&NonPagedPoolAllocMap);
RtlSetBits(&NonPagedPoolAllocMap, 0, NonPagedPoolAllocMapHint);
ULONG MiUsedSwapPages;
/*
- * Number of pages that have been reserved for swapping but not yet allocated
+ * Number of pages that have been reserved for swapping but not yet allocated
*/
static ULONG MiReservedSwapPages;
MmIsFileAPagingFile(PFILE_OBJECT FileObject)
{
ULONG i;
-
+
/* Loop through all the paging files */
for (i = 0; i < MiPagingFileCount; i++)
{
/* Check if this is one of them */
if (PagingFileList[i]->FileObject == FileObject) return TRUE;
}
-
+
/* Nothing found */
return FALSE;
}
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = Iosb.Status;
}
- MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
+ MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
return(Status);
}
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
Status = Iosb.Status;
}
- MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
+ MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
return(Status);
}
i = FILE_FROM_ENTRY(Entry);
off = OFFSET_FROM_ENTRY(Entry);
-
+
if (i >= MAX_PAGING_FILES)
{
DPRINT1("Bad swap entry 0x%.8X\n", Entry);
KEBUGCHECK(0);
}
KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock);
-
+
PagingFileList[i]->AllocMap[off >> 5] &= (~(1 << (off % 32)));
-
+
PagingFileList[i]->FreePages++;
PagingFileList[i]->UsedPages--;
for (i = 0; i < MmStats.NrTotalPages; i++)
{
MdlMap[0] = i;
- MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
+ MmCreateVirtualMappingForKernel(MmCoreDumpPageFrame,
PAGE_READWRITE,
MdlMap,
1);
FALSE,
&Event,
&Iosb);
- if(Irp == NULL)
+ if(Irp == NULL)
{
ObDereferenceObject(PageFile);
return(STATUS_NO_MEMORY);// tMk - is this correct return code ???
}
PreviousMode = ExGetPreviousMode();
-
+
Status = RtlCaptureUnicodeString(&CapturedFileName,
PreviousMode,
PagedPool,
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if (!NT_SUCCESS(Status))
{
RtlReleaseCapturedUnicodeString(&CapturedFileName,
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/pageop.c
* PURPOSE: No purpose listed.
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/*
* FUNCTION: Get a page operation descriptor corresponding to
* the memory area and either the segment, offset pair or the
- * pid, address pair.
+ * pid, address pair.
*/
{
ULONG_PTR Hash;
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/pagfault.c
-/* $Id:$
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/paging.c
* PURPOSE: Paging file functions
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/pe.c
* PURPOSE: Loader for PE executables
- *
+ *
* PROGRAMMERS: KJK::Hyperion <hackbunny@reactos.com>
*/
ASSERT(ImageSectionObject);
ASSERT(ReadFileCb);
ASSERT(AllocateSegmentsCb);
-
+
ASSERT(Intsafe_CanOffsetPointer(FileHeader, FileHeaderSize));
ASSERT(FileHeaderSize >= sizeof(IMAGE_DOS_HEADER));
/* don't trust an invalid NT header */
if(pinhNtHeader->Signature != IMAGE_NT_SIGNATURE)
DIE(("The file isn't a PE executable, Signature is %X\n", pinhNtHeader->Signature));
-
+
if(!Intsafe_AddULong32(&cbOptHeaderOffsetSize, pidhDosHeader->e_lfanew, FIELD_OFFSET(IMAGE_NT_HEADERS32, OptionalHeader)))
DIE(("The DOS stub is too large, e_lfanew is %X\n", pidhDosHeader->e_lfanew));
case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
break;
-
+
default:
DIE(("Unrecognized optional header, Magic is %X\n", piohOptHeader->Magic));
}
{
if(nCharacteristics & IMAGE_SCN_CNT_CODE)
nCharacteristics |= IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
-
+
if(nCharacteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
-
+
if(nCharacteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
nCharacteristics |= IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
}
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/physical.c
* PURPOSE: Physical Memory Manipulation functions
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/pool.c
* PURPOSE: Implements the kernel memory pool
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
* PoolType
* Specifies the type of memory to allocate which can be one
* of the following:
- *
+ *
* NonPagedPool
* NonPagedPoolMustSucceed
* NonPagedPoolCacheAligned
* NonPagedPoolCacheAlignedMustS
* PagedPool
* PagedPoolCacheAligned
- *
+ *
* NumberOfBytes
* Specifies the number of bytes to allocate
* RETURNS: The allocated block on success
*/
SIZE_T
STDCALL
-ExQueryPoolBlockSize (
- IN PVOID PoolBlock,
- OUT PBOOLEAN QuotaCharged
+ExQueryPoolBlockSize (
+ IN PVOID PoolBlock,
+ OUT PBOOLEAN QuotaCharged
)
{
UNIMPLEMENTED;
-/*
+/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/process.c
extern ULONG NtOSCSDVersion;
/* FUNCTIONS *****************************************************************/
-
+
PVOID
STDCALL
MiCreatePebOrTeb(PEPROCESS Process,
PHYSICAL_ADDRESS BoundaryAddressMultiple;
BoundaryAddressMultiple.QuadPart = 0;
PVOID AllocatedBase = BaseAddress;
-
+
/* Acquire the Lock */
MmLockAddressSpace(ProcessAddressSpace);
- /*
- * Create a Peb or Teb.
+ /*
+ * Create a Peb or Teb.
* Loop until it works, decreasing by PAGE_SIZE each time. The logic here
* is that a PEB allocation should never fail since the address is free,
* while TEB allocation can fail, and we should simply try the address
BoundaryAddressMultiple);
AllocatedBase = AllocatedBase - PAGE_SIZE;
} while (Status != STATUS_SUCCESS);
-
+
/* Initialize the Region */
MmInitialiseRegion(&MemoryArea->Data.VirtualMemoryData.RegionListHead,
- PAGE_SIZE,
- MEM_COMMIT,
+ PAGE_SIZE,
+ MEM_COMMIT,
PAGE_READWRITE);
-
+
/* Reserve the pages */
MmReserveSwapPages(PAGE_SIZE);
-
+
/* Unlock Address Space */
DPRINT("Returning\n");
MmUnlockAddressSpace(ProcessAddressSpace);
}
VOID
-MiFreeStackPage(PVOID Context,
- MEMORY_AREA* MemoryArea,
- PVOID Address,
- PFN_TYPE Page,
- SWAPENTRY SwapEntry,
+MiFreeStackPage(PVOID Context,
+ MEMORY_AREA* MemoryArea,
+ PVOID Address,
+ PFN_TYPE Page,
+ SWAPENTRY SwapEntry,
BOOLEAN Dirty)
{
ASSERT(SwapEntry == 0);
STDCALL
MmDeleteKernelStack(PVOID Stack,
BOOLEAN GuiStack)
-{
+{
/* Lock the Address Space */
MmLockAddressSpace(MmGetKernelAddressSpace());
-
+
/* Delete the Stack */
MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
Stack,
MiFreeStackPage,
NULL);
-
+
/* Unlock the Address Space */
MmUnlockAddressSpace(MmGetKernelAddressSpace());
}
VOID
-MiFreePebPage(PVOID Context,
- MEMORY_AREA* MemoryArea,
- PVOID Address,
- PFN_TYPE Page,
- SWAPENTRY SwapEntry,
+MiFreePebPage(PVOID Context,
+ MEMORY_AREA* MemoryArea,
+ PVOID Address,
+ PFN_TYPE Page,
+ SWAPENTRY SwapEntry,
BOOLEAN Dirty)
{
PEPROCESS Process = (PEPROCESS)Context;
STDCALL
MmDeleteTeb(PEPROCESS Process,
PTEB Teb)
-{
+{
PMADDRESS_SPACE ProcessAddressSpace = &Process->AddressSpace;
-
+
/* Lock the Address Space */
MmLockAddressSpace(ProcessAddressSpace);
-
+
/* Delete the Stack */
MmFreeMemoryAreaByPtr(ProcessAddressSpace,
Teb,
MiFreePebPage,
Process);
-
+
/* Unlock the Address Space */
MmUnlockAddressSpace(ProcessAddressSpace);
}
PFN_TYPE Page[MM_STACK_SIZE / PAGE_SIZE];
PVOID KernelStack = NULL;
NTSTATUS Status;
-
+
/* Initialize the Boundary Address */
BoundaryAddressMultiple.QuadPart = 0;
-
+
/* Lock the Kernel Address Space */
MmLockAddressSpace(MmGetKernelAddressSpace());
-
+
/* Create a MAREA for the Kernel Stack */
Status = MmCreateMemoryArea(NULL,
MmGetKernelAddressSpace(),
FALSE,
FALSE,
BoundaryAddressMultiple);
-
+
/* Unlock the Address Space */
MmUnlockAddressSpace(MmGetKernelAddressSpace());
-
+
/* Check for Success */
- if (!NT_SUCCESS(Status))
- {
+ if (!NT_SUCCESS(Status))
+ {
DPRINT1("Failed to create thread stack\n");
KEBUGCHECK(0);
}
-
+
/* Mark the Stack in use */
- for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++)
+ for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++)
{
Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page[i]);
}
-
+
/* Create a Virtual Mapping for it */
Status = MmCreateVirtualMapping(NULL,
KernelStack,
PAGE_READWRITE,
Page,
MM_STACK_SIZE / PAGE_SIZE);
-
+
/* Check for success */
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Could not create Virtual Mapping for Kernel Stack\n");
KEBUGCHECK(0);
}
-
+
return KernelStack;
}
NTSTATUS
STDCALL
MmCreatePeb(PEPROCESS Process)
-{
+{
PPEB Peb = NULL;
LARGE_INTEGER SectionOffset;
ULONG ViewSize = 0;
PVOID TableBase = NULL;
NTSTATUS Status;
SectionOffset.QuadPart = (ULONGLONG)0;
-
+
DPRINT("MmCreatePeb\n");
-
+
/* Map NLS Tables */
DPRINT("Mapping NLS\n");
Status = MmMapViewOfSection(NlsSectionObject,
ViewShare,
MEM_TOP_DOWN,
PAGE_READONLY);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("MmMapViewOfSection() failed (Status %lx)\n", Status);
return(Status);
/* Attach to Process */
KeAttachProcess(&Process->Pcb);
-
+
/* Allocate the PEB */
Peb = MiCreatePebOrTeb(Process, (PVOID)PEB_BASE);
-
+
/* Initialize the PEB */
DPRINT("Allocated: %x\n", Peb);
RtlZeroMemory(Peb, sizeof(PEB));
{
PTEB Teb;
BOOLEAN Attached = FALSE;
-
+
/* Attach to the process */
DPRINT("MmCreateTeb\n");
if (Process != PsGetCurrentProcess())
KeAttachProcess(&Process->Pcb);
Attached = TRUE;
}
-
+
/* Allocate the TEB */
Teb = MiCreatePebOrTeb(Process, (PVOID)TEB_BASE);
-
+
/* Initialize the PEB */
RtlZeroMemory(Teb, sizeof(TEB));
-
+
/* Set TIB Data */
Teb->Tib.ExceptionList = (PVOID)0xFFFFFFFF;
Teb->Tib.Version = 1;
Teb->Tib.Self = (PNT_TIB)Teb;
-
+
/* Set TEB Data */
Teb->Cid = *ClientId;
Teb->RealClientId = *ClientId;
Teb->Peb = Process->Peb;
Teb->CurrentLocale = PsDefaultThreadLocaleId;
-
+
/* Store stack information from InitialTeb */
if(InitialTeb != NULL)
{
Teb->DeallocationStack = InitialTeb->StackReserved;
}
}
-
+
/* Return TEB Address */
DPRINT("Allocated: %x\n", Teb);
if (Attached) KeDetachProcess();
BoundaryAddressMultiple.QuadPart = 0;
ULONG ViewSize = 0;
PVOID ImageBase = 0;
-
+
/* Initialize the Addresss Space */
- MmInitializeAddressSpace(Process, ProcessAddressSpace);
-
+ MmInitializeAddressSpace(Process, ProcessAddressSpace);
+
/* Acquire the Lock */
MmLockAddressSpace(ProcessAddressSpace);
FALSE,
FALSE,
BoundaryAddressMultiple);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to protect last 64KB\n");
goto exit;
}
-
+
/* Protect the 60KB above the shared user page */
BaseAddress = (char*)USER_SHARED_DATA + PAGE_SIZE;
Status = MmCreateMemoryArea(Process,
FALSE,
FALSE,
BoundaryAddressMultiple);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to protect the memory above the shared user page\n");
goto exit;
FALSE,
FALSE,
BoundaryAddressMultiple);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create Shared User Data\n");
goto exit;
}
-
+
/* Check if there's a Section Object */
- if (Section)
+ if (Section)
{
UNICODE_STRING FileName;
PWCHAR szSrc;
PCHAR szDest;
USHORT lnFName = 0;
-
+
/* Unlock the Address Space */
DPRINT("Unlocking\n");
MmUnlockAddressSpace(ProcessAddressSpace);
-
+
DPRINT("Mapping process image. Section: %p, Process: %p, ImageBase: %p\n",
Section, Process, &ImageBase);
Status = MmMapViewOfSection(Section,
0,
MEM_COMMIT,
PAGE_READWRITE);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to map process Image\n");
- ObDereferenceObject(Section);
+ ObDereferenceObject(Section);
goto exit;
}
ObDereferenceObject(Section);
-
+
/* Save the pointer */
Process->SectionBaseAddress = ImageBase;
-
+
/* Determine the image file name and save it to EPROCESS */
DPRINT("Getting Image name\n");
FileName = Section->FileObject->FileName;
szSrc = (PWCHAR)(FileName.Buffer + (FileName.Length / sizeof(WCHAR)) - 1);
- while(szSrc >= FileName.Buffer)
+ while(szSrc >= FileName.Buffer)
{
- if(*szSrc == L'\\')
+ if(*szSrc == L'\\')
{
szSrc++;
break;
- }
- else
+ }
+ else
{
szSrc--;
lnFName++;
szDest = Process->ImageFileName;
lnFName = min(lnFName, sizeof(Process->ImageFileName) - 1);
while(lnFName-- > 0) *(szDest++) = (UCHAR)*(szSrc++);
-
+
/* Return status to caller */
return Status;
}
-
+
exit:
/* Unlock the Address Space */
DPRINT("Unlocking\n");
MmUnlockAddressSpace(ProcessAddressSpace);
-
+
/* Return status to caller */
return Status;
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/region.c
* PURPOSE: No purpose listed.
- *
+ *
* PROGRAMMERS: David Welch
*/
/* $Id$
*
* COPYRIGHT: See COPYING in the top directory
- * PROJECT: ReactOS kernel
+ * PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/rmap.c
* PURPOSE: Kernel memory managment functions
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/*
* Lock the address space; then check that the address we are using
* still corresponds to a valid memory area (the page might have been
- * freed or paged out after we read the rmap entry.)
+ * freed or paged out after we read the rmap entry.)
*/
MmLockAddressSpace(AddressSpace);
MemoryArea = MmLocateMemoryAreaByAddress(AddressSpace, Address);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/section.c
* PURPOSE: Implements section objects
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
{
/*
* FIXME:
- * We hold all locks. Nobody can do something with the current
+ * We hold all locks. Nobody can do something with the current
* process and the current segment (also not within an other process).
*/
NTSTATUS Status;
if (PAGE_FROM_SSE(Entry) == 0 || HasSwapEntry)
{
/*
- * The page was a private page in another or in our address space
+ * The page was a private page in another or in our address space
*/
MmUnlockSectionSegment(Segment);
MmspCompleteAndReleasePageOp(PageOp);
BufferSize,
&FileOffset,
NULL);
-
+
if(NT_SUCCESS(Status))
{
UsedSize = Iosb.Information;
* TODO: relax the limitation on gaps. For example, gaps smaller than a
* page could be OK (Windows seems to be OK with them), and larger gaps
* could lead to image sections spanning several discontiguous regions
- * (NtMapViewOfSection could then refuse to map them, and they could
+ * (NtMapViewOfSection could then refuse to map them, and they could
* e.g. only be allowed as parameters to NtCreateProcess, like on UNIX)
*/
if ((ImageSectionObject->Segments[i - 1].VirtualAddress +
ULONG_PTR VirtualOffset;
VirtualAddress = EffectiveSegment->VirtualAddress;
-
+
/* Round down the virtual address to the nearest page */
EffectiveSegment->VirtualAddress = PAGE_ROUND_DOWN(VirtualAddress);
-
+
/* Round up the virtual size to the nearest page */
EffectiveSegment->Length = PAGE_ROUND_UP(VirtualAddress + EffectiveSegment->Length) -
EffectiveSegment->VirtualAddress;
-
+
/* Adjust the raw address and size */
VirtualOffset = VirtualAddress - EffectiveSegment->VirtualAddress;
-
+
if (EffectiveSegment->FileOffset < VirtualOffset)
{
return FALSE;
}
-
+
/*
- * Garbage in, garbage out: unaligned base addresses make the file
- * offset point in curious and odd places, but that's what we were
+ * Garbage in, garbage out: unaligned base addresses make the file
+ * offset point in curious and odd places, but that's what we were
* asked for
*/
EffectiveSegment->FileOffset -= VirtualOffset;
EndOfEffectiveSegment = EffectiveSegment->VirtualAddress + EffectiveSegment->Length;
ASSERT((EndOfEffectiveSegment % PAGE_SIZE) == 0);
-
+
/*
* The current segment begins exactly where the current effective
* segment ended, therefore beginning a new effective segment
/*
* Extend the file size
*/
-
+
/* Unaligned segments must be contiguous within the file */
if (Segment->FileOffset != (EffectiveSegment->FileOffset +
EffectiveSegment->RawLength))
{
return FALSE;
}
-
+
EffectiveSegment->RawLength += Segment->RawLength;
-
+
/*
* Extend the virtual size
*/
ASSERT(PAGE_ROUND_UP(Segment->VirtualAddress + Segment->Length) > EndOfEffectiveSegment);
-
+
EffectiveSegment->Length = PAGE_ROUND_UP(Segment->VirtualAddress + Segment->Length) -
EffectiveSegment->VirtualAddress;
-
+
/*
* Merge the protection
*/
/* FIXME? are these values platform-dependent? */
if(ImageSectionObject->StackReserve == 0)
ImageSectionObject->StackReserve = 0x40000;
-
+
if(ImageSectionObject->StackCommit == 0)
ImageSectionObject->StackCommit = 0x1000;
-
+
if(ImageSectionObject->ImageBase == 0)
{
if(ImageSectionObject->ImageCharacteristics & IMAGE_FILE_DLL)
NTSTATUS Status = STATUS_SUCCESS;
PreviousMode = ExGetPreviousMode();
-
+
if(MaximumSize != NULL && PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
}
}
-
+
/*
* Check the protection
*/
HANDLE hSection;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
KPROCESSOR_MODE PreviousMode;
PMADDRESS_SPACE AddressSpace;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
SafeBaseAddress = NULL;
SafeSectionOffset.QuadPart = 0;
SafeViewSize = 0;
-
+
_SEH_TRY
{
if(BaseAddress != NULL)
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
ObDereferenceObject(Section);
ObDereferenceObject(Process);
-
+
if(NT_SUCCESS(Status))
{
/* copy parameters back to the caller */
/**
* Queries the information of a section object.
- *
+ *
* @param SectionHandle
* Handle to the section object. It must be opened with SECTION_QUERY
* access.
PSECTION_OBJECT Section;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PreviousMode = ExGetPreviousMode();
-
+
DefaultQueryInfoBufferCheck(SectionInformationClass,
ExSectionInfoClass,
SectionInformation,
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
break;
}
Sii->ImageNumber = ImageSectionObject->Machine;
Sii->Executable = ImageSectionObject->Executable;
}
-
+
if (ResultLength != NULL)
{
*ResultLength = sizeof(SECTION_IMAGE_INFORMATION);
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
break;
}
}
ObDereferenceObject(Section);
}
-
+
return(Status);
}
/**
* Extends size of file backed section.
- *
+ *
* @param SectionHandle
* Handle to the section object. It must be opened with
* SECTION_EXTEND_SIZE access.
PSECTION_OBJECT Section;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
ObfDereferenceObject(Section);
return STATUS_INVALID_PARAMETER;
}
-
+
/*
* - Acquire file extneding resource.
* - Check if we're not resizing the section below it's actual size!
-/* $Id:$
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/verifier.c
* PURPOSE: Driver Verifier functions
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/virtual.c
* PURPOSE: Implementing operations on virtual memory.
- *
+ *
* PROGRAMMERS: David Welch
*/
Info->AllocationProtect = MemoryArea->Attributes;
Info->BaseAddress = MemoryArea->StartingAddress;
Info->AllocationBase = MemoryArea->StartingAddress;
- Info->RegionSize = (ULONG_PTR)MemoryArea->EndingAddress -
+ Info->RegionSize = (ULONG_PTR)MemoryArea->EndingAddress -
(ULONG_PTR)MemoryArea->StartingAddress;
Status = STATUS_SUCCESS;
*ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
Info->AllocationProtect = MemoryArea->Attributes;
Info->BaseAddress = MemoryArea->StartingAddress;
Info->AllocationBase = MemoryArea->StartingAddress;
- Info->RegionSize = (ULONG_PTR)MemoryArea->EndingAddress -
+ Info->RegionSize = (ULONG_PTR)MemoryArea->EndingAddress -
(ULONG_PTR)MemoryArea->StartingAddress;
Status = STATUS_SUCCESS;
*ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
Info->AllocationProtect = MemoryArea->Attributes;
Info->BaseAddress = MemoryArea->StartingAddress;
Info->AllocationBase = MemoryArea->StartingAddress;
- Info->RegionSize = (ULONG_PTR)MemoryArea->EndingAddress -
+ Info->RegionSize = (ULONG_PTR)MemoryArea->EndingAddress -
(ULONG_PTR)MemoryArea->StartingAddress;
Status = STATUS_SUCCESS;
*ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
Info->AllocationProtect = MemoryArea->Attributes;
Info->BaseAddress = MemoryArea->StartingAddress;
Info->AllocationBase = MemoryArea->StartingAddress;
- Info->RegionSize = (ULONG_PTR)MemoryArea->EndingAddress -
+ Info->RegionSize = (ULONG_PTR)MemoryArea->EndingAddress -
(ULONG_PTR)MemoryArea->StartingAddress;
Status = STATUS_SUCCESS;
*ResultLength = sizeof(MEMORY_BASIC_INFORMATION);
KPROCESSOR_MODE PreviousMode;
PEPROCESS Process, CurrentProcess;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(NT_SUCCESS(Status))
{
KeAttachProcess(&Process->Pcb);
}
_SEH_END;
}
-
+
return(Status);
}
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/mm/wset.c
* PURPOSE: Manages working sets
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ob/dirobj.c
* PURPOSE: Interface functions to directory object
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
*
* DESCRIPTION
* Opens a namespace directory object.
- *
+ *
* ARGUMENTS
* DirectoryHandle (OUT)
* Variable which receives the directory handle.
- *
+ *
* DesiredAccess
* Desired access to the directory.
- *
+ *
* ObjectAttributes
* Structure describing the directory.
- *
+ *
* RETURN VALUE
* Status.
- *
+ *
* NOTES
* Undocumented.
*/
HANDLE hDirectory;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
DPRINT1("NtOpenDirectoryObject failed, Status: 0x%x\n", Status);
return Status;
}
}
-
+
Status = ObOpenObjectByName(ObjectAttributes,
ObDirectoryType,
NULL,
}
_SEH_END;
}
-
+
return Status;
}
/**********************************************************************
* NAME EXPORTED
* NtQueryDirectoryObject
- *
+ *
* DESCRIPTION
* Reads information from a directory in the system namespace.
- *
+ *
* ARGUMENTS
* DirectoryHandle
* Handle, obtained with NtOpenDirectoryObject(), which
* must grant DIRECTORY_QUERY access to the directory
* object.
- *
+ *
* Buffer (OUT)
* Buffer to hold the data read.
- *
+ *
* BufferLength
* Size of the buffer in bytes.
- *
+ *
* ReturnSingleEntry
* When TRUE, only 1 entry is written in DirObjInformation;
* otherwise as many as will fit in the buffer.
- *
+ *
* RestartScan
* If TRUE start reading at index 0.
* If FALSE start reading at the index specified
* by object index *ObjectIndex.
- *
+ *
* Context
* Zero based index into the directory, interpretation
* depends on RestartScan.
- *
+ *
* ReturnLength (OUT)
* Caller supplied storage for the number of bytes
* written (or NULL).
ULONG NextEntry = 0;
ULONG CopyBytes = 0;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
{
SkipEntries = *Context;
}
-
+
Status = ObReferenceObjectByHandle(DirectoryHandle,
DIRECTORY_QUERY,
ObDirectoryType,
ULONG RequiredSize = 0;
ULONG nDirectories = 0;
POBJECT_DIRECTORY_INFORMATION DirInfo = (POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer;
-
+
Status = STATUS_NO_MORE_ENTRIES;
KeAcquireSpinLock(&Directory->Lock, &OldLevel);
nDirectories++;
RequiredSize += EntrySize;
-
+
Status = STATUS_SUCCESS;
if(ReturnSingleEntry)
RequiredSize += EntrySize;
Status = STATUS_BUFFER_TOO_SMALL;
}
-
+
/* we couldn't query this entry, so leave the index that will be stored
in Context to this entry so the caller can query it the next time
he queries (hopefully with a buffer that is large enough then...) */
NextEntry--;
-
+
/* just copy the entries that fit into the buffer */
break;
}
SkipEntries--;
}
}
-
+
if(!ReturnSingleEntry && ListEntry != &Directory->head)
{
/* there are more entries to enumerate but the buffer is already full.
{
PWSTR strbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)TemporaryBuffer + nDirectories);
PWSTR deststrbuf = (PWSTR)((POBJECT_DIRECTORY_INFORMATION)Buffer + nDirectories);
-
+
CopyBytes = nDirectories * sizeof(OBJECT_DIRECTORY_INFORMATION);
-
+
/* copy the names from the objects and append them to the list of the
objects. copy to the temporary buffer only because the directory
lock can't be released and the buffer might be pagable memory! */
nDirectories--, DirInfo++)
{
ULONG NameLength;
-
+
if(DirInfo->ObjectName.Length > 0)
{
RtlCopyMemory(strbuf,
CopyBytes += (NameLength + 1) * sizeof(WCHAR);
}
-
+
RtlCopyMemory(strbuf,
DirInfo->ObjectTypeName.Buffer,
DirInfo->ObjectTypeName.Length);
strbuf[NameLength] = L'\0';
strbuf += NameLength + 1;
deststrbuf += NameLength + 1;
-
+
CopyBytes += (NameLength + 1) * sizeof(WCHAR);
}
}
}
_SEH_END;
}
-
+
ExFreePool(TemporaryBuffer);
}
else
Status = STATUS_INSUFFICIENT_RESOURCES;
}
}
-
+
return Status;
}
/**********************************************************************
* NAME (EXPORTED as Zw)
* NtCreateDirectoryObject
- *
+ *
* DESCRIPTION
* Creates or opens a directory object (a container for other
* objects).
- *
+ *
* ARGUMENTS
* DirectoryHandle (OUT)
- * Caller supplied storage for the handle of the
+ * Caller supplied storage for the handle of the
* directory.
- *
+ *
* DesiredAccess
* Access desired to the directory.
- *
+ *
* ObjectAttributes
* Object attributes initialized with
* InitializeObjectAttributes.
- *
+ *
* RETURN VALUE
* Status.
*/
HANDLE hDirectory;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
DPRINT("NtCreateDirectoryObject(DirectoryHandle %x, "
"DesiredAccess %x, ObjectAttributes %x\n",
DirectoryHandle, DesiredAccess, ObjectAttributes);
if it's not a permanent object. */
ObpRemoveEntryDirectory(ObjectHeader);
}
-
+
/* remove the keep-alive reference */
ObDereferenceObject(ObjectBody);
}
PHANDLE_TABLE HandleTable;
PHANDLE_TABLE_ENTRY HandleTableEntry;
LONG ExHandle;
-
+
PAGED_CODE();
DPRINT("ObpQueryHandleAttributes(Handle %x)\n", Handle);
-
+
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
{
HandleTable = ObpKernelHandleTable;
PHANDLE_TABLE HandleTable;
PHANDLE_TABLE_ENTRY HandleTableEntry;
LONG ExHandle;
-
+
PAGED_CODE();
DPRINT("ObpSetHandleAttributes(Handle %x)\n", Handle);
HandleTable = PsGetCurrentProcess()->ObjectTable;
ExHandle = HANDLE_TO_EX_HANDLE(Handle);
}
-
+
KeEnterCriticalRegion();
HandleTableEntry = ExMapHandleToPointer(HandleTable,
LONG ExTargetHandle;
LONG ExSourceHandle;
ULONG NewHandleCount;
-
+
PAGED_CODE();
-
+
if(ObIsKernelHandle(SourceHandle, ExGetPreviousMode()))
{
SourceHandleTable = ObpKernelHandleTable;
{
SourceHandleTable = SourceProcess->ObjectTable;
}
-
+
ExSourceHandle = HANDLE_TO_EX_HANDLE(SourceHandle);
-
+
KeEnterCriticalRegion();
-
+
SourceHandleEntry = ExMapHandleToPointer(SourceHandleTable,
ExSourceHandle);
if (SourceHandleEntry == NULL)
}
NewHandleEntry.u2.GrantedAccess = DesiredAccess;
}
-
+
/* reference the object so it doesn't get deleted after releasing the lock
and before creating a new handle for it */
ObReferenceObject(ObjectBody);
-
+
/* increment the handle count of the object, it should always be >= 2 because
we're holding a handle lock to this object! if the new handle count was
1 here, we're in big trouble... it would've been safe to increment and
entry is locked, which means the handle count can't change. */
NewHandleCount = InterlockedIncrement(&ObjectHeader->HandleCount);
ASSERT(NewHandleCount >= 2);
-
+
ExUnlockHandleTableEntry(SourceHandleTable,
SourceHandleEntry);
ObpDeleteHandle(SourceHandleTable,
SourceHandle);
}
-
+
ObDereferenceObject(ObjectBody);
*TargetHandle = EX_HANDLE_TO_HANDLE(ExTargetHandle);
-
+
return STATUS_SUCCESS;
}
else
{
ObDereferenceObject(ObjectBody);
}
-
+
ObDereferenceObject(ObjectBody);
return STATUS_UNSUCCESSFUL;
}
/*
* @implemented
*/
-NTSTATUS STDCALL
+NTSTATUS STDCALL
NtDuplicateObject (IN HANDLE SourceProcessHandle,
IN HANDLE SourceHandle,
IN HANDLE TargetProcessHandle,
/*
* FUNCTION: Copies a handle from one process space to another
* ARGUMENTS:
- * SourceProcessHandle = The source process owning the handle. The
+ * SourceProcessHandle = The source process owning the handle. The
* source process should have opened
- * the SourceHandle with PROCESS_DUP_HANDLE
+ * the SourceHandle with PROCESS_DUP_HANDLE
* access.
* SourceHandle = The handle to the object.
- * TargetProcessHandle = The destination process owning the handle
- * TargetHandle (OUT) = Caller should supply storage for the
- * duplicated handle.
+ * TargetProcessHandle = The destination process owning the handle
+ * TargetHandle (OUT) = Caller should supply storage for the
+ * duplicated handle.
* DesiredAccess = The desired access to the handle.
* InheritHandle = Indicates wheter the new handle will be inheritable
* or not.
- * Options = Specifies special actions upon duplicating the handle.
- * Can be one of the values DUPLICATE_CLOSE_SOURCE |
- * DUPLICATE_SAME_ACCESS. DUPLICATE_CLOSE_SOURCE specifies
- * that the source handle should be closed after duplicating.
- * DUPLICATE_SAME_ACCESS specifies to ignore the
- * DesiredAccess paramter and just grant the same access to
+ * Options = Specifies special actions upon duplicating the handle.
+ * Can be one of the values DUPLICATE_CLOSE_SOURCE |
+ * DUPLICATE_SAME_ACCESS. DUPLICATE_CLOSE_SOURCE specifies
+ * that the source handle should be closed after duplicating.
+ * DUPLICATE_SAME_ACCESS specifies to ignore the
+ * DesiredAccess paramter and just grant the same access to
* the new handle.
* RETURNS: Status
* REMARKS: This function maps to the win32 DuplicateHandle.
HANDLE hTarget;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(TargetHandle != NULL && PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
}
}
-
+
Status = ObReferenceObjectByHandle(SourceProcessHandle,
PROCESS_DUP_HANDLE,
NULL,
{
PVOID ObjectBody;
POBJECT_TYPE ObjectType;
-
+
ObjectType = (SourceHandle == NtCurrentThread()) ? PsThreadType : PsProcessType;
Status = ObReferenceObjectByHandle(SourceHandle,
{
POBJECT_HEADER ObjectHeader;
PVOID ObjectBody;
-
+
PAGED_CODE();
ObjectHeader = EX_OBJ_TO_HDR(Object);
ObjectBody = HEADER_TO_BODY(ObjectHeader);
-
+
ObpDecrementHandleCount(ObjectBody);
}
{
POBJECT_HEADER ObjectHeader;
BOOLEAN Ret = FALSE;
-
+
PAGED_CODE();
-
+
Ret = (HandleTableEntry->u1.ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0;
if(Ret)
{
ObReferenceObject(HEADER_TO_BODY(ObjectHeader));
}
}
-
+
return Ret;
}
*/
{
PAGED_CODE();
-
+
DPRINT("ObCreateHandleTable(Parent %x, Inherit %d, Process %x)\n",
Parent,Inherit,Process);
if(Parent != NULL)
HANDLE_TABLE_ENTRY NewEntry;
POBJECT_HEADER ObjectHeader;
LONG ExHandle;
-
+
PAGED_CODE();
DPRINT("ObCreateHandle(Process %x, obj %x)\n",Process,ObjectBody);
ObjectHeader = BODY_TO_HEADER(ObjectBody);
ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED);
-
+
if (GrantedAccess & MAXIMUM_ALLOWED)
{
GrantedAccess &= ~MAXIMUM_ALLOWED;
else
NewEntry.u1.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE;
NewEntry.u2.GrantedAccess = GrantedAccess;
-
+
ExHandle = ExCreateHandle(Process->ObjectTable,
&NewEntry);
DPRINT("ObCreateHandle(0x%x)==0x%x [HT:0x%x]\n", ObjectHeader, *HandleReturn, Process->ObjectTable);
NULL,
UserMode);
}
-
+
*HandleReturn = EX_HANDLE_TO_HANDLE(ExHandle);
return STATUS_SUCCESS;
PHANDLE_TABLE_ENTRY HandleEntry;
PEPROCESS Process;
LONG ExHandle = HANDLE_TO_EX_HANDLE(Handle);
-
+
PAGED_CODE();
DPRINT("ObQueryObjectAuditingByHandle(Handle %x)\n", Handle);
Process = PsGetCurrentProcess();
-
+
KeEnterCriticalRegion();
HandleEntry = ExMapHandleToPointer(Process->ObjectTable,
if(HandleEntry != NULL)
{
*GenerateOnClose = (HandleEntry->u1.ObAttributes & EX_HANDLE_ENTRY_AUDITONCLOSE) != 0;
-
+
ExUnlockHandleTableEntry(Process->ObjectTable,
HandleEntry);
KeLeaveCriticalRegion();
-
+
return STATUS_SUCCESS;
}
-
+
KeLeaveCriticalRegion();
-
+
return STATUS_INVALID_HANDLE;
}
/*
- * FUNCTION: Increments the reference count for an object and returns a
+ * FUNCTION: Increments the reference count for an object and returns a
* pointer to its body
* ARGUMENTS:
* Handle = Handle for the object
* DesiredAccess = Desired access to the object
* ObjectType
- * AccessMode
+ * AccessMode
* Object (OUT) = Points to the object body on return
- * HandleInformation (OUT) = Contains information about the handle
+ * HandleInformation (OUT) = Contains information about the handle
* on return
* RETURNS: Status
*
ACCESS_MASK GrantedAccess;
ULONG Attributes;
LONG ExHandle;
-
+
PAGED_CODE();
-
+
DPRINT("ObReferenceObjectByHandle(Handle %x, DesiredAccess %x, "
"ObjectType %x, AccessMode %d, Object %x)\n",Handle,DesiredAccess,
ObjectType,AccessMode,Object);
/*
* Handle special handle names
*/
- if (Handle == NtCurrentProcess() &&
+ if (Handle == NtCurrentProcess() &&
(ObjectType == PsProcessType || ObjectType == NULL))
{
PEPROCESS CurrentProcess = PsGetCurrentProcess();
-
+
ObReferenceObject(CurrentProcess);
if (HandleInformation != NULL)
return(STATUS_OBJECT_TYPE_MISMATCH);
}
- if (Handle == NtCurrentThread() &&
+ if (Handle == NtCurrentThread() &&
(ObjectType == PsThreadType || ObjectType == NULL))
{
PETHREAD CurrentThread = PsGetCurrentThread();
-
+
ObReferenceObject(CurrentThread);
if (HandleInformation != NULL)
CHECKPOINT;
return(STATUS_OBJECT_TYPE_MISMATCH);
}
-
+
/* desire as much access rights as possible */
if (DesiredAccess & MAXIMUM_ALLOWED)
{
DesiredAccess &= ~MAXIMUM_ALLOWED;
DesiredAccess |= GENERIC_ALL;
}
-
+
if(ObIsKernelHandle(Handle, AccessMode))
{
HandleTable = ObpKernelHandleTable;
}
KeEnterCriticalRegion();
-
+
HandleEntry = ExMapHandleToPointer(HandleTable,
ExHandle);
if (HandleEntry == NULL)
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
ObjectBody = HEADER_TO_BODY(ObjectHeader);
-
+
DPRINT("locked1: ObjectHeader: 0x%x [HT:0x%x]\n", ObjectHeader, HandleTable);
-
+
if (ObjectType != NULL && ObjectType != ObjectHeader->ObjectType)
{
DPRINT("ObjectType mismatch: %wZ vs %wZ (handle 0x%x)\n", &ObjectType->TypeName, ObjectHeader->ObjectType ? &ObjectHeader->ObjectType->TypeName : NULL, Handle);
RtlMapGenericMask(&DesiredAccess,
BODY_TO_HEADER(ObjectBody)->ObjectType->Mapping);
}
-
+
GrantedAccess = HandleEntry->u2.GrantedAccess;
-
+
/* Unless running as KernelMode, deny access if caller desires more access
rights than the handle can grant */
if(AccessMode != KernelMode && (~GrantedAccess & DesiredAccess))
HandleEntry);
KeLeaveCriticalRegion();
-
+
DPRINT1("GrantedAccess: 0x%x, ~GrantedAccess: 0x%x, DesiredAccess: 0x%x, denied: 0x%x\n", GrantedAccess, ~GrantedAccess, DesiredAccess, ~GrantedAccess & DesiredAccess);
return(STATUS_ACCESS_DENIED);
}
ObReferenceObject(ObjectBody);
-
+
Attributes = HandleEntry->u1.ObAttributes & (EX_HANDLE_ENTRY_PROTECTFROMCLOSE |
EX_HANDLE_ENTRY_INHERITABLE |
EX_HANDLE_ENTRY_AUDITONCLOSE);
ExUnlockHandleTableEntry(HandleTable,
HandleEntry);
-
+
KeLeaveCriticalRegion();
if (HandleInformation != NULL)
}
*Object = ObjectBody;
-
+
return(STATUS_SUCCESS);
}
/**********************************************************************
* NAME EXPORTED
* NtClose
- *
+ *
* DESCRIPTION
* Closes a handle reference to an object.
- *
+ *
* ARGUMENTS
* Handle
* Handle to close.
- *
+ *
* RETURN VALUE
* Status.
*
{
PHANDLE_TABLE HandleTable;
NTSTATUS Status;
-
+
PAGED_CODE();
-
+
if(ObIsKernelHandle(Handle, ExGetPreviousMode()))
{
HandleTable = ObpKernelHandleTable;
{
HandleTable = PsGetCurrentProcess()->ObjectTable;
}
-
+
Status = ObpDeleteHandle(HandleTable,
Handle);
if (!NT_SUCCESS(Status))
}
return Status;
}
-
+
return(STATUS_SUCCESS);
}
{
POBJECT_HEADER ObjectHeader;
ACCESS_MASK Access;
-
+
PAGED_CODE();
Access = DesiredAccess;
// pshi->HandleValue;
-/*
+/*
This will never work with ROS! M$, I guess uses 0 -> 65535.
Ros uses 0 -> 4294967295!
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ob/namespc.c
* PURPOSE: Manages the system namespace
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
UNICODE_STRING RemainingPath;
OBJECT_ATTRIBUTES ObjectAttributes;
NTSTATUS Status;
-
+
PAGED_CODE();
InitializeObjectAttributes(&ObjectAttributes,
/**********************************************************************
* NAME EXPORTED
* ObOpenObjectByName
- *
+ *
* DESCRIPTION
* Obtain a handle to an existing object.
- *
+ *
* ARGUMENTS
* ObjectAttributes
* ...
UNICODE_STRING RemainingPath;
PVOID Object = NULL;
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("ObOpenObjectByName(...)\n");
PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo)
{
//KIRQL OldIrql ;
-
+
/*
* FIXME: This is an ugly hack for now, to always return the System Device Map
* instead of returning the Process Device Map. Not important yet since we don't use it
*/
-
+
/* FIXME: Acquire the DeviceMap Spinlock */
// KeAcquireSpinLock(DeviceMap->Lock, &OldIrql);
-
+
/* Make a copy */
DeviceMapInfo->Query.DriveMap = ObSystemDeviceMap->DriveMap;
RtlMoveMemory(DeviceMapInfo->Query.DriveType, ObSystemDeviceMap->DriveType, sizeof(ObSystemDeviceMap->DriveType));
-
+
/* FIXME: Release the DeviceMap Spinlock */
// KeReleasepinLock(DeviceMap->Lock, OldIrql);
-}
-
+}
+
VOID
ObpAddEntryDirectory(PDIRECTORY_OBJECT Parent,
POBJECT_HEADER Header,
POBJECT_HEADER current_obj;
DPRINT("ObFindEntryDirectory(dir %x, name %S)\n",DirectoryObject, Name);
-
+
if (Name[0]==0)
{
return(DirectoryObject);
/* create 'directory' object type */
ObDirectoryType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
+
ObDirectoryType->Tag = TAG('D', 'I', 'R', 'T');
ObDirectoryType->TotalObjects = 0;
ObDirectoryType->TotalHandles = 0;
/* create 'type' object type*/
ObTypeObjectType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
+
ObTypeObjectType->Tag = TAG('T', 'y', 'p', 'T');
ObTypeObjectType->TotalObjects = 0;
ObTypeObjectType->TotalHandles = 0;
/* Create 'symbolic link' object type */
ObInitSymbolicLinkImplementation();
-
+
/* FIXME: Hack Hack! */
ObSystemDeviceMap = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ObSystemDeviceMap), TAG('O', 'b', 'D', 'm'));
RtlZeroMemory(ObSystemDeviceMap, sizeof(*ObSystemDeviceMap));
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ob/ntobj.c
* PURPOSE: User mode interface to object manager
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/**********************************************************************
* NAME EXPORTED
* NtSetInformationObject
- *
+ *
* DESCRIPTION
*
* ARGUMENTS
{
PVOID Object;
NTSTATUS Status;
-
+
PAGED_CODE();
if (ObjectInformationClass != ObjectHandleInformation)
ULONG InfoLength;
PVOID Object;
NTSTATUS Status;
-
+
PAGED_CODE();
Status = ObReferenceObjectByHandle (ObjectHandle,
ObjectHeader = BODY_TO_HEADER(ObjectBody);
ObjectHeader->Permanent = Permanent;
-
+
if (ObjectHeader->HandleCount == 0 && !Permanent && ObjectHeader->Parent != NULL)
{
/* Remove the object from the namespace */
{
PVOID ObjectBody;
NTSTATUS Status;
-
+
PAGED_CODE();
Status = ObReferenceObjectByHandle(ObjectHandle,
{
PVOID ObjectBody;
NTSTATUS Status;
-
+
PAGED_CODE();
Status = ObReferenceObjectByHandle(ObjectHandle,
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ob/object.c
* PURPOSE: Implements generic object managment functions
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
* Skywing (skywing@valhallalegends.com)
*/
if(AccessMode != KernelMode)
{
RtlZeroMemory(&AttributesCopy, sizeof(AttributesCopy));
-
+
_SEH_TRY
{
ProbeForRead(ObjectAttributes,
if(AttributesCopy.SecurityQualityOfService != NULL)
{
SECURITY_QUALITY_OF_SERVICE SafeQoS;
-
+
RtlZeroMemory(&SafeQoS, sizeof(SafeQoS));
_SEH_TRY
if(AccessMode != KernelMode)
{
RtlZeroMemory(&OriginalCopy, sizeof(OriginalCopy));
-
+
_SEH_TRY
{
/* probe the ObjectName structure and make a local stack copy of it */
UNICODE_STRING PathString;
ULONG Attributes;
PUNICODE_STRING ObjectName;
-
+
PAGED_CODE();
DPRINT("ObFindObject(ObjectAttributes %x, ReturnedObject %x, "
/* reparse the object path */
NextObject = NameSpaceRoot;
current = PathString.Buffer;
-
+
ObReferenceObjectByPointer(NextObject,
DIRECTORY_TRAVERSE,
NULL,
POBJECT_HEADER ObjectHeader;
ULONG LocalReturnLength;
NTSTATUS Status;
-
+
PAGED_CODE();
*ReturnLength = 0;
SECURITY_SUBJECT_CONTEXT SubjectContext;
PAGED_CODE();
-
+
if(ObjectAttributesAccessMode == UserMode && ObjectAttributes != NULL)
{
Status = STATUS_SUCCESS;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
IN KPROCESSOR_MODE AccessMode)
{
POBJECT_HEADER Header;
-
+
/* NOTE: should be possible to reference an object above APC_LEVEL! */
DPRINT("ObReferenceObjectByPointer(Object %x, ObjectType %x)\n",
Object,ObjectType);
-
+
Header = BODY_TO_HEADER(Object);
-
+
if (ObjectType != NULL && Header->ObjectType != ObjectType)
{
DPRINT("Failed %x (type was %x %S) should be %x %S\n",
Object, Header->RefCount, PsThreadType);
DPRINT("eip %x\n", ((PULONG)&Object)[-1]);
}
-
+
if (Header->RefCount == 0 && !Header->Permanent)
{
if (Header->ObjectType == PsProcessType)
{
KEBUGCHECK(0);
}
-
+
return(STATUS_SUCCESS);
}
OUT PHANDLE Handle)
{
NTSTATUS Status;
-
+
PAGED_CODE();
-
+
DPRINT("ObOpenObjectByPointer()\n");
-
+
Status = ObReferenceObjectByPointer(Object,
0,
ObjectType,
{
return Status;
}
-
+
Status = ObCreateHandle(PsGetCurrentProcess(),
Object,
DesiredAccess,
(BOOLEAN)(HandleAttributes & OBJ_INHERIT),
Handle);
-
+
ObDereferenceObject(Object);
-
+
return STATUS_SUCCESS;
}
if (ObjectHeader->RefCount < 0)
{
CPRINT("Object %p/%p has invalid reference count (%d)\n",
- ObjectHeader, HEADER_TO_BODY(ObjectHeader),
+ ObjectHeader, HEADER_TO_BODY(ObjectHeader),
ObjectHeader->RefCount);
KEBUGCHECK(0);
}
if (ObjectHeader->HandleCount < 0)
{
CPRINT("Object %p/%p has invalid handle count (%d)\n",
- ObjectHeader, HEADER_TO_BODY(ObjectHeader),
+ ObjectHeader, HEADER_TO_BODY(ObjectHeader),
ObjectHeader->HandleCount);
KEBUGCHECK(0);
}
#endif
-
+
switch (KeGetCurrentIrql ())
{
case PASSIVE_LEVEL:
return ObpDeleteObject (ObjectHeader);
-
+
case APC_LEVEL:
case DISPATCH_LEVEL:
{
PRETENTION_CHECK_PARAMS Params;
-
+
/*
We use must succeed pool here because if the allocation fails
then we leak memory.
CriticalWorkQueue);
}
return STATUS_PENDING;
-
+
default:
DPRINT("ObpDeleteObjectDpcLevel called at unsupported "
"IRQL %u!\n", KeGetCurrentIrql());
Header = BODY_TO_HEADER(Object);
Permanent = Header->Permanent;
- /*
+ /*
Drop our reference and get the new count so we can tell if this was the
last reference.
*/
VOID
FASTCALL
-ObInitializeFastReference(IN PEX_FAST_REF FastRef,
+ObInitializeFastReference(IN PEX_FAST_REF FastRef,
PVOID Object)
{
/* FIXME: Fast Referencing is Unimplemented */
ObFastReferenceObject(IN PEX_FAST_REF FastRef)
{
/* FIXME: Fast Referencing is Unimplemented */
-
+
/* Do a normal Reference */
ObReferenceObject(FastRef->Object);
-
+
/* Return the Object */
return FastRef->Object;
}
PVOID Object)
{
/* FIXME: Fast Referencing is Unimplemented */
-
+
/* Do a normal Dereference */
ObDereferenceObject(FastRef->Object);
}
PVOID Object)
{
PVOID OldObject = FastRef->Object;
-
+
/* FIXME: Fast Referencing is Unimplemented */
FastRef->Object = Object;
-
+
/* Do a normal Dereference */
ObDereferenceObject(OldObject);
ObGetObjectPointerCount(PVOID Object)
{
POBJECT_HEADER Header;
-
+
PAGED_CODE();
ASSERT(Object);
ObGetObjectHandleCount(PVOID Object)
{
POBJECT_HEADER Header;
-
+
PAGED_CODE();
ASSERT(Object);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ob/sdcache.c
* PURPOSE: No purpose listed.
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ob/security.c
* PURPOSE: Security manager
- *
+ *
* PROGRAMERS: No programmer listed.
*/
{
PSECURITY_DESCRIPTOR NewDescriptor;
NTSTATUS Status;
-
+
PAGED_CODE();
/* Build the new security descriptor */
POBJECT_HEADER Header;
ULONG Length;
NTSTATUS Status;
-
+
PAGED_CODE();
Header = BODY_TO_HEADER(Object);
IN BOOLEAN MemoryAllocated)
{
PAGED_CODE();
-
+
if (SecurityDescriptor == NULL)
return;
POBJECT_HEADER Header;
PVOID Object;
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("NtQuerySecurityObject() called\n");
ULONG Control = 0;
ULONG_PTR Current;
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("NtSetSecurityObject() called\n");
if (SecurityDescriptor->Owner != NULL)
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
- Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
+ Owner = (PSID)((ULONG_PTR)SecurityDescriptor->Owner +
(ULONG_PTR)SecurityDescriptor);
else
Owner = (PSID)SecurityDescriptor->Owner;
if (SecurityDescriptor->Group != NULL)
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
- Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
+ Group = (PSID)((ULONG_PTR)SecurityDescriptor->Group +
(ULONG_PTR)SecurityDescriptor);
else
Group = (PSID)SecurityDescriptor->Group;
(SecurityDescriptor->Dacl != NULL))
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
- Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl +
+ Dacl = (PACL)((ULONG_PTR)SecurityDescriptor->Dacl +
(ULONG_PTR)SecurityDescriptor);
else
Dacl = (PACL)SecurityDescriptor->Dacl;
(SecurityDescriptor->Sacl != NULL))
{
if( SecurityDescriptor->Control & SE_SELF_RELATIVE )
- Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl +
+ Sacl = (PACL)((ULONG_PTR)SecurityDescriptor->Sacl +
(ULONG_PTR)SecurityDescriptor);
else
Sacl = (PACL)SecurityDescriptor->Sacl;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ob/symlink.c
* PURPOSE: Implements symbolic links
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
if(PreviousMode != KernelMode)
return Status;
}
}
-
+
Status = RtlCaptureUnicodeString(&CapturedLinkTarget,
PreviousMode,
PagedPool,
}
ObDereferenceObject(SymbolicLink);
}
-
+
RtlReleaseCapturedUnicodeString(&CapturedLinkTarget,
PreviousMode,
FALSE);
NTSTATUS Status = STATUS_SUCCESS;
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
}
_SEH_END;
}
-
+
return Status;
}
PSYMLINK_OBJECT SymlinkObject;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
if (NT_SUCCESS(Status))
{
ULONG LengthRequired = SymlinkObject->TargetName.Length + sizeof(WCHAR);
-
+
_SEH_TRY
{
if(SafeLinkTarget.MaximumLength >= LengthRequired)
{
Status = STATUS_BUFFER_TOO_SMALL;
}
-
+
if(ResultLength != NULL)
{
*ResultLength = LengthRequired;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ob/wait.c
* PURPOSE: Handles Waiting on Objects
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net) - Created file
* David Welch (welch@mcmail.com)
*/
what objects we referenced in case dereferencing pointers suddenly fails */
RtlCopyMemory(SafeObjectsArray, ObjectsArray, ObjectCount * sizeof(ObjectsArray[0]));
ObjectsArray = SafeObjectsArray;
-
+
if(TimeOut != NULL)
{
ProbeForRead(TimeOut,
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
{
if (NT_SUCCESS(Status))
{
- DPRINT1("Waiting for object type '%wZ' is not supported\n",
+ DPRINT1("Waiting for object type '%wZ' is not supported\n",
&BODY_TO_HEADER(ObjectPtrArray[i])->ObjectType->TypeName);
Status = STATUS_HANDLE_NOT_WAITABLE;
i++;
ObjectHandle,Alertable,TimeOut);
PreviousMode = ExGetPreviousMode();
-
+
if(TimeOut != NULL && PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
}
if (!KiIsObjectWaitable(ObjectPtr))
{
- DPRINT1("Waiting for object type '%wZ' is not supported\n",
+ DPRINT1("Waiting for object type '%wZ' is not supported\n",
&BODY_TO_HEADER(ObjectPtr)->ObjectType->TypeName);
Status = STATUS_HANDLE_NOT_WAITABLE;
}
NTSTATUS Status = STATUS_SUCCESS;
PreviousMode = ExGetPreviousMode();
-
+
if(TimeOut != NULL && PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
}
}
-
+
Status = ObReferenceObjectByHandle(ObjectHandleToSignal,
0,
NULL,
/* $Id$
- *
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/po/power.c
* PURPOSE: Power Manager
- *
+ *
* PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
STDCALL
PoRequestPowerIrp(
IN PDEVICE_OBJECT DeviceObject,
- IN UCHAR MinorFunction,
+ IN UCHAR MinorFunction,
IN POWER_STATE PowerState,
IN PREQUEST_POWER_COMPLETE CompletionFunction,
IN PVOID Context,
IN POWER_STATE State)
{
POWER_STATE ps;
-
+
ASSERT_IRQL(DISPATCH_LEVEL);
ps.SystemState = PowerSystemWorking; // Fully on
NTSTATUS
PopSetSystemPowerState(
SYSTEM_POWER_STATE PowerState)
-{
+{
IO_STATUS_BLOCK IoStatusBlock;
PDEVICE_OBJECT DeviceObject;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
KEVENT Event;
PIRP Irp;
-
+
if (!PopAcpiPresent) return STATUS_NOT_IMPLEMENTED;
Status = IopGetSystemPowerDeviceObject(&DeviceObject);
return Status;
}
-VOID
+VOID
INIT_FUNCTION
-PoInit(PLOADER_PARAMETER_BLOCK LoaderBlock,
+PoInit(PLOADER_PARAMETER_BLOCK LoaderBlock,
BOOLEAN ForceAcpiDisable)
{
if (ForceAcpiDisable)
/*
* @unimplemented
*/
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtPowerInformation(
IN POWER_INFORMATION_LEVEL PowerInformationLevel,
IN PVOID InputBuffer OPTIONAL,
)
{
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("NtPowerInformation(PowerInformationLevel 0x%x, InputBuffer 0x%x, "
)
{
PAGED_CODE();
-
+
DPRINT1("PoQueueShutdownWorkItem(%p)\n", WorkItem);
return STATUS_NOT_IMPLEMENTED;
{
HANDLE_TABLE_ENTRY NewEntry;
LONG ExHandle;
-
+
PAGED_CODE();
-
+
NewEntry.u1.Object = Object;
if(ObjectType == PsThreadType)
NewEntry.u2.GrantedAccess = CID_FLAG_THREAD;
DPRINT1("Can't create CID handles for %wZ objects\n", &ObjectType->TypeName);
KEBUGCHECK(0);
}
-
+
ExHandle = ExCreateHandle(PspCidTable,
&NewEntry);
if(ExHandle != EX_INVALID_HANDLE)
*Handle = EX_HANDLE_TO_HANDLE(ExHandle);
return STATUS_SUCCESS;
}
-
+
return STATUS_UNSUCCESSFUL;
}
{
PHANDLE_TABLE_ENTRY Entry;
LONG ExHandle = HANDLE_TO_EX_HANDLE(CidHandle);
-
+
PAGED_CODE();
KeEnterCriticalRegion();
PsLookupCidHandle(HANDLE CidHandle, POBJECT_TYPE ObjectType, PVOID *Object)
{
PHANDLE_TABLE_ENTRY Entry;
-
+
PAGED_CODE();
KeEnterCriticalRegion();
-
+
Entry = ExMapHandleToPointer(PspCidTable,
HANDLE_TO_EX_HANDLE(CidHandle));
if(Entry != NULL)
Entry);
}
}
-
+
KeLeaveCriticalRegion();
-
+
return NULL;
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/debug.c
* PURPOSE: Thread managment
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
* Phillip Susi
*/
* FUNCTION: This routine is called by an APC sent by NtGetContextThread to
* copy the context of a thread into a buffer.
*/
-VOID
+VOID
STDCALL
PspGetOrSetContextKernelRoutine(PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PGET_SET_CTX_CONTEXT GetSetContext;
PKEVENT Event;
PCONTEXT Context;
-
+
/* Get the Context Structure */
GetSetContext = CONTAINING_RECORD(Apc, GET_SET_CTX_CONTEXT, Apc);
Context = &GetSetContext->Context;
/* Check if it's a set or get */
if (SystemArgument1) {
-
- /* Get the Context */
+
+ /* Get the Context */
KeTrapFrameToContext(KeGetCurrentThread()->TrapFrame, Context);
-
+
} else {
-
+
/* Set the Context */
KeContextToTrapFrame(Context, KeGetCurrentThread()->TrapFrame);
}
-
+
/* Notify the Native API that we are done */
KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
}
-NTSTATUS
+NTSTATUS
STDCALL
NtGetContextThread(IN HANDLE ThreadHandle,
OUT PCONTEXT ThreadContext)
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
GET_SET_CTX_CONTEXT GetSetContext;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
/* Check the buffer to be OK */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(ThreadContext,
sizeof(CONTEXT),
sizeof(ULONG));
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Get the Thread Object */
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_GET_CONTEXT,
PreviousMode,
(PVOID*)&Thread,
NULL);
-
+
/* Check success */
if(NT_SUCCESS(Status)) {
-
+
/* Check if we're running in the same thread */
if(Thread == PsGetCurrentThread()) {
-
+
/*
* I don't know if trying to get your own context makes much
* sense but we can handle it more efficently.
*/
KeTrapFrameToContext(Thread->Tcb.TrapFrame, &GetSetContext.Context);
-
+
} else {
-
+
/* Use an APC... Initialize the Event */
KeInitializeEvent(&GetSetContext.Event,
NotificationEvent,
FALSE);
-
+
/* Initialize the APC */
KeInitializeApc(&GetSetContext.Apc,
&Thread->Tcb,
NULL,
KernelMode,
NULL);
-
+
/* Queue it as a Get APC */
if (!KeInsertQueueApc(&GetSetContext.Apc,
(PVOID)1,
NULL,
IO_NO_INCREMENT)) {
-
+
Status = STATUS_THREAD_IS_TERMINATING;
-
+
} else {
-
+
/* Wait for the APC to complete */
Status = KeWaitForSingleObject(&GetSetContext.Event,
0,
NULL);
}
}
-
+
/* Dereference the thread */
ObDereferenceObject(Thread);
-
+
/* Check for success and return the Context */
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
*ThreadContext = GetSetContext.Context;
-
+
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
- } _SEH_END;
+
+ } _SEH_END;
}
}
-
- /* Return status */
+
+ /* Return status */
return Status;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtSetContextThread(IN HANDLE ThreadHandle,
IN PCONTEXT ThreadContext)
GET_SET_CTX_CONTEXT GetSetContext;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
/* Check the buffer to be OK */
if(PreviousMode != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForRead(ThreadContext,
sizeof(CONTEXT),
sizeof(ULONG));
-
+
GetSetContext.Context = *ThreadContext;
ThreadContext = &GetSetContext.Context;
-
+
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
} _SEH_END;
-
+
if(!NT_SUCCESS(Status)) return Status;
}
PreviousMode,
(PVOID*)&Thread,
NULL);
-
+
/* Check success */
if(NT_SUCCESS(Status)) {
-
+
/* Check if we're running in the same thread */
if(Thread == PsGetCurrentThread()) {
-
+
/*
* I don't know if trying to get your own context makes much
* sense but we can handle it more efficently.
*/
KeContextToTrapFrame(&GetSetContext.Context, Thread->Tcb.TrapFrame);
-
+
} else {
-
+
/* Use an APC... Initialize the Event */
KeInitializeEvent(&GetSetContext.Event,
NotificationEvent,
FALSE);
-
+
/* Initialize the APC */
KeInitializeApc(&GetSetContext.Apc,
&Thread->Tcb,
NULL,
KernelMode,
NULL);
-
+
/* Queue it as a Get APC */
if (!KeInsertQueueApc(&GetSetContext.Apc,
NULL,
NULL,
IO_NO_INCREMENT)) {
-
+
Status = STATUS_THREAD_IS_TERMINATING;
-
+
} else {
-
+
/* Wait for the APC to complete */
Status = KeWaitForSingleObject(&GetSetContext.Event,
0,
NULL);
}
}
-
+
/* Dereference the thread */
ObDereferenceObject(Thread);
}
-
- /* Return status */
+
+ /* Return status */
return Status;
}
-VOID
+VOID
STDCALL
PspDumpThreads(BOOLEAN IncludeSystem)
{
PEPROCESS Process;
PETHREAD Thread;
ULONG nThreads = 0;
-
+
/* Loop all Active Processes */
CurrentProcess = PsActiveProcessHead.Flink;
while(CurrentProcess != &PsActiveProcessHead)
{
/* Get the process */
Process = CONTAINING_RECORD(CurrentProcess, EPROCESS, ActiveProcessLinks);
-
+
/* Skip the Initial Process if requested */
if((Process != PsInitialSystemProcess) ||
(Process == PsInitialSystemProcess && IncludeSystem))
CurrentThread = Process->ThreadListHead.Flink;
while(CurrentThread != &Process->ThreadListHead)
{
-
+
/* Get teh Thread */
Thread = CONTAINING_RECORD(CurrentThread, ETHREAD, ThreadListEntry);
nThreads++;
-
+
/* Print the Info */
DbgPrint("State %d Affinity %08x Priority %d PID.TID %d.%d Name %.8s Stack: \n",
Thread->Tcb.State,
Thread->Cid.UniqueProcess,
Thread->Cid.UniqueThread,
Thread->ThreadsProcess->ImageFileName);
-
+
/* Make sure it's not running */
if(Thread->Tcb.State == Ready ||
Thread->Tcb.State == Standby ||
ULONG i = 0;
PULONG Esp = (PULONG)Thread->Tcb.KernelStack;
PULONG Ebp = (PULONG)Esp[4];
-
+
/* Print EBP */
DbgPrint("Ebp 0x%.8X\n", Ebp);
-
+
/* Walk it */
while(Ebp != 0 && Ebp >= (PULONG)Thread->Tcb.StackLimit)
{
Ebp = (PULONG)Ebp[0];
i++;
}
-
+
/* Print a new line if there's nothing */
if((i % 8) != 0) DbgPrint("\n");
}
}
-
+
/* Move to the next Thread */
CurrentThread = CurrentThread->Flink;
}
-
+
/* Move to the next Process */
CurrentProcess = CurrentProcess->Flink;
}
{
PKTHREAD Thread = KeGetCurrentThread();
PKTRAP_FRAME TrapFrame = Thread->TrapFrame;
- PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
+ PKTRAP_FRAME PrevTrapFrame = (PKTRAP_FRAME)TrapFrame->Edx;
PFX_SAVE_AREA FxSaveArea;
KIRQL oldIrql;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/idle.c
* PURPOSE: Using idle time
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* David Welch (welch@cwcom.net)
*/
extern PEPROCESS PsIdleProcess;
/* FUNCTIONS *****************************************************************/
-
+
/** System idle thread procedure
*
*/
KIRQL oldlvl;
PKPRCB Prcb = KeGetCurrentPrcb();
-
+
for(;;)
{
if (Prcb->DpcData[0].DpcQueueDepth > 0)
}
}
-/*
+/*
* HACK-O-RAMA
* Antique vestigial code left alive for the sole purpose of First/Idle Thread
* creation until I can merge my fix for properly creating them.
Thread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD));
RtlZeroMemory(Thread, sizeof(ETHREAD));
- Thread->ThreadsProcess = Process;
- if (First)
+ Thread->ThreadsProcess = Process;
+ if (First)
{
KernelStack = (PVOID)init_stack;
}
{
KernelStack = MmCreateKernelStack(FALSE);
}
- KeInitializeThread(&Process->Pcb,
- &Thread->Tcb,
+ KeInitializeThread(&Process->Pcb,
+ &Thread->Tcb,
PspSystemThreadStartup,
StartRoutine,
NULL,
return STATUS_SUCCESS;
}
-/*
+/*
* HACK-O-RAMA
* Antique vestigial code left alive for the sole purpose of First/Idle Thread
* creation until I can merge my fix for properly creating them.
*/
-VOID
+VOID
INIT_FUNCTION
PsInitIdleThread(VOID)
{
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/kill.c
* PURPOSE: Thread Termination and Reaping
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* David Welch (welch@cwcom.net)
*/
#include <internal/debug.h>
/* GLOBALS *******************************************************************/
-
+
#define TAG_TERMINATE_APC TAG('T', 'A', 'P', 'C')
PETHREAD PspReaperList = NULL;
{
KIRQL OldIrql;
PETHREAD Thread, NewThread;
-
+
/* Acquire lock */
DPRINT("Evil reaper running!!\n");
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Get the first Thread Entry */
Thread = PspReaperList;
PspReaperList = NULL;
DPRINT("PspReaperList: %x\n", Thread);
-
+
/* Check to see if the list is empty */
do {
-
+
/* Unlock the Dispatcher */
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
/* Is there a thread on the list? */
while (Thread) {
-
+
/* Get the next Thread */
DPRINT("Thread: %x\n", Thread);
DPRINT("Thread: %x\n", Thread->ReaperLink);
NewThread = Thread->ReaperLink;
-
+
/* Remove reference to current thread */
ObDereferenceObject(Thread);
-
+
/* Move to next Thread */
Thread = NewThread;
}
-
+
/* No more linked threads... Reacquire the Lock */
OldIrql = KeAcquireDispatcherDatabaseLock();
-
+
/* Now try to get a new thread from the list */
Thread = PspReaperList;
PspReaperList = NULL;
DPRINT("PspReaperList: %x\n", Thread);
-
+
/* Loop again if there is a new thread */
} while (Thread);
-
+
PspReaping = FALSE;
DPRINT("Done reaping\n");
KeReleaseDispatcherDatabaseLock(OldIrql);
{
PLIST_ENTRY current_entry;
PEPROCESS current;
-
+
/* Acquire the Active Process Lock */
- ExAcquireFastMutex(&PspActiveProcessMutex);
-
+ ExAcquireFastMutex(&PspActiveProcessMutex);
+
/* Loop all processes on the list */
current_entry = PsActiveProcessHead.Flink;
while (current_entry != &PsActiveProcessHead)
{
current = CONTAINING_RECORD(current_entry, EPROCESS, ActiveProcessLinks);
current_entry = current_entry->Flink;
-
+
if (current->UniqueProcessId != PsInitialSystemProcess->UniqueProcessId &&
current->UniqueProcessId != PsGetCurrentProcessId())
{
PspTerminateProcessThreads(current, STATUS_SUCCESS);
}
}
-
+
/* Release the lock */
ExReleaseFastMutex(&PspActiveProcessMutex);
}
{
PLIST_ENTRY CurrentEntry;
PETHREAD Thread, CurrentThread = PsGetCurrentThread();
-
+
CurrentEntry = Process->ThreadListHead.Flink;
while (CurrentEntry != &Process->ThreadListHead) {
-
+
/* Get the Current Thread */
Thread = CONTAINING_RECORD(CurrentEntry, ETHREAD, ThreadListEntry);
-
+
/* Move to the Next Thread */
CurrentEntry = CurrentEntry->Flink;
-
+
/* Make sure it's not the one we're in */
if (Thread != CurrentThread) {
-
+
/* Make sure it didn't already terminate */
if (!Thread->Terminated) {
Thread->Terminated = TRUE;
-
+
/* Terminate it by APC */
PspTerminateThreadByPointer(Thread, ExitStatus);
}
}
}
-VOID
-STDCALL
+VOID
+STDCALL
PspDeleteProcess(PVOID ObjectBody)
{
PEPROCESS Process = (PEPROCESS)ObjectBody;
ExAcquireFastMutex(&PspActiveProcessMutex);
RemoveEntryList(&Process->ActiveProcessLinks);
ExReleaseFastMutex(&PspActiveProcessMutex);
-
- /* Delete the CID Handle */
+
+ /* Delete the CID Handle */
if(Process->UniqueProcessId != NULL) {
-
+
PsDeleteCidHandle(Process->UniqueProcessId, PsProcessType);
}
-
+
/* KDB hook */
KDB_DELETEPROCESS_HOOK(Process);
-
+
/* Dereference the Token */
SeDeassignPrimaryToken(Process);
-
+
/* Release Memory Information */
MmReleaseMmInfo(Process);
-
+
/* Delete the W32PROCESS structure if there's one associated */
if(Process->Win32Process != NULL) ExFreePool(Process->Win32Process);
}
-VOID
+VOID
STDCALL
PspDeleteThread(PVOID ObjectBody)
{
/* Delete the CID Handle */
if(Thread->Cid.UniqueThread != NULL) {
-
+
PsDeleteCidHandle(Thread->Cid.UniqueThread, PsThreadType);
}
-
+
/* Free the W32THREAD structure if present */
if(Thread->Tcb.Win32Thread != NULL) ExFreePool (Thread->Tcb.Win32Thread);
/* Release the Kernel Stack */
MmDeleteKernelStack((PVOID)Thread->Tcb.StackLimit, FALSE);
-
+
/* Dereference the Process */
ObDereferenceObject(Process);
}
-
+
/*
* FUNCTION: Terminates the current thread
* See "Windows Internals" - Chapter 13, Page 50-53
/* Get the Current Thread and Process */
CurrentThread = PsGetCurrentThread();
CurrentProcess = CurrentThread->ThreadsProcess;
-
+
/* Set the Exit Status and Exit Time */
CurrentThread->ExitStatus = ExitStatus;
KeQuerySystemTime(&CurrentThread->ExitTime);
/* Can't terminate a thread if it attached another process */
if (KeIsAttachedProcess()) {
-
+
KEBUGCHECKEX(INVALID_PROCESS_ATTACH_ATTEMPT, (ULONG) CurrentProcess,
(ULONG) CurrentThread->Tcb.ApcState.Process,
(ULONG) CurrentThread->Tcb.ApcStateIndex,
(ULONG) CurrentThread);
}
-
+
/* Lower to Passive Level */
KeLowerIrql(PASSIVE_LEVEL);
/* Lock the Process before we modify its thread entries */
PsLockProcess(CurrentProcess, FALSE);
-
+
/* wake up the thread so we don't deadlock on PsLockProcess */
KeForceResumeThread(&CurrentThread->Tcb);
-
+
/* Run Thread Notify Routines before we desintegrate the thread */
PspRunCreateThreadNotifyRoutines(CurrentThread, FALSE);
/* Remove the thread from the thread list of its process */
RemoveEntryList(&CurrentThread->ThreadListEntry);
Last = IsListEmpty(&CurrentProcess->ThreadListHead);
-
+
/* Set the last Thread Exit Status */
CurrentProcess->LastThreadExitStatus = ExitStatus;
-
+
if (Last) {
/* Save the Exit Time if not already done by NtTerminateProcess. This
terminating the process. */
CurrentProcess->ExitTime = CurrentThread->ExitTime;
}
-
+
/* Check if the process has a debug port */
if (CurrentProcess->DebugPort) {
-
+
/* Notify the Debug API. TODO */
//Last ? DbgkExitProcess(ExitStatus) : DbgkExitThread(ExitStatus);
}
-
- /* Process the Termination Ports */
+
+ /* Process the Termination Ports */
TerminationPort = CurrentThread->TerminationPort;
DPRINT("TerminationPort: %p\n", TerminationPort);
while (TerminationPort) {
-
+
/* Send the LPC Message */
LpcSendTerminationPort(TerminationPort->Port, CurrentThread->CreateTime);
-
+
/* Free the Port */
ExFreePool(TerminationPort);
-
+
/* Get the next one */
TerminationPort = TerminationPort->Next;
DPRINT("TerminationPort: %p\n", TerminationPort);
}
-
+
/* Rundown Win32 Structures */
PsTerminateWin32Thread(CurrentThread);
if (Last) PsTerminateWin32Process(CurrentProcess);
-
+
/* Rundown Registry Notifications. TODO (refers to NtChangeNotify, not Cm callbacks) */
//CmNotifyRunDown(CurrentThread);
-
+
/* Free the TEB */
if((Teb = CurrentThread->Tcb.Teb)) {
MmDeleteTeb(CurrentProcess, Teb);
CurrentThread->Tcb.Teb = NULL;
}
-
+
/* The last Thread shuts down the Process */
if (Last) PspExitProcess(CurrentProcess);
-
+
/* Unlock the Process */
PsUnlockProcess(CurrentProcess);
-
+
/* Cancel I/O for the thread. */
IoCancelThreadIo(CurrentThread);
-
+
/* Rundown Timers */
ExTimerRundown();
KeCancelTimer(&CurrentThread->Tcb.Timer);
-
+
/* If the Processor Control Block's NpxThread points to the current thread
* unset it.
*/
InterlockedCompareExchangePointer(&KeGetCurrentPrcb()->NpxThread,
NULL,
(PKPROCESS)CurrentThread);
-
+
/* Rundown Mutexes */
KeRundownThread();
KEBUGCHECK(0);
}
-VOID
+VOID
STDCALL
PsExitSpecialApc(PKAPC Apc,
PKNORMAL_ROUTINE* NormalRoutine,
PVOID* SystemArguemnt2)
{
NTSTATUS ExitStatus = (NTSTATUS)Apc->NormalContext;
-
+
DPRINT("PsExitSpecialApc called: 0x%x (proc: 0x%x)\n", PsGetCurrentThread(), PsGetCurrentProcess());
-
+
/* Free the APC */
ExFreePool(Apc);
-
+
/* Terminate the Thread */
PspExitThread(ExitStatus);
-
+
/* we should never reach this point! */
KEBUGCHECK(0);
}
-VOID
+VOID
STDCALL
PspExitNormalApc(PVOID NormalContext,
PVOID SystemArgument1,
PVOID SystemArgument2)
{
- /* Not fully supported yet... must work out some issues that
- * I don't understand yet -- Alex
+ /* Not fully supported yet... must work out some issues that
+ * I don't understand yet -- Alex
*/
DPRINT1("APC2\n");
PspExitThread((NTSTATUS)NormalContext);
-
+
/* we should never reach this point! */
KEBUGCHECK(0);
}
PspTerminateThreadByPointer(PETHREAD Thread,
NTSTATUS ExitStatus)
{
- PKAPC Apc;
-
+ PKAPC Apc;
+
DPRINT("PspTerminatedThreadByPointer(Thread %x, ExitStatus %x)\n",
Thread, ExitStatus);
-
+
/* Check if we are already in the right context */
if (PsGetCurrentThread() == Thread) {
/* we should never reach this point! */
KEBUGCHECK(0);
}
-
+
/* Allocate the APC */
Apc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG_TERMINATE_APC);
-
+
/* Initialize a Kernel Mode APC to Kill the Thread */
KeInitializeApc(Apc,
&Thread->Tcb,
PspExitNormalApc,
KernelMode,
(PVOID)ExitStatus);
-
+
/* Insert it into the APC Queue */
KeInsertQueueApc(Apc,
Apc,
NULL,
2);
-
+
/* Forcefully resume the thread */
KeForceResumeThread(&Thread->Tcb);
}
-
-NTSTATUS
+
+NTSTATUS
STDCALL
PspExitProcess(PEPROCESS Process)
{
DPRINT("PspExitProcess 0x%x\n", Process);
-
+
PspRunCreateProcessNotifyRoutines(Process, FALSE);
-
+
/* close all handles associated with our process, this needs to be done
when the last thread still runs */
ObKillProcess(Process);
KeSetProcess(&Process->Pcb, IO_NO_INCREMENT);
-
+
return(STATUS_SUCCESS);
}
-NTSTATUS
+NTSTATUS
STDCALL
NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL,
IN NTSTATUS ExitStatus)
PEPROCESS Process;
PETHREAD CurrentThread;
BOOLEAN KillByHandle;
-
+
PAGED_CODE();
-
+
DPRINT("NtTerminateProcess(ProcessHandle %x, ExitStatus %x)\n",
ProcessHandle, ExitStatus);
-
+
KillByHandle = (ProcessHandle != NULL);
/* Get the Process Object */
DPRINT1("Invalid handle to Process\n");
return(Status);
}
-
+
CurrentThread = PsGetCurrentThread();
-
+
PsLockProcess(Process, FALSE);
-
+
if(Process->ExitTime.QuadPart != 0)
{
PsUnlockProcess(Process);
return STATUS_PROCESS_IS_TERMINATING;
}
-
+
/* Terminate all the Process's Threads */
PspTerminateProcessThreads(Process, ExitStatus);
-
+
/* only kill the calling thread if it either passed a process handle or
NtCurrentProcess() */
if (KillByHandle) {
/* unlock and dereference the process so the threads can kill themselves */
PsUnlockProcess(Process);
ObDereferenceObject(Process);
-
+
return(STATUS_SUCCESS);
}
-NTSTATUS
+NTSTATUS
STDCALL
NtTerminateThread(IN HANDLE ThreadHandle,
IN NTSTATUS ExitStatus)
{
PETHREAD Thread;
NTSTATUS Status;
-
+
PAGED_CODE();
-
+
/* Get the Thread Object */
Status = ObReferenceObjectByHandle(ThreadHandle,
THREAD_TERMINATE,
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1("Could not reference thread object\n");
return(Status);
}
-
+
/* Make sure this is not a system thread */
if (PsIsSystemThread(Thread)) {
-
+
DPRINT1("Trying to Terminate a system thread!\n");
ObDereferenceObject(Thread);
return STATUS_INVALID_PARAMETER;
}
-
+
/* Check to see if we're running in the same thread */
if (Thread != PsGetCurrentThread()) {
-
+
/* we need to lock the process to make sure it's not already terminating */
PsLockProcess(Thread->ThreadsProcess, FALSE);
-
+
/* This isn't our thread, terminate it if not already done */
if (!Thread->Terminated) {
-
+
Thread->Terminated = TRUE;
-
+
/* Terminate it */
PspTerminateThreadByPointer(Thread, ExitStatus);
}
-
+
PsUnlockProcess(Thread->ThreadsProcess);
-
+
/* Dereference the Thread and return */
ObDereferenceObject(Thread);
-
+
} else {
Thread->Terminated = TRUE;
-
+
/* it's safe to dereference thread, there's at least the keep-alive
reference which will be removed by the thread reaper causing the
thread to be finally destroyed */
ObDereferenceObject(Thread);
-
+
/* Terminate him, he's ours */
PspExitThread(ExitStatus);
/* We do never reach this point */
KEBUGCHECK(0);
}
-
+
return(STATUS_SUCCESS);
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
PsTerminateSystemThread(NTSTATUS ExitStatus)
{
PETHREAD Thread = PsGetCurrentThread();
-
+
/* Make sure this is a system thread */
if (!PsIsSystemThread(Thread)) {
-
+
DPRINT1("Trying to Terminate a non-system thread!\n");
return STATUS_INVALID_PARAMETER;
}
-
+
/* Terminate it for real */
PspExitThread(ExitStatus);
-
+
/* we should never reach this point! */
KEBUGCHECK(0);
-
+
return(STATUS_SUCCESS);
}
-NTSTATUS
+NTSTATUS
STDCALL
NtRegisterThreadTerminatePort(HANDLE PortHandle)
{
PTERMINATION_PORT TerminationPort;
PVOID TerminationLpcPort;
PETHREAD Thread;
-
+
PAGED_CODE();
-
+
/* Get the Port */
Status = ObReferenceObjectByHandle(PortHandle,
PORT_ALL_ACCESS,
LpcPortObjectType,
KeGetPreviousMode(),
&TerminationLpcPort,
- NULL);
+ NULL);
if (!NT_SUCCESS(Status)) {
-
+
DPRINT1("Failed to reference Port\n");
return(Status);
}
-
+
/* Allocate the Port and make sure it suceeded */
- if((TerminationPort = ExAllocatePoolWithTag(NonPagedPool,
- sizeof(PTERMINATION_PORT),
+ if((TerminationPort = ExAllocatePoolWithTag(NonPagedPool,
+ sizeof(PTERMINATION_PORT),
TAG('P', 's', 'T', '=')))) {
-
+
/* Associate the Port */
Thread = PsGetCurrentThread();
TerminationPort->Port = TerminationLpcPort;
/* Return success */
return(STATUS_SUCCESS);
-
+
} else {
-
+
/* Dereference and Fail */
ObDereferenceObject(TerminationPort);
return(STATUS_INSUFFICIENT_RESOURCES);
WCHAR ValueBuffer[20];
HANDLE UserKey = NULL;
NTSTATUS Status;
-
+
PAGED_CODE();
if (UserProfile)
HANDLE UserKey;
HANDLE KeyHandle;
NTSTATUS Status;
-
+
PAGED_CODE();
Status = RtlOpenCurrentUser(KEY_READ,
NtQueryInstallUILanguage(OUT PLANGID LanguageId)
{
PAGED_CODE();
-
+
*LanguageId = PsInstallUILanguageId;
return STATUS_SUCCESS;
HANDLE UserHandle;
HANDLE KeyHandle;
NTSTATUS Status;
-
+
PAGED_CODE();
Status = RtlOpenCurrentUser(KEY_WRITE,
static PCREATE_THREAD_NOTIFY_ROUTINE
PspThreadNotifyRoutine[MAX_THREAD_NOTIFY_ROUTINE_COUNT];
-static PCREATE_PROCESS_NOTIFY_ROUTINE
+static PCREATE_PROCESS_NOTIFY_ROUTINE
PspProcessNotifyRoutine[MAX_PROCESS_NOTIFY_ROUTINE_COUNT];
static PLOAD_IMAGE_NOTIFY_ROUTINE
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
PsSetCreateProcessNotifyRoutine(IN PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,
IN BOOLEAN Remove)
return(STATUS_SUCCESS);
}
}
- }
- else
+ }
+ else
{
/* Loop the routines */
for(i=0;i<MAX_PROCESS_NOTIFY_ROUTINE_COUNT;i++)
}
}
}
-
+
/* Nothing found */
return STATUS_INVALID_PARAMETER;
}
/*
* @implemented
- */
+ */
ULONG
STDCALL
PsSetLegoNotifyRoutine(PVOID LegoNotifyRoutine)
{
/* Set the System-Wide Lego Routine */
PspLegoNotifyRoutine = LegoNotifyRoutine;
-
+
/* Return the location to the Lego Data */
return FIELD_OFFSET(KTHREAD, LegoData);
}
/*
* @implemented
- */
+ */
NTSTATUS
STDCALL
PsRemoveLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine)
{
ULONG i;
-
+
/* Loop the routines */
for(i=0;i<MAX_LOAD_IMAGE_NOTIFY_ROUTINE_COUNT;i++)
{
return(STATUS_SUCCESS);
}
}
-
+
/* Nothing found */
return STATUS_INVALID_PARAMETER;
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
PsSetLoadImageNotifyRoutine(IN PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine)
{
PsRemoveCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
{
ULONG i;
-
+
/* Loop the routines */
for(i=0;i<MAX_THREAD_NOTIFY_ROUTINE_COUNT;i++)
{
return(STATUS_SUCCESS);
}
}
-
+
/* Nothing found */
return STATUS_INVALID_PARAMETER;
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
PsSetCreateThreadNotifyRoutine(IN PCREATE_THREAD_NOTIFY_ROUTINE NotifyRoutine)
{
return(STATUS_SUCCESS);
}
-VOID
+VOID
STDCALL
PspRunCreateThreadNotifyRoutines(PETHREAD CurrentThread,
BOOLEAN Create)
ULONG i;
HANDLE ProcessId = (HANDLE)CurrentProcess->UniqueProcessId;
HANDLE ParentId = CurrentProcess->InheritedFromUniqueProcessId;
-
- for(i = 0; i < MAX_PROCESS_NOTIFY_ROUTINE_COUNT; ++i)
+
+ for(i = 0; i < MAX_PROCESS_NOTIFY_ROUTINE_COUNT; ++i)
{
- if(PspProcessNotifyRoutine[i])
+ if(PspProcessNotifyRoutine[i])
{
PspProcessNotifyRoutine[i](ParentId, ProcessId, Create);
}
}
}
-VOID
+VOID
STDCALL
PspRunLoadImageNotifyRoutines(PUNICODE_STRING FullImageName,
HANDLE ProcessId,
PIMAGE_INFO ImageInfo)
{
ULONG i;
-
+
for (i = 0; i < MAX_PROCESS_NOTIFY_ROUTINE_COUNT; ++ i)
{
if (PspLoadImageNotifyRoutine[i])
LIST_ENTRY PsActiveProcessHead;
FAST_MUTEX PspActiveProcessMutex;
LARGE_INTEGER ShortPsLockDelay, PsLockTimeout;
-
+
/* INTERNAL FUNCTIONS *****************************************************************/
NTSTATUS
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PLARGE_INTEGER Delay = (Timeout ? &PsLockTimeout : NULL);
PKTHREAD CallingThread = KeGetCurrentThread();
-
+
PAGED_CODE();
-
+
KeEnterCriticalRegion();
-
+
for(;;)
{
PrevLockOwner = (PKTHREAD)InterlockedCompareExchangePointer(
}
}
}
-
+
return Status;
}
PsUnlockProcess(PEPROCESS Process)
{
PAGED_CODE();
-
+
ASSERT(Process->LockOwner == KeGetCurrentThread());
-
+
if(InterlockedDecrementUL(&Process->LockCount) == 0)
{
InterlockedExchangePointer(&Process->LockOwner, NULL);
KeSetEvent(&Process->LockEvent, IO_NO_INCREMENT, FALSE);
}
-
+
KeLeaveCriticalRegion();
}
{
PEPROCESS NextProcess;
NTSTATUS Status;
-
+
/* Check if we have a previous process */
if (OldProcess == NULL)
{
Status = ObReferenceObjectByPointer(PsIdleProcess,
PROCESS_ALL_ACCESS,
PsProcessType,
- KernelMode);
+ KernelMode);
if (!NT_SUCCESS(Status))
{
DPRINT1("PsGetNextProcess(): ObReferenceObjectByPointer failed for PsIdleProcess\n");
KEBUGCHECK(0);
}
-
+
return PsIdleProcess;
}
-
+
/* Acquire the Active Process Lock */
ExAcquireFastMutex(&PspActiveProcessMutex);
-
+
/* Start at the previous process */
NextProcess = OldProcess;
-
+
/* Loop until we fail */
while (1)
{
/* Get the Process Link */
PLIST_ENTRY Flink = (NextProcess == PsIdleProcess ? PsActiveProcessHead.Flink :
NextProcess->ActiveProcessLinks.Flink);
-
+
/* Move to the next Process if we're not back at the beginning */
if (Flink != &PsActiveProcessHead)
{
PsProcessType,
KernelMode);
- /* Exit the loop if the reference worked, keep going if there's an error */
+ /* Exit the loop if the reference worked, keep going if there's an error */
if (NT_SUCCESS(Status)) break;
}
-
+
/* Release the lock */
ExReleaseFastMutex(&PspActiveProcessMutex);
-
+
/* Reference the Process we had referenced earlier */
ObDereferenceObject(OldProcess);
return(NextProcess);
{
HANDLE hProcess;
PEPROCESS Process;
- PEPROCESS pParentProcess;
+ PEPROCESS pParentProcess;
PEPORT pDebugPort = NULL;
PEPORT pExceptionPort = NULL;
PSECTION_OBJECT SectionObject = NULL;
DirectoryTableBase.QuadPart = (ULONGLONG)0;
DPRINT("PspCreateProcess(ObjectAttributes %x)\n", ObjectAttributes);
-
+
/* Reference the Parent if there is one */
- if(ParentProcess != NULL)
+ if(ParentProcess != NULL)
{
Status = ObReferenceObjectByHandle(ParentProcess,
PROCESS_CREATE_PROCESS,
PreviousMode,
(PVOID*)&pParentProcess,
NULL);
-
- if (!NT_SUCCESS(Status))
+
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference the parent process: Status: 0x%x\n", Status);
return(Status);
}
-
+
/* Inherit Parent process's Affinity. */
- Affinity = pParentProcess->Pcb.Affinity;
-
- }
- else
+ Affinity = pParentProcess->Pcb.Affinity;
+
+ }
+ else
{
pParentProcess = NULL;
Affinity = KeActiveProcessors;
}
/* Add the debug port */
- if (DebugPort != NULL)
- {
+ if (DebugPort != NULL)
+ {
Status = ObReferenceObjectByHandle(DebugPort,
PORT_ALL_ACCESS,
LpcPortObjectType,
- PreviousMode,
+ PreviousMode,
(PVOID*)&pDebugPort,
NULL);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference the debug port: Status: 0x%x\n", Status);
goto exitdereferenceobjects;
}
/* Add the exception port */
- if (ExceptionPort != NULL)
+ if (ExceptionPort != NULL)
{
Status = ObReferenceObjectByHandle(ExceptionPort,
PORT_ALL_ACCESS,
PreviousMode,
(PVOID*)&pExceptionPort,
NULL);
-
- if (!NT_SUCCESS(Status))
+
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to reference the exception port: Status: 0x%x\n", Status);
goto exitdereferenceobjects;
}
/* Add the Section */
- if (SectionHandle != NULL)
+ if (SectionHandle != NULL)
{
Status = ObReferenceObjectByHandle(SectionHandle,
0,
0,
0,
(PVOID*)&Process);
-
- if (!NT_SUCCESS(Status))
+
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create process object, Status: 0x%x\n", Status);
goto exitdereferenceobjects;
}
-
+
/* Clean up the Object */
DPRINT("Cleaning Process Object\n");
RtlZeroMemory(Process, sizeof(EPROCESS));
-
+
/* Inherit stuff from the Parent since we now have the object created */
- if (pParentProcess)
+ if (pParentProcess)
{
Process->InheritedFromUniqueProcessId = pParentProcess->UniqueProcessId;
Process->Session = pParentProcess->Session;
}
-
+
/* FIXME: Set up the Quota Block from the Parent
PspInheritQuota(Parent, Process); */
-
+
/* FIXME: Set up Dos Device Map from the Parent
ObInheritDeviceMap(Parent, Process) */
-
+
/* Set the Process' LPC Ports */
Process->DebugPort = pDebugPort;
Process->ExceptionPort = pExceptionPort;
-
+
/* Setup the Lock Event */
DPRINT("Initialzing Process Lock\n");
KeInitializeEvent(&Process->LockEvent, SynchronizationEvent, FALSE);
-
+
/* Setup the Thread List Head */
DPRINT("Initialzing Process ThreadListHead\n");
InitializeListHead(&Process->ThreadListHead);
-
+
/* Create or Clone the Handle Table */
DPRINT("Initialzing Process Handle Table\n");
ObCreateHandleTable(pParentProcess, InheritObjectTable, Process);
DPRINT("Handle Table: %x\n", Process->ObjectTable);
-
+
/* Set Process's Directory Base */
DPRINT("Initialzing Process Directory Base\n");
- MmCopyMmInfo(pParentProcess ? pParentProcess : PsInitialSystemProcess,
+ MmCopyMmInfo(pParentProcess ? pParentProcess : PsInitialSystemProcess,
Process,
&DirectoryTableBase);
-
+
/* Now initialize the Kernel Process */
DPRINT("Initialzing Kernel Process\n");
KeInitializeProcess(&Process->Pcb,
PROCESS_PRIO_NORMAL,
Affinity,
DirectoryTableBase);
-
+
/* Duplicate Parent Token */
DPRINT("Initialzing Process Token\n");
Status = PspInitializeProcessSecurity(Process, pParentProcess);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DbgPrint("PspInitializeProcessSecurity failed (Status %x)\n", Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
-
+
/* Create the Process' Address Space */
DPRINT("Initialzing Process Address Space\n");
Status = MmCreateProcessAddressSpace(Process, SectionObject);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to create Address Space\n");
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
-
- if (SectionObject)
+
+ if (SectionObject)
{
/* Map the System Dll */
DPRINT("Mapping System DLL\n");
PsProcessType,
&Process->UniqueProcessId);
DPRINT("Created CID: %d\n", Process->UniqueProcessId);
- if(!NT_SUCCESS(Status))
+ if(!NT_SUCCESS(Status))
{
DPRINT1("Failed to create CID handle (unique process ID)! Status: 0x%x\n", Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
-
+
/* FIXME: Insert into Job Object */
/* Create PEB only for User-Mode Processes */
- if (pParentProcess)
+ if (pParentProcess)
{
DPRINT("Creating PEB\n");
Status = MmCreatePeb(Process);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DbgPrint("NtCreateProcess() Peb creation failed: Status %x\n",Status);
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
-
+
/* Let's take advantage of this time to kill the reference too */
ObDereferenceObject(pParentProcess);
pParentProcess = NULL;
ExAcquireFastMutex(&PspActiveProcessMutex);
InsertTailList(&PsActiveProcessHead, &Process->ActiveProcessLinks);
ExReleaseFastMutex(&PspActiveProcessMutex);
-
+
/* FIXME: SeCreateAccessStateEx */
-
+
/* Insert the Process into the Object Directory */
DPRINT("Inserting Process Object\n");
Status = ObInsertObject(Process,
0,
NULL,
&hProcess);
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
DPRINT1("Could not get a handle to the Process Object\n");
ObDereferenceObject(Process);
goto exitdereferenceobjects;
}
-
+
/* Set the Creation Time */
KeQuerySystemTime(&Process->CreateTime);
-
+
DPRINT("Done. Returning handle: %x\n", hProcess);
- _SEH_TRY
+ _SEH_TRY
{
*ProcessHandle = hProcess;
- }
- _SEH_HANDLE
+ }
+ _SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
} _SEH_END;
-
+
/* FIXME: ObGetObjectSecurity(Process, &SecurityDescriptor)
SeAccessCheck
*/
ObDereferenceObject(Process);
return Status;
-
+
exitdereferenceobjects:
if(SectionObject != NULL) ObDereferenceObject(SectionObject);
if(pExceptionPort != NULL) ObDereferenceObject(pExceptionPort);
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
PsCreateSystemProcess(PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
PsLookupProcessByProcessId(IN HANDLE ProcessId,
OUT PEPROCESS *Process)
PEPROCESS STDCALL
IoGetCurrentProcess(VOID)
{
- if (PsGetCurrentThread() == NULL ||
+ if (PsGetCurrentThread() == NULL ||
PsGetCurrentThread()->Tcb.ApcState.Process == NULL)
{
return(PsInitialSystemProcess);
/*
* @implemented
- */
+ */
VOID
STDCALL
PsSetProcessPriorityClass(PEPROCESS Process,
/*
* @implemented
- */
+ */
VOID
STDCALL
PsSetProcessSecurityPort(PEPROCESS Process,
*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtCreateProcess(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
{
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
- /* Check parameters */
+
+ /* Check parameters */
if(PreviousMode != KernelMode)
{
_SEH_TRY
if(!NT_SUCCESS(Status)) return Status;
}
-
+
/* Make sure there's a parent process */
if(ParentProcess == NULL)
{
DebugPort,
ExceptionPort);
}
-
+
/* Return Status */
return Status;
}
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtOpenProcess(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
NTSTATUS Status = STATUS_INVALID_PARAMETER;
PEPROCESS Process;
PETHREAD Thread = NULL;
-
+
DPRINT("NtOpenProcess(ProcessHandle %x, DesiredAccess %x, "
"ObjectAttributes %x, ClientId %x { UniP %d, UniT %d })\n",
ProcessHandle, DesiredAccess, ObjectAttributes, ClientId,
ClientId->UniqueProcess, ClientId->UniqueThread);
-
+
PAGED_CODE();
-
+
/* Open by name if one was given */
DPRINT("Checking type\n");
if (ObjectAttributes->ObjectName)
{
- /* Open it */
+ /* Open it */
DPRINT("Opening by name\n");
Status = ObOpenObjectByName(ObjectAttributes,
PsProcessType,
DesiredAccess,
NULL,
ProcessHandle);
-
+
if (Status != STATUS_SUCCESS)
{
DPRINT1("Could not open object by name\n");
}
-
+
/* Return Status */
DPRINT("Found: %x\n", ProcessHandle);
return(Status);
&Process,
&Thread);
DPRINT("Found: %x\n", Process);
- }
- else
+ }
+ else
{
/* Get the Process */
DPRINT("Opening by Process ID: %x\n", ClientId->UniqueProcess);
&Process);
DPRINT("Found: %x\n", Process);
}
-
+
if(!NT_SUCCESS(Status))
{
DPRINT1("Failure to find process\n");
return Status;
}
-
+
/* Open the Process Object */
Status = ObOpenObjectByPointer(Process,
ObjectAttributes->Attributes,
{
DPRINT1("Failure to open process\n");
}
-
+
/* Dereference the thread if we used it */
if (Thread) ObDereferenceObject(Thread);
-
+
/* Dereference the Process */
ObDereferenceObject(Process);
}
-
+
return Status;
}
/* EOF */
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/psmgr.c
* PURPOSE: Process management
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
STANDARD_RIGHTS_READ | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
STANDARD_RIGHTS_WRITE | PROCESS_CREATE_PROCESS | PROCESS_CREATE_THREAD |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE |
- PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
+ PROCESS_TERMINATE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION |
PROCESS_SUSPEND_RESUME,
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
PROCESS_ALL_ACCESS};
THREAD_ALERT | THREAD_SET_INFORMATION | THREAD_SET_CONTEXT,
STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
THREAD_ALL_ACCESS};
-
+
BOOLEAN DoneInitYet = FALSE;
extern ULONG NtBuildNumber;
extern ULONG NtMajorVersion;
extern ULONG NtMinorVersion;
-VOID
+VOID
INIT_FUNCTION
PsInitClientIDManagment(VOID);
VOID PiShutdownProcessManager(VOID)
{
DPRINT("PiShutdownProcessManager()\n");
-
+
PspKillMostProcesses();
}
PsInitialiseW32Call();
}
-VOID
+VOID
INIT_FUNCTION
PsInitThreadManagment(VOID)
/*
DPRINT("FirstThread %x\n",FirstThread);
DoneInitYet = TRUE;
-
+
ExInitializeWorkItem(&PspReaperWorkItem, PspReapRoutine, NULL);
}
-VOID
+VOID
INIT_FUNCTION
PsInitProcessManagment(VOID)
{
PKPROCESS KProcess;
NTSTATUS Status;
-
+
ShortPsLockDelay.QuadPart = -100LL;
PsLockTimeout.QuadPart = -10000000LL; /* one second */
/*
* Register the process object type
*/
-
+
PsProcessType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
PsProcessType->Tag = TAG('P', 'R', 'O', 'C');
PsProcessType->OkayToClose = NULL;
PsProcessType->Create = NULL;
PsProcessType->DuplicationNotify = NULL;
-
+
RtlInitUnicodeString(&PsProcessType->TypeName, L"Process");
-
+
ObpCreateTypeObject(PsProcessType);
InitializeListHead(&PsActiveProcessHead);
ExInitializeFastMutex(&PspActiveProcessMutex);
-
+
/*
* Initialize the idle process
*/
}
RtlZeroMemory(PsIdleProcess, sizeof(EPROCESS));
-
+
PsIdleProcess->Pcb.Affinity = 0xFFFFFFFF;
PsIdleProcess->Pcb.IopmOffset = 0xffff;
PsIdleProcess->Pcb.BasePriority = PROCESS_PRIO_IDLE;
KEBUGCHECK(0);
return;
}
-
+
/* System threads may run on any processor. */
RtlZeroMemory(PsInitialSystemProcess, sizeof(EPROCESS));
PsInitialSystemProcess->Pcb.Affinity = 0xFFFFFFFF;
sizeof(EPROCESS),
FALSE);
KProcess = &PsInitialSystemProcess->Pcb;
-
+
MmInitializeAddressSpace(PsInitialSystemProcess,
&PsInitialSystemProcess->AddressSpace);
-
+
KeInitializeEvent(&PsInitialSystemProcess->LockEvent, SynchronizationEvent, FALSE);
#if defined(__GNUC__)
- KProcess->DirectoryTableBase =
+ KProcess->DirectoryTableBase =
(LARGE_INTEGER)(LONGLONG)(ULONG)MmGetPageDirectory();
#else
{
#endif
strcpy(PsInitialSystemProcess->ImageFileName, "System");
-
+
PsInitialSystemProcess->Win32WindowStation = (HANDLE)0;
-
+
InsertHeadList(&PsActiveProcessHead,
&PsInitialSystemProcess->ActiveProcessLinks);
InitializeListHead(&PsInitialSystemProcess->ThreadListHead);
-
+
#ifndef SCHED_REWRITE
PTOKEN BootToken;
-
+
/* No parent, this is the Initial System Process. Assign Boot Token */
BootToken = SepCreateSystemProcessToken();
BootToken->TokenInUse = TRUE;
PspPostInitSystemProcess(VOID)
{
NTSTATUS Status;
-
+
/* this routine is called directly after the exectuive handle tables were
initialized. We'll set up the Client ID handle table and assign the system
process a PID */
PsInitClientIDManagment();
-
+
ObCreateHandleTable(NULL, FALSE, PsInitialSystemProcess);
ObpKernelHandleTable = PsInitialSystemProcess->ObjectTable;
-
+
Status = PsCreateCidHandle(PsInitialSystemProcess,
PsProcessType,
&PsInitialSystemProcess->UniqueProcessId);
ICI_SQ_SAME( 0, 1, 0 ), /* ProcessUnknown33 */
ICI_SQ_SAME( 0, 1, 0 ), /* ProcessUnknown34 */
ICI_SQ_SAME( 0, 1, 0 ), /* ProcessUnknown35 */
-
+
ICI_SQ_SAME( sizeof(ULONG), sizeof(ULONG), ICIF_QUERY), /* ProcessCookie */
};
{
BOOLEAN Implemented;
ULONG Size;
-} QueryInformationData[MaxThreadInfoClass + 1] =
+} QueryInformationData[MaxThreadInfoClass + 1] =
{
{TRUE, sizeof(THREAD_BASIC_INFORMATION)}, // ThreadBasicInformation
{TRUE, sizeof(KERNEL_USER_TIMES)}, // ThreadTimes
{
BOOLEAN Implemented;
ULONG Size;
-} SetInformationData[MaxThreadInfoClass + 1] =
+} SetInformationData[MaxThreadInfoClass + 1] =
{
{TRUE, 0}, // ThreadBasicInformation
{TRUE, 0}, // ThreadTimes
PEPROCESS Process;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
DefaultQueryInfoBufferCheck(ProcessInformationClass,
PsProcessInfoClass,
ProcessInformation,
DPRINT1("NtQueryInformationProcess() failed, Status: 0x%x\n", Status);
return Status;
}
-
+
if(ProcessInformationClass != ProcessCookie)
{
Status = ObReferenceObjectByHandle(ProcessHandle,
real handle actually represents the current process. */
return STATUS_INVALID_PARAMETER;
}
-
+
switch (ProcessInformationClass)
{
case ProcessBasicInformation:
_SEH_END;
break;
}
-
+
case ProcessLdtInformation:
case ProcessWorkingSetWatch:
case ProcessWx86Information:
case ProcessHandleCount:
{
ULONG HandleCount = ObpGetHandleCountByHandleTable(Process->ObjectTable);
-
+
_SEH_TRY
{
*(PULONG)ProcessInformation = HandleCount;
_SEH_END;
break;
}
-
+
case ProcessWow64Information:
DPRINT1("We currently don't support the ProcessWow64Information information class!\n");
Status = STATUS_NOT_IMPLEMENTED;
case ProcessVmCounters:
{
PVM_COUNTERS pOut = (PVM_COUNTERS)ProcessInformation;
-
+
_SEH_TRY
{
pOut->PeakVirtualSize = Process->PeakVirtualSize;
case ProcessPriorityBoost:
{
PULONG BoostEnabled = (PULONG)ProcessInformation;
-
+
_SEH_TRY
{
*BoostEnabled = Process->Pcb.DisableBoost ? FALSE : TRUE;
case ProcessDeviceMap:
{
PROCESS_DEVICEMAP_INFORMATION DeviceMap;
-
+
ObQueryDeviceMapInformation(Process, &DeviceMap);
_SEH_TRY
if(Attached)
KeAttachProcess(&Process->Pcb);
-
+
_SEH_TRY
{
ProcParams = Process->Peb->ProcessParameters;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(NT_SUCCESS(Status))
{
if(ProcessInformationLength < sizeof(UNICODE_STRING) + ImagePathLen + sizeof(WCHAR))
else
{
PWSTR StrSource = NULL;
-
+
RtlZeroMemory(&LocalDest, sizeof(LocalDest));
/* create a DstPath structure on the stack */
}
}
}
-
+
/* don't forget to detach from the process!!! */
if(Attached)
KeDetachProcess();
}
break;
}
-
+
case ProcessCookie:
{
ULONG Cookie;
-
+
/* receive the process cookie, this is only allowed for the current
process! */
LARGE_INTEGER SystemTime;
ULONG NewCookie;
PKPRCB Prcb;
-
+
/* generate a new cookie */
-
+
KeQuerySystemTime(&SystemTime);
-
+
Prcb = KeGetCurrentPrcb();
NewCookie = Prcb->KeSystemCalls ^ Prcb->InterruptTime ^
SystemTime.u.LowPart ^ SystemTime.u.HighPart;
-
+
/* try to set the new cookie, return the current one if another thread
set it in the meanwhile */
Cookie = InterlockedCompareExchange((LONG*)&Process->Cookie,
Cookie = NewCookie;
}
}
-
+
_SEH_TRY
{
*(PULONG)ProcessInformation = Cookie;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
break;
}
{
ObDereferenceObject(Process);
}
-
+
return Status;
}
KPROCESSOR_MODE PreviousMode;
ACCESS_MASK Access;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
DefaultSetInfoBufferCheck(ProcessInformationClass,
DPRINT1("NtSetInformationProcess() %x failed, Status: 0x%x\n", Status);
return Status;
}
-
+
switch(ProcessInformationClass)
{
case ProcessSessionInformation:
Access = PROCESS_SET_INFORMATION;
break;
}
-
+
Status = ObReferenceObjectByHandle(ProcessHandle,
Access,
PsProcessType,
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(NT_SUCCESS(Status))
{
PEPORT ExceptionPort;
-
+
/* in case we had success reading from the buffer, verify the provided
* LPC port handle
*/
if(NT_SUCCESS(Status))
{
/* lock the process to be thread-safe! */
-
+
Status = PsLockProcess(Process, FALSE);
if(NT_SUCCESS(Status))
{
_SEH_END;
break;
}
-
+
case ProcessSessionInformation:
{
PROCESS_SESSION_INFORMATION SessionInfo;
Status = STATUS_SUCCESS;
-
+
RtlZeroMemory(&SessionInfo, sizeof(SessionInfo));
-
+
_SEH_TRY
{
/* copy the structure to the stack */
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(NT_SUCCESS(Status))
{
/* we successfully copied the structure to the stack, continue processing */
-
+
/*
* setting the session id requires the SeTcbPrivilege!
*/
Status = STATUS_PRIVILEGE_NOT_HELD;
break;
}
-
+
/* FIXME - update the session id for the process token */
Status = PsLockProcess(Process, FALSE);
}
break;
}
-
+
case ProcessPriorityClass:
{
PROCESS_PRIORITY_CLASS ppc;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(NT_SUCCESS(Status))
{
}
-
+
break;
}
-
+
case ProcessLdtInformation:
case ProcessLdtSize:
case ProcessIoPortHandlers:
* PiQuerySystemProcessInformation
*
* DESCRIPTION
- * Compute the size of a process+thread snapshot as
+ * Compute the size of a process+thread snapshot as
* expected by NtQuerySystemInformation.
*
* RETURN VALUE
PEPROCESS CurrentP;
PLIST_ENTRY CurrentEntryT;
PETHREAD CurrentT;
-
+
ULONG RequiredSize = 0L;
BOOLEAN SizeOnly = FALSE;
ULONG SpiSize = 0L;
-
+
PSYSTEM_PROCESS_INFORMATION pInfoP = (PSYSTEM_PROCESS_INFORMATION) SnapshotBuffer;
PSYSTEM_PROCESS_INFORMATION pInfoPLast = NULL;
PSYSTEM_THREAD_INFO pInfoT = NULL;
-
+
/* Lock the process list. */
ExAcquireFastMutex(&PspActiveProcessMutex);
SizeOnly = TRUE;
continue;
}
- /*
- * Get a reference to the
+ /*
+ * Get a reference to the
* process descriptor we are
* handling.
*/
CurrentP = CONTAINING_RECORD(
CurrentEntryP,
- EPROCESS,
+ EPROCESS,
ProcessListEntry
);
/*
/* THREAD */
for ( pInfoT = & CurrentP->ThreadSysInfo [0],
CurrentEntryT = CurrentP->ThreadListHead.Flink;
-
+
(CurrentEntryT != & CurrentP->ThreadListHead);
-
+
pInfoT = & CurrentP->ThreadSysInfo [pInfoP->ThreadCount],
CurrentEntryT = CurrentEntryT->Flink
)
SizeOnly = TRUE;
continue;
}
- /*
- * Get a reference to the
+ /*
+ * Get a reference to the
* thread descriptor we are
* handling.
*/
CurrentT = CONTAINING_RECORD(
CurrentEntryT,
- KTHREAD,
+ KTHREAD,
ThreadListEntry
);
/*
pInfoT->State = CurrentT-> ; /* DWORD */
pInfoT->WaitReason = CurrentT-> ; /* KWAIT_REASON */
/*
- * Count the number of threads
+ * Count the number of threads
* this process has.
*/
++ pInfoP->ThreadCount;
*/
pInfoPLast = pInfoP;
/*
- * Compute the offset of the
+ * Compute the offset of the
* SYSTEM_PROCESS_INFORMATION
- * descriptor in the snapshot
+ * descriptor in the snapshot
* buffer for the next process.
*/
(ULONG) pInfoP += SpiSize;
* Mark the end of the snapshot.
*/
pInfoP->RelativeOffset = 0L;
- /* OK */
+ /* OK */
return STATUS_SUCCESS;
#endif
}
HANDLE Handle;
PVOID Address;
}u;
-
+
PAGED_CODE();
if (ThreadInformationClass <= MaxThreadInfoClass &&
}
KeSetPriorityThread(&Thread->Tcb, u.Priority);
break;
-
+
case ThreadBasePriority:
KeSetBasePriorityThread (&Thread->Tcb, u.Increment);
break;
-
+
case ThreadAffinityMask:
Status = KeSetAffinityThread(&Thread->Tcb, u.Affinity);
break;
-
+
case ThreadImpersonationToken:
Status = PsAssignImpersonationToken (Thread, u.Handle);
break;
-
+
case ThreadQuerySetWin32StartAddress:
Thread->Win32StartAddress = u.Address;
break;
LARGE_INTEGER Count;
BOOLEAN Last;
}u;
-
+
PAGED_CODE();
if (ThreadInformationClass <= MaxThreadInfoClass &&
{
case ThreadBasicInformation:
/* A test on W2K agains ntdll shows NtQueryInformationThread return STATUS_PENDING
- * as ExitStatus for current/running thread, while KETHREAD's ExitStatus is
+ * as ExitStatus for current/running thread, while KETHREAD's ExitStatus is
* 0. So do the conversion here:
* -Gunnar */
u.TBI.ExitStatus = (Thread->ExitStatus == 0) ? STATUS_PENDING : Thread->ExitStatus;
u.TBI.Priority = Thread->Tcb.Priority;
u.TBI.BasePriority = Thread->Tcb.BasePriority;
break;
-
+
case ThreadTimes:
u.TTI.KernelTime.QuadPart = Thread->Tcb.KernelTime * 100000LL;
u.TTI.UserTime.QuadPart = Thread->Tcb.UserTime * 100000LL;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/quota.c
* PURPOSE: Process Pool Quotas
- *
+ *
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
*/
Status = PsChargeProcessPoolQuota(Process, PoolType, Amount);
/* Raise Exception */
- if (!NT_SUCCESS(Status))
+ if (!NT_SUCCESS(Status))
{
ExRaiseStatus(Status);
}
NewUsageSize = QuotaBlock->QuotaEntry[PoolType].Usage + Amount;
/* Does this size respect the quota? */
- if (NewUsageSize > QuotaBlock->QuotaEntry[PoolType].Limit)
+ if (NewUsageSize > QuotaBlock->QuotaEntry[PoolType].Limit)
{
/* It doesn't, so keep raising the Quota */
- while (MiRaisePoolQuota(PoolType,
- QuotaBlock->QuotaEntry[PoolType].Limit,
- &NewMaxQuota))
+ while (MiRaisePoolQuota(PoolType,
+ QuotaBlock->QuotaEntry[PoolType].Limit,
+ &NewMaxQuota))
{
/* Save new Maximum Quota */
QuotaBlock->QuotaEntry[PoolType].Limit = NewMaxQuota;
QuotaBlock->QuotaEntry[PoolType].Usage = NewUsageSize;
/* Is this a new peak? */
- if (NewUsageSize > QuotaBlock->QuotaEntry[PoolType].Peak)
+ if (NewUsageSize > QuotaBlock->QuotaEntry[PoolType].Peak)
{
QuotaBlock->QuotaEntry[PoolType].Peak = NewUsageSize;
}
/*
* @unimplemented
- */
+ */
VOID
STDCALL
PsReturnPoolQuota(IN PEPROCESS Process,
IN ULONG_PTR Amount)
{
UNIMPLEMENTED;
-}
+}
/*
* @unimplemented
- */
+ */
VOID
STDCALL
PsReturnProcessNonPagedPoolQuota(IN PEPROCESS Process,
IN ULONG_PTR Amount)
{
UNIMPLEMENTED;
-}
+}
/*
* @unimplemented
- */
+ */
VOID
STDCALL
PsReturnProcessPagedPoolQuota(IN PEPROCESS Process,
{
/* Enter a Guarded Region */
KeEnterGuardedRegion();
-
+
/* Lock the Process */
- //ExAcquirePushLockShared(&Process->ProcessLock);
+ //ExAcquirePushLockShared(&Process->ProcessLock);
}
/* FIXME: Turn into Macro */
{
/* Unlock the Process */
//ExReleasePushLockShared(&Process->ProcessLock);
-
+
/* Leave Guarded Region */
KeLeaveGuardedRegion();
}
/*
* @implemented
*/
-NTSTATUS
-STDCALL
+NTSTATUS
+STDCALL
NtOpenProcessToken(IN HANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
OUT PHANDLE TokenHandle)
HANDLE hToken;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode == UserMode)
{
_SEH_TRY
_SEH_END;
}
}
-
+
return Status;
}
/*
* @implemented
*/
-PACCESS_TOKEN
+PACCESS_TOKEN
STDCALL
PsReferencePrimaryToken(PEPROCESS Process)
{
PACCESS_TOKEN Token;
-
+
/* Fast Reference the Token */
Token = ObFastReferenceObject(&Process->Token);
-
+
/* Check if we got the Token or if we got locked */
if (!Token)
{
/* Lock the Process */
PspLockProcessSecurityShared(Process);
-
+
/* Do a Locked Fast Reference */
//Token = ObFastReferenceObjectLocked(&Process->Token);
-
+
/* Unlock the Process */
PspUnlockProcessSecurityShared(Process);
}
-
+
/* Return the Token */
return Token;
}
{
PEPROCESS Process;
NTSTATUS Status;
-
+
/* Get the Token */
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_QUERY_INFORMATION,
ExGetPreviousMode(),
(PVOID*)&Process,
NULL);
-
+
/* Reference it */
if(NT_SUCCESS(Status)) {
-
+
*Token = PsReferencePrimaryToken(Process);
ObDereferenceObject(Process);
}
-
+
/* Return */
return Status;
}
PEPROCESS Parent OPTIONAL)
{
NTSTATUS Status = STATUS_SUCCESS;
-
+
/* If we have a parent, then duplicate the Token */
if (Parent) {
-
+
PTOKEN pNewToken;
PTOKEN pParentToken;
OBJECT_ATTRIBUTES ObjectAttributes;
0,
NULL,
NULL);
-
+
/* Duplicate the Token */
Status = SepDuplicateToken(pParentToken,
&ObjectAttributes,
pParentToken->ImpersonationLevel,
KernelMode,
&pNewToken);
-
+
if(!NT_SUCCESS(Status)) {
-
+
DPRINT1("Failed to Duplicate Token\n");
return Status;
}
-
+
/* Dereference the Token */
ObFastDereferenceObject(&Parent->Token, pParentToken);
-
+
/* Set the new Token */
ObInitializeFastReference(&Process->Token, pNewToken);
-
+
} else {
-
+
#ifdef SCHED_REWRITE
PTOKEN BootToken;
-
+
/* No parent, this is the Initial System Process. Assign Boot Token */
BootToken = SepCreateSystemProcessToken();
BootToken->TokenInUse = TRUE;
DPRINT1("PspInitializeProcessSecurity called with no parent.\n");
#endif
}
-
+
/* Return to caller */
return Status;
}
PACCESS_TOKEN Token;
PACCESS_TOKEN OldToken;
NTSTATUS Status;
-
+
/* Reference the Token */
Status = ObReferenceObjectByHandle(TokenHandle,
0,
return(Status);
}
-
+
/* Exchange them */
Status = SeExchangePrimaryToken(Process, Token, &OldToken);
-
+
/* Derefernece Tokens and Return */
ObDereferenceObject(Token);
return(Status);
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
PsAssignImpersonationToken(PETHREAD Thread,
HANDLE TokenHandle)
KeGetPreviousMode(),
(PVOID*)&Token,
NULL);
-
+
if (!NT_SUCCESS(Status)) {
-
+
return(Status);
}
-
+
ImpersonationLevel = SeTokenImpersonationLevel(Token);
-
+
} else {
-
+
Token = NULL;
ImpersonationLevel = 0;
}
FALSE,
FALSE,
ImpersonationLevel);
-
+
if (Token != NULL) ObDereferenceObject(Token);
return(STATUS_SUCCESS);
}
PsRevertThreadToSelf(IN PETHREAD Thread)
{
if (Thread->ActiveImpersonationInfo == TRUE) {
-
+
ObDereferenceObject (Thread->ImpersonationInfo->Token);
Thread->ActiveImpersonationInfo = FALSE;
}
/*
* @implemented
*/
-VOID
+VOID
STDCALL
PsImpersonateClient(IN PETHREAD Thread,
IN PACCESS_TOKEN Token,
IN BOOLEAN EffectiveOnly,
IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
{
-
+
if (Token == NULL) {
-
+
if (Thread->ActiveImpersonationInfo == TRUE) {
-
+
Thread->ActiveImpersonationInfo = FALSE;
-
+
if (Thread->ImpersonationInfo->Token != NULL) {
-
+
ObDereferenceObject (Thread->ImpersonationInfo->Token);
}
}
-
+
return;
}
if (Thread->ImpersonationInfo == NULL) {
-
+
Thread->ImpersonationInfo = ExAllocatePool(NonPagedPool,
sizeof(PS_IMPERSONATION_INFORMATION));
}
Thread->ImpersonationInfo->CopyOnOpen = CopyOnOpen;
Thread->ImpersonationInfo->EffectiveOnly = EffectiveOnly;
Thread->ImpersonationInfo->Token = Token;
-
+
ObReferenceObjectByPointer(Token,
0,
SepTokenObjectType,
KernelMode);
-
+
Thread->ActiveImpersonationInfo = TRUE;
}
{
PEPROCESS Process;
PACCESS_TOKEN Token;
-
- if (Thread->ActiveImpersonationInfo == FALSE)
- {
+
+ if (Thread->ActiveImpersonationInfo == FALSE)
+ {
Process = Thread->ThreadsProcess;
*TokenType = TokenPrimary;
*EffectiveOnly = FALSE;
-
+
/* Fast Reference the Token */
Token = ObFastReferenceObject(&Process->Token);
-
+
/* Check if we got the Token or if we got locked */
if (!Token)
{
/* Lock the Process */
PspLockProcessSecurityShared(Process);
-
+
/* Do a Locked Fast Reference */
//Token = ObFastReferenceObjectLocked(&Process->Token);
-
+
/* Unlock the Process */
PspUnlockProcessSecurityShared(Process);
- }
- }
- else
+ }
+ }
+ else
{
Token = Thread->ImpersonationInfo->Token;
*TokenType = TokenImpersonation;
*EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
*Level = Thread->ImpersonationInfo->ImpersonationLevel;
}
-
+
return Token;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtImpersonateThread(IN HANDLE ThreadHandle,
IN HANDLE ThreadToImpersonateHandle,
PETHREAD ThreadToImpersonate;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
/*
* @implemented
*/
-PACCESS_TOKEN
+PACCESS_TOKEN
STDCALL
PsReferenceImpersonationToken(IN PETHREAD Thread,
OUT PBOOLEAN CopyOnOpen,
OUT PBOOLEAN EffectiveOnly,
OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
{
-
+
if (Thread->ActiveImpersonationInfo == FALSE) {
-
+
return NULL;
}
*ImpersonationLevel = Thread->ImpersonationInfo->ImpersonationLevel;
*CopyOnOpen = Thread->ImpersonationInfo->CopyOnOpen;
*EffectiveOnly = Thread->ImpersonationInfo->EffectiveOnly;
-
+
ObReferenceObjectByPointer(Thread->ImpersonationInfo->Token,
TOKEN_ALL_ACCESS,
SepTokenObjectType,
PsDereferenceImpersonationToken(IN PACCESS_TOKEN ImpersonationToken)
{
if (ImpersonationToken) {
-
+
ObDereferenceObject(ImpersonationToken);
}
}
/*
* @implemented
- */
+ */
VOID
STDCALL
PsRestoreImpersonation(IN PETHREAD Thread,
IN PSE_IMPERSONATION_STATE ImpersonationState)
{
-
- PsImpersonateClient(Thread,
+
+ PsImpersonateClient(Thread,
ImpersonationState->Token,
ImpersonationState->CopyOnOpen,
ImpersonationState->EffectiveOnly,
ImpersonationState->Level);
-
+
ObfDereferenceObject(ImpersonationState->Token);
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/suspend.c
* PURPOSE: Thread managment
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
/*
* FUNCTION: Decrements a thread's resume count
- * ARGUMENTS:
+ * ARGUMENTS:
* ThreadHandle = Handle to the thread that should be resumed
* ResumeCount = The resulting resume count.
* RETURNS: Status
ULONG Prev;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
DPRINT("NtResumeThead(ThreadHandle %lx SuspendCount %p)\n",
ThreadHandle, SuspendCount);
-
+
/* Check buffer validity */
if(SuspendCount && PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(SuspendCount,
sizeof(ULONG),
sizeof(ULONG));
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status)) {
-
+
return Status;
}
-
+
/* Call the Kernel Function */
Prev = KeResumeThread(&Thread->Tcb);
-
- /* Return it */
+
+ /* Return it */
if(SuspendCount) {
-
+
_SEH_TRY {
-
+
*SuspendCount = Prev;
-
+
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
/*
* FUNCTION: Increments a thread's suspend count
- * ARGUMENTS:
+ * ARGUMENTS:
* ThreadHandle = Handle to the thread that should be resumed
* PreviousSuspendCount = The resulting/previous suspend count.
* REMARK:
- * A thread will be suspended if its suspend count is greater than 0.
- * This procedure maps to the win32 SuspendThread function. (
+ * A thread will be suspended if its suspend count is greater than 0.
+ * This procedure maps to the win32 SuspendThread function. (
* documentation about the the suspend count can be found here aswell )
- * The suspend count is not increased if it is greater than
+ * The suspend count is not increased if it is greater than
* MAXIMUM_SUSPEND_COUNT.
* RETURNS: Status
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtSuspendThread(IN HANDLE ThreadHandle,
IN PULONG PreviousSuspendCount OPTIONAL)
ULONG Prev;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
/* Check buffer validity */
if(PreviousSuspendCount && PreviousMode == UserMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(PreviousSuspendCount,
sizeof(ULONG),
sizeof(ULONG));
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
if(!NT_SUCCESS(Status)) return Status;
(PVOID*)&Thread,
NULL);
if (!NT_SUCCESS(Status)) {
-
+
return Status;
}
-
+
/* Call the Kernel Function */
Prev = KeSuspendThread(&Thread->Tcb);
-
- /* Return it */
+
+ /* Return it */
if(PreviousSuspendCount) {
-
+
_SEH_TRY {
-
+
*PreviousSuspendCount = Prev;
-
+
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
KPROCESSOR_MODE PreviousMode;
PEPROCESS Process;
NTSTATUS Status;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_SUSPEND_RESUME,
PsProcessType,
/* FIXME */
Status = STATUS_NOT_IMPLEMENTED;
DPRINT1("NtSuspendProcess not yet implemented!\n");
-
+
ObDereferenceObject(Process);
}
-
+
return Status;
}
/* FIXME */
Status = STATUS_NOT_IMPLEMENTED;
DPRINT1("NtResumeProcess not yet implemented!\n");
-
+
ObDereferenceObject(Process);
}
extern PEPROCESS PsIdleProcess;
POBJECT_TYPE EXPORTED PsThreadType = NULL;
-
+
/* FUNCTIONS ***************************************************************/
VOID
{
PKAPC ThreadApc;
PETHREAD Thread = PsGetCurrentThread();
-
+
DPRINT("I am a new USER thread. This is my start routine: %p. This my context: %p."
"This is my IRQL: %d. This is my Thread Pointer: %x.\n", StartRoutine,
StartContext, KeGetCurrentIrql(), Thread);
-
+
if (!Thread->Terminated) {
-
+
/* Allocate the APC */
ThreadApc = ExAllocatePoolWithTag(NonPagedPool, sizeof(KAPC), TAG('T', 'h', 'r','d'));
-
+
/* Initialize it */
KeInitializeApc(ThreadApc,
&Thread->Tcb,
LdrpGetSystemDllEntryPoint(),
UserMode,
NULL);
-
+
/* Insert it into the queue */
KeInsertQueueApc(ThreadApc, NULL, NULL, IO_NO_INCREMENT);
Thread->Tcb.ApcState.UserApcPending = TRUE;
}
-
+
/* Go to Passive Level and notify debugger */
KeLowerIrql(PASSIVE_LEVEL);
DbgkCreateThread(StartContext);
PVOID StartContext)
{
PETHREAD Thread = PsGetCurrentThread();
-
+
/* Unlock the dispatcher Database */
KeLowerIrql(PASSIVE_LEVEL);
-
+
/* Make sure it's not terminated by now */
if (!Thread->Terminated) {
-
+
/* Call it */
(StartRoutine)(StartContext);
}
-
+
/* Exit the thread */
PspExitThread(STATUS_SUCCESS);
}
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
NTSTATUS Status;
PVOID KernelStack;
-
+
/* Reference the Process by handle or pointer, depending on what we got */
DPRINT("PspCreateThread: %x, %x, %x\n", ProcessHandle, TargetProcess, ThreadContext);
if (ProcessHandle) {
-
+
/* Normal thread or System Thread */
DPRINT("Referencing Parent Process\n");
Status = ObReferenceObjectByHandle(ProcessHandle,
(PVOID*)&Process,
NULL);
} else {
-
+
/* System thread inside System Process, or Normal Thread with a bug */
if (StartRoutine) {
-
+
/* Reference the Process by Pointer */
DPRINT("Referencing Parent System Process\n");
ObReferenceObject(TargetProcess);
Process = TargetProcess;
Status = STATUS_SUCCESS;
-
+
} else {
-
+
/* Fake ObReference returning this */
Status = STATUS_INVALID_HANDLE;
}
}
-
+
/* Check for success */
if(!NT_SUCCESS(Status)) {
-
+
DPRINT1("Invalid Process Handle, or no handle given\n");
return(Status);
}
-
+
/* Create Thread Object */
DPRINT("Creating Thread Object\n");
Status = ObCreateObject(PreviousMode,
0,
0,
(PVOID*)&Thread);
-
+
/* Check for success */
if (!NT_SUCCESS(Status)) {
-
+
/* Dereference the Process */
DPRINT1("Failed to Create Thread Object\n");
ObDereferenceObject(Process);
return(Status);
}
-
+
/* Zero the Object entirely */
DPRINT("Cleaning Thread Object\n");
RtlZeroMemory(Thread, sizeof(ETHREAD));
-
+
/* Create Cid Handle */
DPRINT("Creating Thread Handle (CID)\n");
if (!(NT_SUCCESS(PsCreateCidHandle(Thread, PsThreadType, &Thread->Cid.UniqueThread)))) {
-
+
DPRINT1("Failed to create Thread Handle (CID)\n");
ObDereferenceObject(Process);
ObDereferenceObject(Thread);
return Status;
}
-
+
/* Initialize Lists */
DPRINT("Initialliazing Thread Lists and Locks\n");
InitializeListHead(&Thread->LpcReplyChain);
InitializeListHead(&Thread->IrpList);
InitializeListHead(&Thread->ActiveTimerListHead);
KeInitializeSpinLock(&Thread->ActiveTimerListLock);
-
+
/* Initialize LPC */
DPRINT("Initialliazing Thread Semaphore\n");
KeInitializeSemaphore(&Thread->LpcReplySemaphore, 0, LONG_MAX);
-
+
/* Allocate Stack for non-GUI Thread */
DPRINT("Initialliazing Thread Stack\n");
KernelStack = MmCreateKernelStack(FALSE);
-
+
/* Set the Process CID */
DPRINT("Initialliazing Thread PID and Parent Process\n");
Thread->Cid.UniqueProcess = Process->UniqueProcessId;
Thread->ThreadsProcess = Process;
-
+
/* Now let the kernel initialize the context */
if (ThreadContext) {
-
+
/* User-mode Thread */
-
+
/* Create Teb */
DPRINT("Initialliazing Thread PEB\n");
TebBase = MmCreateTeb(Process, &Thread->Cid, InitialTeb);
-
+
/* Set the Start Addresses */
DPRINT("Initialliazing Thread Start Addresses :%x, %x\n", ThreadContext->Eip, ThreadContext->Eax);
Thread->StartAddress = (PVOID)ThreadContext->Eip;
Thread->Win32StartAddress = (PVOID)ThreadContext->Eax;
-
+
/* Let the kernel intialize the Thread */
DPRINT("Initialliazing Kernel Thread\n");
- KeInitializeThread(&Process->Pcb,
- &Thread->Tcb,
+ KeInitializeThread(&Process->Pcb,
+ &Thread->Tcb,
PspUserThreadStartup,
NULL,
NULL,
ThreadContext,
TebBase,
- KernelStack);
-
+ KernelStack);
+
} else {
-
+
/* System Thread */
DPRINT("Initialliazing Thread Start Address :%x\n", StartRoutine);
Thread->StartAddress = StartRoutine;
Thread->SystemThread = TRUE;
-
+
/* Let the kernel intialize the Thread */
DPRINT("Initialliazing Kernel Thread\n");
- KeInitializeThread(&Process->Pcb,
- &Thread->Tcb,
+ KeInitializeThread(&Process->Pcb,
+ &Thread->Tcb,
PspSystemThreadStartup,
StartRoutine,
StartContext,
NULL,
NULL,
- KernelStack);
+ KernelStack);
}
- /*
- * Insert the Thread into the Process's Thread List
+ /*
+ * Insert the Thread into the Process's Thread List
* Note, this is the ETHREAD Thread List. It is removed in
* ps/kill.c!PspExitThread.
*/
DPRINT("Inserting into Process Thread List \n");
InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
-
+
/* Notify Thread Creation */
DPRINT("Running Thread Notify \n");
PspRunCreateThreadNotifyRoutines(Thread, TRUE);
-
+
/* FIXME: Use Lock */
DPRINT("Apcs Queueable: %d \n", Thread->Tcb.ApcQueueable);
Thread->Tcb.ApcQueueable = TRUE;
-
+
/* Suspend the Thread if we have to */
if (CreateSuspended) {
DPRINT("Suspending Thread\n");
KeSuspendThread(&Thread->Tcb);
}
-
+
/* Reference ourselves as a keep-alive */
ObReferenceObject(Thread);
-
+
/* Insert the Thread into the Object Manager */
DPRINT("Inserting Thread\n");
Status = ObInsertObject((PVOID)Thread,
0,
NULL,
&hThread);
-
+
/* Return Cid and Handle */
DPRINT("All worked great!\n");
if(NT_SUCCESS(Status)) {
-
+
_SEH_TRY {
-
+
if(ClientId != NULL) {
-
+
*ClientId = Thread->Cid;
}
*ThreadHandle = hThread;
-
+
} _SEH_HANDLE {
-
+
Status = _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
-
+
/* FIXME: SECURITY */
-
+
/* Dispatch thread */
DPRINT("About to dispatch the thread: %x!\n", &Thread->Tcb);
OldIrql = KeAcquireDispatcherDatabaseLock ();
KiUnblockThread(&Thread->Tcb, NULL, 0);
ObDereferenceObject(Thread);
KeReleaseDispatcherDatabaseLock(OldIrql);
-
+
/* Return */
DPRINT("Returning\n");
return Status;
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
PsCreateSystemThread(PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
PVOID StartContext)
{
PEPROCESS TargetProcess = NULL;
- HANDLE Handle = ProcessHandle;
-
+ HANDLE Handle = ProcessHandle;
+
/* Check if we have a handle. If not, use the System Process */
if (!ProcessHandle) {
-
+
Handle = NULL;
TargetProcess = PsInitialSystemProcess;
}
-
+
/* Call the shared function */
return PspCreateThread(ThreadHandle,
DesiredAccess,
/*
* @implemented
*/
-HANDLE
-STDCALL
+HANDLE
+STDCALL
PsGetCurrentThreadId(VOID)
{
return(PsGetCurrentThread()->Cid.UniqueThread);
/*
* @implemented
*/
-BOOLEAN
+BOOLEAN
STDCALL
PsIsThreadTerminating(IN PETHREAD Thread)
{
/*
* @implemented
- */
+ */
VOID
STDCALL
PsSetThreadHardErrorsAreDisabled(PETHREAD Thread,
/*
* @implemented
- */
+ */
VOID
STDCALL
PsSetThreadWin32Thread(PETHREAD Thread,
Thread->Tcb.Win32Thread = Win32Thread;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtCreateThread(OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN BOOLEAN CreateSuspended)
{
INITIAL_TEB SafeInitialTeb;
-
+
PAGED_CODE();
-
+
DPRINT("NtCreateThread(ThreadHandle %x, PCONTEXT %x)\n",
ThreadHandle,ThreadContext);
-
+
if(KeGetPreviousMode() != KernelMode) {
-
+
_SEH_TRY {
-
+
ProbeForWrite(ThreadHandle,
sizeof(HANDLE),
sizeof(ULONG));
-
+
if(ClientId != NULL) {
-
+
ProbeForWrite(ClientId,
sizeof(CLIENT_ID),
sizeof(ULONG));
}
-
+
if(ThreadContext != NULL) {
-
+
ProbeForRead(ThreadContext,
sizeof(CONTEXT),
sizeof(ULONG));
-
+
} else {
-
+
DPRINT1("No context for User-Mode Thread!!\n");
return STATUS_INVALID_PARAMETER;
}
-
+
ProbeForRead(InitialTeb,
sizeof(INITIAL_TEB),
sizeof(ULONG));
-
+
} _SEH_HANDLE {
-
+
return _SEH_GetExceptionCode();
-
+
} _SEH_END;
}
-
+
/* Use probed data for the Initial TEB */
SafeInitialTeb = *InitialTeb;
InitialTeb = &SafeInitialTeb;
-
+
/* Call the shared function */
return PspCreateThread(ThreadHandle,
DesiredAccess,
/*
* @implemented
*/
-NTSTATUS
+NTSTATUS
STDCALL
NtOpenThread(OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
ProbeForWrite(ThreadHandle,
sizeof(HANDLE),
sizeof(ULONG));
-
+
if(ClientId != NULL)
{
ProbeForRead(ClientId,
sizeof(CLIENT_ID),
sizeof(ULONG));
-
+
SafeClientId = *ClientId;
ClientId = &SafeClientId;
}
_SEH_HANDLE
{
Status = _SEH_GetExceptionCode();
- }
+ }
_SEH_END;
if(!NT_SUCCESS(Status)) return Status;
DesiredAccess,
NULL,
hThread);
-
+
if (Status != STATUS_SUCCESS)
{
DPRINT1("Could not open object by name\n");
}
-
+
/* Return Status */
return(Status);
}
Status = PsLookupProcessThreadByCid(ClientId,
NULL,
&Thread);
- }
- else
+ }
+ else
{
/* Get the Process */
DPRINT("Opening by Thread ID: %x\n", ClientId->UniqueThread);
Status = PsLookupThreadByThreadId(ClientId->UniqueThread,
&Thread);
}
-
+
if(!NT_SUCCESS(Status))
{
DPRINT1("Failure to find Thread\n");
return Status;
}
-
+
/* Open the Thread Object */
Status = ObOpenObjectByPointer(Thread,
ObjectAttributes->Attributes,
{
DPRINT1("Failure to open Thread\n");
}
-
+
/* Dereference the thread */
ObDereferenceObject(Thread);
}
return Status;
}
-NTSTATUS
+NTSTATUS
STDCALL
NtYieldExecution(VOID)
{
return(STATUS_SUCCESS);
}
-NTSTATUS
+NTSTATUS
STDCALL
NtTestAlert(VOID)
{
/*
* @implemented
*/
-KPROCESSOR_MODE
+KPROCESSOR_MODE
STDCALL
ExGetPreviousMode (VOID)
{
PspWin32ProcessSize = W32ProcessSize;
PspWin32ThreadSize = W32ThreadSize;
-
+
ExpWindowStationObjectCreate = W32ObjectCallback->WinStaCreate;
ExpWindowStationObjectParse = W32ObjectCallback->WinStaParse;
ExpWindowStationObjectDelete = W32ObjectCallback->WinStaDelete;
ULONG i, j;
PHYSICAL_ADDRESS BoundaryAddressMultiple;
PPFN_TYPE Pages = alloca(sizeof(PFN_TYPE) * (StackSize /PAGE_SIZE));
-
+
DPRINT1("PsAllocateCallbackStack\n");
BoundaryAddressMultiple.QuadPart = 0;
StackSize = PAGE_ROUND_UP(StackSize);
return(KernelStack);
}
-NTSTATUS
+NTSTATUS
STDCALL
NtW32Call(IN ULONG RoutineIndex,
IN PVOID Argument,
OUT PULONG ResultLength OPTIONAL)
{
NTSTATUS CallbackStatus;
-
+
DPRINT("NtW32Call(RoutineIndex %d, Argument %X, ArgumentLength %d)\n",
RoutineIndex, Argument, ArgumentLength);
-
+
/* FIXME: SEH!!! */
-
+
/* Call kernel function */
CallbackStatus = KeUserModeCallback(RoutineIndex,
Argument,
ArgumentLength,
Result,
ResultLength);
-
+
/* Return the result */
return(CallbackStatus);
-}
+}
#ifndef ALEX_CB_REWRITE
NTSTATUS STDCALL
PKTRAP_FRAME SavedTrapFrame;
PVOID SavedCallbackStack;
PVOID SavedExceptionStack;
-
+
PAGED_CODE();
Thread = PsGetCurrentThread();
/*
* Get the values that NtW32Call left on the inactive stack for us.
*/
- State = (PNTW32CALL_SAVED_STATE)OldStack[0];
+ State = (PNTW32CALL_SAVED_STATE)OldStack[0];
CallbackStatus = State->CallbackStatus;
CallerResultLength = State->CallerResultLength;
CallerResult = State->CallerResult;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/atom.c
* PURPOSE: Atom managment
- *
+ *
* PROGRAMMERS: No programmer listed.
*/
*PinCount = 1;
}
- Length = swprintf(TempAtomName, L"#%lu", (ULONG)Atom);
+ Length = swprintf(TempAtomName, L"#%lu", (ULONG)Atom);
if (NameLength != NULL)
{
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/capture.c
* PURPOSE: Helper routines for system calls.
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
{
UNICODE_STRING Src;
NTSTATUS Status = STATUS_SUCCESS;
-
+
ASSERT(Dest != NULL);
-
+
/*
* Copy the source string structure to kernel space.
*/
-
+
if(CurrentMode == UserMode)
{
RtlZeroMemory(&Src, sizeof(Src));
-
+
_SEH_TRY
{
ProbeForRead(UnsafeSrc,
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
/* capture the string even though it is considered to be valid */
Src = *UnsafeSrc;
}
-
+
/*
* Initialize the destination string.
*/
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
ExFreePool(Dest->Buffer);
Dest->MaximumLength = 0;
Dest->Buffer = NULL;
}
-
+
return Status;
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/ctype.c
* PURPOSE: Character type and conversion functions
- *
+ *
* PROGRAMMERS: Eric Kohl
*/
#undef __MSVCRT__
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/dbgprint.c
* PURPOSE: Debug output
- *
+ *
* PROGRAMMERS: Eric Kohl (ekohl@abo.rhein-zeitung.de)
*/
/*
* @implemented
*/
-ULONG
+ULONG
DbgPrint(PCH Format, ...)
{
ANSI_STRING DebugString;
/*
* @unimplemented
*/
-VOID
+VOID
STDCALL
DbgPrompt(PCH OutputString,
PCH InputString,
{
ANSI_STRING Output;
ANSI_STRING Input;
-
+
Input.Length = 0;
Input.MaximumLength = InputSize;
Input.Buffer = InputString;
-
+
Output.Length = strlen (OutputString);
Output.MaximumLength = Output.Length + 1;
Output.Buffer = OutputString;
NTSTATUS
STDCALL
DbgLoadImageSymbols(IN PUNICODE_STRING Name,
- IN ULONG Base,
+ IN ULONG Base,
IN ULONG Unknown3)
{
UNIMPLEMENTED;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/handle.c
* PURPOSE: Handle table
- *
+ *
* PROGRAMMERS: Eric Kohl <ekohl@rz-online.de>
*/
&Handle,
Index))
return FALSE;
-
+
/* clear handle */
memset(Handle, 0, sizeof(RTL_HANDLE));
-
+
/* add handle to free list */
Handle->Next = HandleTable->FirstFree;
HandleTable->FirstFree = Handle;
-
+
return TRUE;
}
KPROCESSOR_MODE
RtlpGetMode()
-{
- return KernelMode;
+{
+ return KernelMode;
}
/*
return ((PEPROCESS)(KeGetCurrentThread()->ApcState.Process))->Peb;
}
-NTSTATUS
+NTSTATUS
STDCALL
RtlDeleteCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection)
return STATUS_SUCCESS;
}
-BOOLEAN
+BOOLEAN
STDCALL
RtlTryEnterCriticalSection(
PRTL_CRITICAL_SECTION CriticalSection)
-/* $Id:$
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/misc.c
* PURPOSE: Various functions
- *
+ *
* PROGRAMMERS: Hartmut Birr
*/
/* FUNCTIONS *****************************************************************/
-VOID
+VOID
INIT_FUNCTION
STDCALL
RtlpInitNls(VOID)
{
ULONG_PTR BaseAddress;
-
- /* Import NLS Data */
+
+ /* Import NLS Data */
BaseAddress = CachedModules[AnsiCodepage]->ModStart;
RtlpImportAnsiCodePage((PUSHORT)BaseAddress,
CachedModules[AnsiCodepage]->ModEnd - BaseAddress);
-
+
BaseAddress = CachedModules[OemCodepage]->ModStart;
RtlpImportOemCodePage((PUSHORT)BaseAddress,
CachedModules[OemCodepage]->ModEnd - BaseAddress);
-
+
BaseAddress = CachedModules[UnicodeCasemap]->ModStart;
RtlpImportUnicodeCasemap((PUSHORT)BaseAddress,
CachedModules[UnicodeCasemap]->ModEnd - BaseAddress);
-
+
/* Create initial NLS tables */
RtlpCreateInitialNlsTables();
-
+
/* Create the NLS section */
- RtlpCreateNlsSection();
+ RtlpCreateNlsSection();
}
VOID INIT_FUNCTION
KEBUGCHECKEX(0x32, Status, 1, 3, 0);
}
- DPRINT("NlsSection: Base %p Size %lx\n",
+ DPRINT("NlsSection: Base %p Size %lx\n",
NlsSectionBase,
NlsSectionViewSize);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/purecall.c
* PURPOSE: No purpose listed.
- *
+ *
* PROGRAMMERS: Eric Kohl <ekohl@zr-online.de>
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/regio.c
* PURPOSE: Register io functions
- *
+ *
* PROGRAMMERS: Eric Kohl (ekohl@abo.rhein-zeitung.de)
*/
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/sprintf.c
* PURPOSE: Single byte sprintf functions
- *
+ *
* PROGRAMMERS: David Welch
* Eric Kohl
*/
return buf;
}
-static char*
+static char*
string(char* buf, char* end, const char* s, int len, int field_width, int precision, int flags)
{
int i;
return buf;
}
-static char*
+static char*
stringw(char* buf, char* end, const wchar_t* sw, int len, int field_width, int precision, int flags)
{
int i;
if (!(flags & LEFT))
while (len < field_width--)
{
- if (buf <= end)
+ if (buf <= end)
*buf = ' ';
++buf;
}
else if (cnt > 0)
/* don't write out a null byte if the buf size is zero */
*end = '\0';
-
+
return str-buf;
}
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/stdlib.c
* PURPOSE: Standard library functions
- *
+ *
* PROGRAMMERS: Eric Kohl (ekohl@abo.rhein-zeitung.de)
*/
/*
- * NOTE: no error
+ * NOTE: no error
*
* @implemented
*/
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/string.c
* PURPOSE: Ascii string functions
- *
+ *
* PROGRAMMERS: Eric Kohl (ekohl@abo.rhein-zeitung.de)
*/
*szToFill = szFill;
szToFill++;
i++;
-
+
}
return t;
}
/*
* @implemented
*/
-char * _strrev(char *s)
+char * _strrev(char *s)
{
char *e;
char a;
{
*szToFill = szFill;
szToFill++;
-
+
}
return t;
}
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/strtok.c
* PURPOSE: Unicode and thread safe implementation of strtok
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
int c, sc;
char *tok;
static char *last;
-
+
if (s == NULL && (s = last) == NULL)
return (NULL);
PWSTR string;
PWSTR sep;
PWSTR start;
-
+
if (_string!=NULL)
{
string = _string->Buffer;
{
string = *temp;
}
-
+
start = string;
-
+
while ((*string)!=0)
{
sep = _sep;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/swprintf.c
* PURPOSE: Unicode sprintf functions
- *
+ *
* PROGRAMMERS: David Welch
* Eric Kohl
*/
return buf;
}
-static wchar_t*
+static wchar_t*
stringw(wchar_t* buf, wchar_t* end, const wchar_t* sw, int len, int field_width, int precision, int flags)
{
int i;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/rtl/wstring.c
* PURPOSE: Wide string functions
- *
+ *
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
s=(wchar_t *)str;
do {
t=(wchar_t *)reject;
- while (*t) {
- if (*t==*s)
+ while (*t) {
+ if (*t==*s)
break;
t++;
}
- if (*t)
+ if (*t)
break;
s++;
} while (*s);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/acl.c
* PURPOSE: Security manager
- *
+ *
* PROGRAMMERS: David Welch <welch@cwcom.net>
*/
return(TRUE);
}
-NTSTATUS STDCALL
-SepCreateImpersonationTokenDacl(PTOKEN Token,
+NTSTATUS STDCALL
+SepCreateImpersonationTokenDacl(PTOKEN Token,
PTOKEN PrimaryToken,
PACL *Dacl)
{
ULONG AclLength;
PVOID TokenDacl;
-
+
PAGED_CODE();
AclLength = sizeof(ACL) +
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/audit.c
* PURPOSE: Audit functions
- *
+ *
* PROGRAMMERS: Eric Kohl <eric.kohl@t-online.de>
*/
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/lsa.c
NTSTATUS STDCALL LsaFreeReturnBuffer (PVOID Buffer)
{
ULONG Size = 0; /* required by MEM_RELEASE */
-
+
return ZwFreeVirtualMemory (
NtCurrentProcess(),
& Buffer,
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/luid.c
* PURPOSE: Security manager
- *
+ *
* PROGRAMMERS: No programmer listed.
*/
SepInitLuid(VOID)
{
LUID DummyLuidValue = SYSTEM_LUID;
-
+
LuidValue.u.HighPart = DummyLuidValue.HighPart;
LuidValue.u.LowPart = DummyLuidValue.LowPart;
LuidIncrement.QuadPart = 1;
ExpAllocateLocallyUniqueId(OUT LUID *LocallyUniqueId)
{
LARGE_INTEGER NewLuid, PrevLuid;
-
+
/* atomically increment the luid */
do
{
LocallyUniqueId->LowPart = NewLuid.u.LowPart;
LocallyUniqueId->HighPart = NewLuid.u.HighPart;
-
+
return STATUS_SUCCESS;
}
LUID NewLuid;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/priv.c
* PURPOSE: Security manager
- *
+ *
* PROGRAMMERS: No programmer listed.
*/
ULONG k;
DPRINT ("SepPrivilegeCheck() called\n");
-
+
PAGED_CODE();
if (PreviousMode == KernelMode)
{
PLUID_AND_ATTRIBUTES* NewMem;
ULONG SrcLength;
-
+
PAGED_CODE();
if (PrivilegeCount == 0)
ULONG a)
{
PAGED_CODE();
-
+
ExFreePool (Privilege);
}
ULONG PrivilegeControl;
ULONG Length;
NTSTATUS Status;
-
+
PAGED_CODE();
Status = ObReferenceObjectByHandle (ClientToken,
KPROCESSOR_MODE PreviousMode)
{
PACCESS_TOKEN Token = NULL;
-
+
PAGED_CODE();
if (SubjectContext->ClientToken == NULL)
SECURITY_SUBJECT_CONTEXT SubjectContext;
PRIVILEGE_SET Priv;
BOOLEAN Result;
-
+
PAGED_CODE();
SeCaptureSubjectContext (&SubjectContext);
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/sd.c
* PURPOSE: Security manager
- *
+ *
* PROGRAMMERS: David Welch <welch@cwcom.net>
*/
ULONG SaclSize = 0, DaclSize = 0;
ULONG DescriptorSize = 0;
NTSTATUS Status = STATUS_SUCCESS;
-
+
if(OriginalSecurityDescriptor != NULL)
{
if(CurrentMode != KernelMode)
{
RtlZeroMemory(&DescriptorCopy, sizeof(DescriptorCopy));
-
+
_SEH_TRY
{
/* first only probe and copy until the control field of the descriptor
Status = STATUS_UNKNOWN_REVISION;
_SEH_LEAVE;
}
-
+
/* make a copy on the stack */
DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
if(DescriptorCopy.Control & SE_SELF_RELATIVE)
{
PSECURITY_DESCRIPTOR_RELATIVE RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)OriginalSecurityDescriptor;
-
+
DescriptorCopy.Owner = (PSID)RelSD->Owner;
DescriptorCopy.Group = (PSID)RelSD->Group;
DescriptorCopy.Sacl = (PACL)RelSD->Sacl;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
{
return STATUS_UNKNOWN_REVISION;
}
-
+
*CapturedSecurityDescriptor = OriginalSecurityDescriptor;
return STATUS_SUCCESS;
}
{
return STATUS_UNKNOWN_REVISION;
}
-
+
/* make a copy on the stack */
DescriptorCopy.Revision = OriginalSecurityDescriptor->Revision;
DescriptorCopy.Sbz1 = OriginalSecurityDescriptor->Sbz1;
DescriptorCopy.Dacl = OriginalSecurityDescriptor->Dacl;
}
}
-
+
if(DescriptorCopy.Control & SE_SELF_RELATIVE)
{
/* in case we're dealing with a self-relative descriptor, do a basic convert
DescriptorCopy.Sacl = (PACL)((ULONG_PTR)OriginalSecurityDescriptor + (ULONG_PTR)DescriptorCopy.Sacl);
}
}
-
+
/* determine the size of the SIDs */
#define DetermineSIDSize(SidType) \
do { \
} \
} \
} while(0)
-
+
DetermineSIDSize(Owner);
DetermineSIDSize(Group);
-
+
/* determine the size of the ACLs */
#define DetermineACLSize(AclType, AclFlag) \
do { \
DescriptorCopy.AclType = NULL; \
} \
} while(0)
-
+
DetermineACLSize(Sacl, SACL);
DetermineACLSize(Dacl, DACL);
-
+
/* allocate enough memory to store a complete copy of a self-relative
security descriptor */
NewDescriptor = ExAllocatePool(PoolType,
if(NewDescriptor != NULL)
{
ULONG_PTR Offset = sizeof(SECURITY_DESCRIPTOR);
-
+
NewDescriptor->Revision = DescriptorCopy.Revision;
NewDescriptor->Sbz1 = DescriptorCopy.Sbz1;
NewDescriptor->Control = DescriptorCopy.Control | SE_SELF_RELATIVE;
-
+
_SEH_TRY
{
/* setup the offsets and copy the SIDs and ACLs to the new
Offset += ROUND_UP(Type##Size, sizeof(ULONG)); \
} \
} while(0)
-
+
CopySIDOrACL(Owner);
CopySIDOrACL(Group);
CopySIDOrACL(Sacl);
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(NT_SUCCESS(Status))
{
/* we're finally done! copy the pointer to the captured descriptor to
/* nothing to do... */
*CapturedSecurityDescriptor = NULL;
}
-
+
return Status;
}
ULONG Control = 0;
ULONG_PTR Current;
ULONG SdLength;
-
+
RelSD = (PSECURITY_DESCRIPTOR_RELATIVE)SecurityDescriptor;
if (*ObjectsSecurityDescriptor == NULL)
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/semgr.c
* PURPOSE: Security manager
- *
+ *
* PROGRAMMERS: No programmer listed.
*/
PETHREAD Thread;
BOOLEAN CopyOnOpen;
BOOLEAN EffectiveOnly;
-
+
PAGED_CODE();
Thread = PsGetCurrentThread();
else
{
SubjectContext->ProcessAuditId = Thread->ThreadsProcess;
- SubjectContext->ClientToken =
+ SubjectContext->ClientToken =
PsReferenceImpersonationToken(Thread,
&CopyOnOpen,
&EffectiveOnly,
SeLockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
PAGED_CODE();
-
+
KeEnterCriticalRegion();
ExAcquireResourceExclusiveLite(&SepSubjectContextLock, TRUE);
}
SeUnlockSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
PAGED_CODE();
-
+
ExReleaseResourceLite(&SepSubjectContextLock);
KeLeaveCriticalRegion();
}
SeReleaseSubjectContext(IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
{
PAGED_CODE();
-
+
if (SubjectContext->PrimaryToken != NULL)
{
ObDereferenceObject(SubjectContext->PrimaryToken);
SeDeassignSecurity(PSECURITY_DESCRIPTOR *SecurityDescriptor)
{
PAGED_CODE();
-
+
if (*SecurityDescriptor != NULL)
{
ExFreePool(*SecurityDescriptor);
/*
* FUNCTION: Creates a security descriptor for a new object.
* ARGUMENTS:
- * ParentDescriptor =
- * ExplicitDescriptor =
- * NewDescriptor =
- * IsDirectoryObject =
- * SubjectContext =
- * GeneralMapping =
- * PoolType =
+ * ParentDescriptor =
+ * ExplicitDescriptor =
+ * NewDescriptor =
+ * IsDirectoryObject =
+ * SubjectContext =
+ * GeneralMapping =
+ * PoolType =
* RETURNS: Status
*
* @implemented
PSID Group = NULL;
PACL Dacl = NULL;
PACL Sacl = NULL;
-
+
PAGED_CODE();
/* Lock subject context */
/* Allocate and initialize the new security descriptor */
- Length = sizeof(SECURITY_DESCRIPTOR) +
+ Length = sizeof(SECURITY_DESCRIPTOR) +
OwnerLength + GroupLength + DaclLength + SaclLength;
- DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
+ DPRINT("L: sizeof(SECURITY_DESCRIPTOR) %d OwnerLength %d GroupLength %d DaclLength %d SaclLength %d\n",
sizeof(SECURITY_DESCRIPTOR),
OwnerLength,
GroupLength,
{
ULONG i;
PTOKEN Token = (PTOKEN)_Token;
-
+
PAGED_CODE();
if (Token->UserAndGroupCount == 0)
PACE CurrentAce;
PSID Sid;
NTSTATUS Status;
-
+
PAGED_CODE();
CurrentAccess = PreviouslyGrantedAccess;
KPROCESSOR_MODE PreviousMode;
PTOKEN Token;
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT("NtAccessCheck() called\n");
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/sid.c
* PURPOSE: Security manager
- *
+ *
* PROGRAMMERS: David Welch <welch@cwcom.net>
*/
ULONG SidSize = 0;
PISID NewSid, Sid = (PISID)InputSid;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
if(AccessMode != KernelMode)
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(NT_SUCCESS(Status))
{
/* allocate a SID and copy it */
IN BOOLEAN CaptureIfKernel)
{
PAGED_CODE();
-
+
if(CapturedSid != NULL &&
(AccessMode == UserMode ||
(AccessMode == KernelMode && CaptureIfKernel)))
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/se/token.c
* PURPOSE: Security manager
- *
+ *
* PROGRAMMERS: David Welch <welch@cwcom.net>
*/
return(STATUS_NOT_IMPLEMENTED);
}
-NTSTATUS
+NTSTATUS
SeExchangePrimaryToken(PEPROCESS Process,
PACCESS_TOKEN NewTokenP,
PACCESS_TOKEN* OldTokenP)
{
PTOKEN OldToken;
PTOKEN NewToken = (PTOKEN)NewTokenP;
-
+
PAGED_CODE();
-
+
if (NewToken->TokenType != TokenPrimary) return(STATUS_BAD_TOKEN_TYPE);
if (NewToken->TokenInUse) return(STATUS_TOKEN_ALREADY_IN_USE);
-
+
/* Mark new token in use */
NewToken->TokenInUse = 1;
-
+
/* Reference the New Token */
ObReferenceObject(NewToken);
-
+
/* Replace the old with the new */
OldToken = ObFastReplaceObject(&Process->Token, NewToken);
-
+
/* Mark the Old Token as free */
OldToken->TokenInUse = 0;
-
+
*OldTokenP = (PACCESS_TOKEN)OldToken;
return STATUS_SUCCESS;
}
SeDeassignPrimaryToken(PEPROCESS Process)
{
PTOKEN OldToken;
-
+
/* Remove the Token */
OldToken = ObFastReplaceObject(&Process->Token, NULL);
-
+
/* Mark the Old Token as free */
OldToken->TokenInUse = 0;
}
{
ULONG i;
ULONG uLength;
-
+
PAGED_CODE();
uLength = Count * sizeof(SID_AND_ATTRIBUTES);
PVOID EndMem;
PTOKEN AccessToken;
NTSTATUS Status;
-
+
PAGED_CODE();
Status = ObCreateObject(PreviousMode,
for (i = 0; i < Token->UserAndGroupCount; i++)
uLength += RtlLengthSid(Token->UserAndGroups[i].Sid);
- AccessToken->UserAndGroups =
+ AccessToken->UserAndGroups =
(PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
uLength,
TAG('T', 'O', 'K', 'u'));
{
RtlCopyLuid(&AccessToken->Privileges[i].Luid,
&Token->Privileges[i].Luid);
- AccessToken->Privileges[i].Attributes =
+ AccessToken->Privileges[i].Attributes =
Token->Privileges[i].Attributes;
}
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
-
+
PAGED_CODE();
-
+
InitializeObjectAttributes(&ObjectAttributes,
NULL,
0,
Level,
PreviousMode,
(PTOKEN*)NewToken);
-
+
return(Status);
}
PACCESS_TOKEN Token;
ULONG g;
PACCESS_TOKEN NewToken;
-
+
PAGED_CODE();
-
+
Token = PsReferenceEffectiveToken(Thread,
&TokenType,
&b,
ClientContext->DirectAccessEffectiveOnly = FALSE;
}
}
-
+
if (Qos->ContextTrackingMode == 0)
{
ClientContext->DirectlyAccessClientToken = FALSE;
IN PETHREAD ServerThread OPTIONAL)
{
UCHAR b;
-
+
PAGED_CODE();
-
+
if (ClientContext->DirectlyAccessClientToken == FALSE)
{
b = ClientContext->SecurityQos.EffectiveOnly;
ULONG RequiredLength;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
/* Check buffers and class validity */
DefaultQueryInfoBufferCheck(TokenInformationClass,
SeTokenInformationClass,
case TokenUser:
{
PTOKEN_USER tu = (PTOKEN_USER)TokenInformation;
-
+
DPRINT("NtQueryInformationToken(TokenUser)\n");
RequiredLength = sizeof(TOKEN_USER) +
RtlLengthSid(Token->UserAndGroups[0].Sid);
{
Status = STATUS_BUFFER_TOO_SMALL;
}
-
+
if(ReturnLength != NULL)
{
*ReturnLength = RequiredLength;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
break;
}
-
+
case TokenGroups:
{
PTOKEN_GROUPS tg = (PTOKEN_GROUPS)TokenInformation;
-
+
DPRINT("NtQueryInformationToken(TokenGroups)\n");
RequiredLength = sizeof(tg->GroupCount) +
RtlLengthSidAndAttributes(Token->UserAndGroupCount - 1, &Token->UserAndGroups[1]);
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
break;
}
-
+
case TokenPrivileges:
{
PTOKEN_PRIVILEGES tp = (PTOKEN_PRIVILEGES)TokenInformation;
-
+
DPRINT("NtQueryInformationToken(TokenPrivileges)\n");
RequiredLength = sizeof(tp->PrivilegeCount) +
(Token->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
{
Status = STATUS_BUFFER_TOO_SMALL;
}
-
+
if(ReturnLength != NULL)
{
*ReturnLength = RequiredLength;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
break;
}
-
+
case TokenOwner:
{
ULONG SidLen;
PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
-
+
DPRINT("NtQueryInformationToken(TokenOwner)\n");
SidLen = RtlLengthSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid);
RequiredLength = sizeof(TOKEN_OWNER) + SidLen;
{
Status = STATUS_BUFFER_TOO_SMALL;
}
-
+
if(ReturnLength != NULL)
{
*ReturnLength = RequiredLength;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
break;
}
-
+
case TokenPrimaryGroup:
{
ULONG SidLen;
break;
}
-
+
case TokenDefaultDacl:
{
PTOKEN_DEFAULT_DACL tdd = (PTOKEN_DEFAULT_DACL)TokenInformation;
DPRINT("NtQueryInformationToken(TokenDefaultDacl)\n");
RequiredLength = sizeof(TOKEN_DEFAULT_DACL);
-
+
if(Token->DefaultDacl != NULL)
{
RequiredLength += Token->DefaultDacl->AclSize;
break;
}
-
+
case TokenSource:
{
PTOKEN_SOURCE ts = (PTOKEN_SOURCE)TokenInformation;
break;
}
-
+
case TokenType:
{
PTOKEN_TYPE tt = (PTOKEN_TYPE)TokenInformation;
break;
}
-
+
case TokenImpersonationLevel:
{
PSECURITY_IMPERSONATION_LEVEL sil = (PSECURITY_IMPERSONATION_LEVEL)TokenInformation;
break;
}
-
+
case TokenStatistics:
{
PTOKEN_STATISTICS ts = (PTOKEN_STATISTICS)TokenInformation;
break;
}
-
+
case TokenOrigin:
{
PTOKEN_ORIGIN to = (PTOKEN_ORIGIN)TokenInformation;
ULONG SessionId = 0;
DPRINT("NtQueryInformationToken(TokenSessionId)\n");
-
+
Status = SeQuerySessionIdToken(Token,
&SessionId);
}
_SEH_END;
}
-
+
break;
}
KPROCESSOR_MODE PreviousMode;
ULONG NeededAccess = TOKEN_ADJUST_DEFAULT;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
DefaultSetInfoBufferCheck(TokenInformationClass,
SeTokenInformationClass,
TokenInformation,
DPRINT("NtSetInformationToken() failed, Status: 0x%x\n", Status);
return Status;
}
-
+
if(TokenInformationClass == TokenSessionId)
{
NeededAccess |= TOKEN_ADJUST_SESSIONID;
{
PTOKEN_OWNER to = (PTOKEN_OWNER)TokenInformation;
PSID InputSid = NULL;
-
+
_SEH_TRY
{
InputSid = to->Owner;
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(NT_SUCCESS(Status))
{
PSID CapturedSid;
-
+
Status = SepCaptureSid(InputSid,
PreviousMode,
PagedPool,
}
break;
}
-
+
case TokenPrimaryGroup:
{
if(TokenInformationLength >= sizeof(TOKEN_PRIMARY_GROUP))
}
break;
}
-
+
case TokenDefaultDacl:
{
if(TokenInformationLength >= sizeof(TOKEN_DEFAULT_DACL))
{
ExFreePool(Token->DefaultDacl);
}
-
+
/* set the new dacl */
Token->DefaultDacl = CapturedAcl;
}
}
break;
}
-
+
case TokenSessionId:
{
ULONG SessionId = 0;
PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService;
BOOLEAN QoSPresent;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
PreviousMode = KeGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
return Status;
}
}
-
+
Status = SepCaptureSecurityQualityOfService(ObjectAttributes,
PreviousMode,
PagedPool,
DPRINT1("NtDuplicateToken() failed to capture QoS! Status: 0x%x\n", Status);
return Status;
}
-
+
Status = ObReferenceObjectByHandle(ExistingTokenHandle,
TOKEN_DUPLICATE,
SepTokenObjectType,
}
}
}
-
+
/* free the captured structure */
SepReleaseSecurityQualityOfService(CapturedSecurityQualityOfService,
PreviousMode,
ULONG a;
ULONG b;
ULONG c;
-
+
PAGED_CODE();
-
+
Status = ObReferenceObjectByHandle(TokenHandle,
?,
SepTokenObjectType,
UserMode,
(PVOID*)&Token,
NULL);
-
-
+
+
SepAdjustGroups(Token,
0,
ResetToDefault,
ULONG c;
#endif
NTSTATUS Status;
-
+
PAGED_CODE();
DPRINT ("NtAdjustPrivilegesToken() called\n");
/* Update current privlege */
Token->Privileges[i].Attributes &= ~SE_PRIVILEGE_ENABLED;
- Token->Privileges[i].Attributes |=
+ Token->Privileges[i].Attributes |=
(NewState->Privileges[j].Attributes & SE_PRIVILEGE_ENABLED);
DPRINT ("New attributes %lx\n",
Token->Privileges[i].Attributes);
NTSTATUS Status;
ULONG uSize;
ULONG i;
-
+
PAGED_CODE();
ULONG uLocalSystemLength = RtlLengthSid(SeLocalSystemSid);
uSize += uAuthUserLength;
uSize += uAdminsLength;
- AccessToken->UserAndGroups =
+ AccessToken->UserAndGroups =
(PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(NonPagedPool,
uSize,
TAG('T', 'O', 'K', 'u'));
AccessToken->Privileges[i].Attributes = 0;
AccessToken->Privileges[i++].Luid = SeTakeOwnershipPrivilege;
-
+
AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
AccessToken->Privileges[i++].Luid = SeCreatePagefilePrivilege;
-
+
AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
AccessToken->Privileges[i++].Luid = SeLockMemoryPrivilege;
-
+
AccessToken->Privileges[i].Attributes = 0;
AccessToken->Privileges[i++].Luid = SeAssignPrimaryTokenPrivilege;
-
+
AccessToken->Privileges[i].Attributes = 0;
AccessToken->Privileges[i++].Luid = SeIncreaseQuotaPrivilege;
-
+
AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
AccessToken->Privileges[i++].Luid = SeIncreaseBasePriorityPrivilege;
-
+
AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
AccessToken->Privileges[i++].Luid = SeCreatePermanentPrivilege;
-
+
AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
AccessToken->Privileges[i++].Luid = SeDebugPrivilege;
-
+
AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
AccessToken->Privileges[i++].Luid = SeAuditPrivilege;
-
+
AccessToken->Privileges[i].Attributes = 0;
AccessToken->Privileges[i++].Luid = SeSecurityPrivilege;
-
+
AccessToken->Privileges[i].Attributes = 0;
AccessToken->Privileges[i++].Luid = SeSystemEnvironmentPrivilege;
-
+
AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
AccessToken->Privileges[i++].Luid = SeChangeNotifyPrivilege;
-
+
AccessToken->Privileges[i].Attributes = 0;
AccessToken->Privileges[i++].Luid = SeBackupPrivilege;
-
+
AccessToken->Privileges[i].Attributes = 0;
AccessToken->Privileges[i++].Luid = SeRestorePrivilege;
-
+
AccessToken->Privileges[i].Attributes = 0;
AccessToken->Privileges[i++].Luid = SeShutdownPrivilege;
-
+
AccessToken->Privileges[i].Attributes = 0;
AccessToken->Privileges[i++].Luid = SeLoadDriverPrivilege;
-
+
AccessToken->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED_BY_DEFAULT|SE_PRIVILEGE_ENABLED;
AccessToken->Privileges[i++].Luid = SeProfileSingleProcessPrivilege;
-
+
AccessToken->Privileges[i].Attributes = 0;
AccessToken->Privileges[i++].Luid = SeSystemtimePrivilege;
#if 0
ULONG i;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
for (i = 0; i < TokenGroups->GroupCount; i++)
uLength += RtlLengthSid(TokenGroups->Groups[i].Sid);
- AccessToken->UserAndGroups =
+ AccessToken->UserAndGroups =
(PSID_AND_ATTRIBUTES)ExAllocatePoolWithTag(PagedPool,
uLength,
TAG('T', 'O', 'K', 'u'));
if (NT_SUCCESS(Status))
{
Status = SepFindPrimaryGroupAndDefaultOwner(
- AccessToken,
+ AccessToken,
TokenPrimaryGroup->PrimaryGroup,
TokenOwner->Owner);
}
OUT PLUID LogonId)
{
PAGED_CODE();
-
+
*LogonId = ((PTOKEN)Token)->AuthenticationId;
return STATUS_SUCCESS;
SeTokenImpersonationLevel(IN PACCESS_TOKEN Token)
{
PAGED_CODE();
-
+
return ((PTOKEN)Token)->ImpersonationLevel;
}
SeTokenType(IN PACCESS_TOKEN Token)
{
PAGED_CODE();
-
+
return ((PTOKEN)Token)->TokenType;
}
PACL Dacl = NULL;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status = STATUS_SUCCESS;
-
+
PAGED_CODE();
-
+
PreviousMode = ExGetPreviousMode();
-
+
if(PreviousMode != KernelMode)
{
_SEH_TRY
Status = _SEH_GetExceptionCode();
}
_SEH_END;
-
+
if(!NT_SUCCESS(Status))
{
return Status;
}
return Status;
}
-
+
PrimaryToken = PsReferencePrimaryToken(Thread->ThreadsProcess);
Status = SepCreateImpersonationTokenDacl(Token, PrimaryToken, &Dacl);
ObfDereferenceObject(PrimaryToken);
}
return Status;
}
-
+
RtlCreateSecurityDescriptor(&SecurityDescriptor,
SECURITY_DESCRIPTOR_REVISION);
RtlSetDaclSecurityDescriptor(&SecurityDescriptor, TRUE, Dacl,
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/tests/setup.c
-/* $Id:$
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/tests/tests/VirtualMemory.c