Leaked source code of windows server 2003
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*++
Copyright (c) 1991 Microsoft Corporation
Module Name:
gdtsup.c
Abstract:
This module implements interfaces that support manipulation of i386 GDTs. These entry points only exist on i386 machines.
Author:
Dave Hastings (daveh) 28 May 1991
Environment:
Kernel mode only.
Revision History:
--*/
#include "ki.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGELK, KeI386SetGdtSelector)
#pragma alloc_text(PAGE, Ke386GetGdtEntryThread)
#endif
VOID Ke386GetGdtEntryThread( IN PKTHREAD Thread, IN ULONG Offset, IN PKGDTENTRY Descriptor ) /*++
Routine Description:
This routine returns the contents of an entry in the GDT. If the entry is thread specific, the entry for the specified thread is created and returned (KGDT_LDT, and KGDT_R3_TEB). If the selector is processor dependent, the entry for the current processor is returned (KGDT_R0_PCR).
Arguments:
Thread -- Supplies a pointer to the thread to return the entry for.
Offset -- Supplies the offset in the Gdt. This value must be 0 mod 8.
Descriptor -- Returns the contents of the Gdt descriptor
Return Value:
None.
--*/
{ PKGDTENTRY Gdt; PKPROCESS Process;
//
// If the entry is out of range, don't return anything
//
if (Offset >= KGDT_NUMBER * sizeof(KGDTENTRY)) { return ; }
if (Offset == KGDT_LDT) {
//
// Materialize Ldt selector
//
Process = Thread->Process; RtlCopyMemory( Descriptor, &(Process->LdtDescriptor), sizeof(KGDTENTRY) );
} else {
//
// Copy Selector from Ldt
//
// N.B. We will change the base later, if it is KGDT_R3_TEB
//
Gdt = KiPcr()->GDT;
RtlCopyMemory(Descriptor, (PCHAR)Gdt + Offset, sizeof(KGDTENTRY));
//
// if it is the TEB selector, fix the base
//
if (Offset == KGDT_R3_TEB) { Descriptor->BaseLow = (USHORT)((ULONG)(Thread->Teb) & 0xFFFF); Descriptor->HighWord.Bytes.BaseMid = (UCHAR) ( ( (ULONG)(Thread->Teb) & 0xFF0000L) >> 16); Descriptor->HighWord.Bytes.BaseHi = (CHAR) ( ( (ULONG)(Thread->Teb) & 0xFF000000L) >> 24); } }
return ; }
NTSTATUS KeI386SetGdtSelector ( ULONG Selector, PKGDTENTRY GdtValue ) /*++
Routine Description:
Sets a GDT entry obtained via KeI386AllocateGdtSelectors to the supplied GdtValue.
Arguments:
Selector - Which GDT to set
GdtValue - GDT value to set into GDT
Return Value:
status code
--*/ { KAFFINITY TargetSet; PKPRCB Prcb; PKPCR Pcr; PKGDTENTRY GdtEntry; ULONG GdtIndex, BitNumber;
PAGED_CODE ();
//
// Verify GDT entry passed, and it's above the kernel GDT values
//
GdtIndex = Selector >> 3; if ((Selector & 0x7) != 0 || GdtIndex < KGDT_NUMBER) { return STATUS_UNSUCCESSFUL; }
//
// Set GDT entry in each processor's GDT
//
TargetSet = KeActiveProcessors; while (TargetSet != 0) { KeFindFirstSetLeftAffinity(TargetSet, &BitNumber); ClearMember(BitNumber, TargetSet);
Prcb = KiProcessorBlock[BitNumber]; Pcr = CONTAINING_RECORD (Prcb, KPCR, PrcbData); GdtEntry = Pcr->GDT + GdtIndex;
// set it
*GdtEntry = *GdtValue; }
return STATUS_SUCCESS; }
|