Esempio n. 1
0
NTSTATUS
NlInitialize(
    VOID
    )

/*++

Routine Description:

    Initialize NETLOGON portion of msv1_0 authentication package.

Arguments:

    None.

Return Status:

    STATUS_SUCCESS - Indicates NETLOGON successfully initialized.

--*/

{
    NTSTATUS Status;
    LPWSTR ComputerName;
    DWORD ComputerNameLength = MAX_COMPUTERNAME_LENGTH + 1;
    NT_PRODUCT_TYPE NtProductType;
    UNICODE_STRING TempUnicodeString;

    //
    // Initialize global data
    //

    NlpEnumerationHandle = 0;
    NlpSessionCount = 0;

    NlpComputerName.Buffer = NULL;
    NlpSamDomainName.Buffer = NULL;
    NlpSamDomainId = NULL;
    NlpSamDomainHandle = NULL;



    //
    // Get the name of this machine.
    //

    ComputerName = RtlAllocateHeap(
                        MspHeap, 0,
                        ComputerNameLength * sizeof(WCHAR) );

    if (ComputerName == NULL ||
        !GetComputerNameW( ComputerName, &ComputerNameLength )) {

        KdPrint(( "MsV1_0: Cannot get computername %lX\n", GetLastError() ));

        NlpLanmanInstalled = FALSE;
        RtlFreeHeap( MspHeap, 0, ComputerName );
        ComputerName = NULL;
    } else {

        NlpLanmanInstalled = TRUE;
    }

    RtlInitUnicodeString( &NlpComputerName, ComputerName );

    //
    // Determine if this machine is running Windows NT or Lanman NT.
    //  LanMan NT runs on a domain controller.
    //

    if ( !RtlGetNtProductType( &NtProductType ) ) {
        KdPrint(( "MsV1_0: Nt Product Type undefined (WinNt assumed)\n" ));
        NtProductType = NtProductWinNt;
    }

    NlpWorkstation = (BOOLEAN)(NtProductType != NtProductLanManNt);


#ifdef notdef

    //
    // Initialize any locks.
    //

    RtlInitializeCriticalSection(&NlpActiveLogonLock);
    RtlInitializeCriticalSection(&NlpSessionCountLock);

    //
    // initialize the cache - creates a critical section is all
    //

    NlpCacheInitialize();
#endif // notdef


    //
    // Attempt to load Netapi.dll
    //

    NlpLoadNetapiDll();

#ifdef COMPILED_BY_DEVELOPER
    KdPrint(("msv1_0: COMPILED_BY_DEVELOPER breakpoint.\n"));
    DbgBreakPoint();
#endif // COMPILED_BY_DEVELOPER



    //
    // Initialize useful encryption constants
    //

    Status = RtlCalculateLmOwfPassword( "", &NlpNullLmOwfPassword );
    ASSERT( NT_SUCCESS(Status) );

    RtlInitUnicodeString(&TempUnicodeString, NULL);
    Status = RtlCalculateNtOwfPassword(&TempUnicodeString,
                                       &NlpNullNtOwfPassword);
    ASSERT( NT_SUCCESS(Status) );




#ifdef notdef
    //
    // If we weren't successful,
    //  Clean up global resources we intended to initialize.
    //

    if ( !NT_SUCCESS(Status) ) {
        if ( NlpComputerName.Buffer != NULL ) {
            MIDL_user_free( NlpComputerName.Buffer );
        }

    }
#endif // notdef

    return STATUS_SUCCESS;

}
Esempio n. 2
0
BOOLEAN
HalHandleNMI(
    IN PKINTERRUPT Interrupt,
    IN PVOID ServiceContext
    )
/*++

Routine Description:

   This function is called when an EISA NMI occurs.  It prints the 
   appropriate status information and bugchecks.

Arguments:

   Interrupt - Supplies a pointer to the interrupt object

   ServiceContext - Bug number to call bugcheck with.

Return Value:

   Returns TRUE.

--*/
{
    LEGO_SRV_MGMT  SmRegister;
    UCHAR   NmiControl, NmiStatus;
    BOOLEAN GotSerr, GotIochk, GotSmFan, GotSmTemp, GotHalt;
    
    NMIcount++;

#if DBG
    if (NMIcount<5) {
        DbgPrint("II<NMI><");
    }
    if (NMIcount % 100 == 0) {
        DbgPrint("II<NMI><%08x><", NMIcount);
    }
#endif

    GotSerr = GotIochk = GotSmFan = GotSmTemp = GotHalt = FALSE;

    //
    // Set the Eisa NMI disable bit. We do this to mask further NMI 
    // interrupts while we're servicing this one.
    //
    NmiControl = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&NmiControl))->NmiDisable = 1;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, NmiControl);

#ifdef DBG
    DbgPrint("HalHandleNMI: wrote 0x%x to NmiEnable\n", NmiControl);
#endif

    NmiStatus =
        READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus);

    if (NmiStatus & 0x80) {
        GotSerr = TRUE;

#ifdef DBG
        DbgPrint("HalHandleNMI: Parity Check / Parity Error\n");
        DbgPrint("HalHandleNMI:    NMI Status = 0x%x\n", NmiStatus);
#endif
        HalAcquireDisplayOwnership(NULL);
        HalDisplayString ("NMI: Parity Check / Parity Error\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
    }

    if (NmiStatus & 0x40) {
        GotIochk = TRUE;
#ifdef DBG
        DbgPrint("HalHandleNMI: Channel Check / IOCHK\n");
        DbgPrint("HalHandleNMI:    NMI Status = 0x%x\n", NmiStatus);
#endif
        HalAcquireDisplayOwnership(NULL);
        HalDisplayString ("NMI: Channel Check / IOCHK\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
    }

    // Read server management register
    //  Events that can be reported as NMI are:
    //      Enclosure temperature too high
    //      CPU Fan failure
    //
    // For now, generate a bugcheck.
    // [wem] Future: perform secondary dispatch to give
    //       driver shot at reporting problem.
    //
    SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );

    GotSmFan = SmRegister.CpuFanFailureNmi == 1;
    GotSmTemp = SmRegister.EnclTempFailureNmi == 1;

    if (GotSmFan || GotSmTemp) {

#ifdef DBG
        DbgPrint("HalHandleNMI: Server management NMI\n");
        DbgPrint("HalHandleNMI:    NMI Status = 0x%x\n", NmiStatus);
        DbgPrint("HalHandleNMI:    Server Management Status = 0x%x\n", SmRegister);
#endif

        //
        // If secondary dispatch enabled, do it now.
        //
#if 0
        if (HalpLegoDispatchNmi
            && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[SM_ERROR_VECTOR])(
                    PCR->InterruptRoutine[SM_ERROR_VECTOR],
                    TrapFrame)
           ) {
            return TRUE;
        }
#endif

        //
        // Build uncorrectable error frame and 
        // prepare for orderly shutdown
        //
        // The delayed shutdown depends on watchdog timer support
        // A power off cannot be directly done since KeBugChk() turns
        // off interrupts, so there's no way to get control back.
        //
        // WARNING: Pick a delay that allows a dump to complete.
        //

        LegoServerMgmtReportFatalError(SmRegister.All);
        LegoServerMgmtDelayedShutdown(8);                  // Issue reset in 8 seconds

        HalAcquireDisplayOwnership(NULL);

        HalDisplayString ("NMI: Hardware Failure -- ");
        HalDisplayString ((SmRegister.CpuFanFailureNmi==1) ? "CPU fan failed."
                                                           : "Enclosure termperature too high.");
        HalDisplayString ("\nSystem Power Down will be attempted in 8 seconds...\n\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
    }


    // 
    // Halt button was hit.
    //
    // [wem] Perform second-level dispatch here too?
    //
    if (!GotSerr && !GotIochk && !GotSmFan && !GotSmTemp) {

        //
        // If secondary dispatch enabled, do it now.
        //
#if 0
        if (HalpLegoDispatchHalt
            && ((PSECONDARY_DISPATCH) PCR->InterruptRoutine[HALT_BUTTON_VECTOR])(
                    PCR->InterruptRoutine[HALT_BUTTON_VECTOR],
                    TrapFrame)
           ) {
            return TRUE;
        }
#endif

        GotHalt = TRUE;
        HalDisplayString ("NMI: Halt button pressed.\n");

        if (HalpHaltButtonBreak) {
            DbgBreakPoint();
        }

        return (TRUE);
    }

    //
    // Clear and re-enable SERR# and IOCHK#, then re-enable NMI
    //

#ifdef DBG
    DbgPrint("HalHandleNMI: Shouldn't get here!\n");
#endif

    if (GotSerr) {
#ifdef DBG
        DbgPrint("HalHandleNMI: Resetting SERR#; NMI count = %d\n", NMIcount);
#endif
        //
        // Reset SERR# (and disable it), then re-enable it.
        //
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x04);
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);
    }

    if (GotIochk) {
#ifdef DBG
        DbgPrint("HalHandleNMI: Resetting IOCHK#; NMI count = %d\n", NMIcount);
#endif
        //
        // Reset IOCHK# (and disable it), then re-enable it.
        //
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x08);
        WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);
    }

    if (GotSmFan || GotSmTemp) {
        //
        // Reset Server management condition.
        //
        // Interrupt must be cleared or the NMI will continue
        // to occur.
        //
        SmRegister.All = READ_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva );
        if (GotSmFan) {
            SmRegister.CpuFanFailureNmi = 1;
        }
        else {
            SmRegister.EnclTempFailureNmi = 1;
        }
        WRITE_REGISTER_USHORT ((PUSHORT)HalpLegoServerMgmtQva, SmRegister.All );
    }

    //
    // Clear the Eisa NMI disable bit. This re-enables NMI interrupts,
    // now that we're done servicing this one.
    //
    NmiControl = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&NmiControl))->NmiDisable = 0;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, NmiControl);
#ifdef DBG
    DbgPrint("HalHandleNMI: wrote 0x%x to NmiEnable\n", NmiControl);
#endif

    return(TRUE);
}
Esempio n. 3
0
BOOL bTestLoadFOT (
    HDC     hdc
    )
{
    HFONT   hfont;
    HFONT   hfontOriginal;
    LOGFONT lfnt;
    TEXTMETRIC  tm;

// Clear the screen to black.

    BitBlt(hdc, 0, 0, CX, CY, (HDC) 0, 0, 0, 0);

    DbgPrint("ft!bTestLoadFOT(): check gcTrueTypeFonts\n");
    DbgBreakPoint();

// Add a TrueType .FOT font file.

    if ( !AddFontResource("lcallig.fot") )
    {
        DbgPrint("ft!bTestLoadFOT(): failed to load .FOT file\n");
        return FALSE;
    }
    GdiFlush();
    DbgPrint("ft!bTestLoadFOT(): check gcTrueTypeFonts (it should be 1 bigger)\n");
    DbgBreakPoint();

// Get a font.

    memset(&lfnt, 0, sizeof(lfnt));
    lstrcpy(lfnt.lfFaceName, "Lucida Calligraphy");
    lfnt.lfHeight = -14;
    lfnt.lfWeight = 400;

    if ((hfont = CreateFontIndirect(&lfnt)) == NULL)
    {
        DbgPrint("ft!bTestLoadFOT(): Logical font creation failed.\n");
        return FALSE;
    }

    hfontOriginal = SelectObject(hdc, hfont);

// Get metrics.

    if ( GetTextMetrics(hdc, &tm) )
        vPrintTM(hdc, &tm);
    else
        DbgPrint("ft!bTestLoadFOT(): GetTextMetrics call failed\n");

// Restore the font.

    SelectObject(hdc, hfontOriginal);
    DeleteObject(hfont);

// Remove the TrueType .FOT font file.

    if ( !RemoveFontResource("lcallig.fot") )
    {
        DbgPrint("ft!bTestLoadFOT(): error removing .FOT file\n");
        return FALSE;
    }
    GdiFlush();
    DbgPrint("ft!bTestLoadFOT(): check gcTrueTypeFonts (it should be 1 smaller)\n");
    DbgBreakPoint();

    return TRUE;
}
Esempio n. 4
0
void WINAPI DebugBreak(void)
{
    DbgBreakPoint();
}
Esempio n. 5
0
NTSTATUS
TtdiOpenAddress (
    IN PHANDLE FileHandle,
    IN PSZ Name)
{
    IO_STATUS_BLOCK IoStatusBlock;
    NTSTATUS Status;
    UNICODE_STRING NameString;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PFILE_FULL_EA_INFORMATION EaBuffer;
    PTDI_ADDRESS_NETBIOS AddressName;
    PTRANSPORT_ADDRESS Address;
    PTA_ADDRESS AddressType;
    int i;

    DbgPrint ("TtdiOpenAddress: Opening ");
    DbgPrint (Name);
    DbgPrint (".\n");
    RtlInitUnicodeString (&NameString, TRANSPORT_NAME);
    InitializeObjectAttributes (
        &ObjectAttributes,
        &NameString,
        0,
        NULL,
        NULL);

    EaBuffer = (PFILE_FULL_EA_INFORMATION)ExAllocatePool (NonPagedPool, 100);
    if (EaBuffer == NULL) {
        DbgBreakPoint ();
    }

    EaBuffer->NextEntryOffset =0;
    EaBuffer->Flags = 0;
    EaBuffer->EaNameLength = TDI_TRANSPORT_ADDRESS_LENGTH;
    EaBuffer->EaValueLength = sizeof (TDI_ADDRESS_NETBIOS);

    for (i=0;i<(int)EaBuffer->EaNameLength;i++) {
        EaBuffer->EaName[i] = TdiTransportAddress[i];
    }

    Address = (PTRANSPORT_ADDRESS)&EaBuffer->EaName[EaBuffer->EaNameLength+1];
    Address->TAAddressCount = 1;

    AddressType = (PTA_ADDRESS)((PUCHAR)Address + sizeof (Address->TAAddressCount));

    AddressType->AddressType = TDI_ADDRESS_TYPE_NETBIOS;
    AddressType->AddressLength = TDI_ADDRESS_LENGTH_NETBIOS;

    AddressName = (PTDI_ADDRESS_NETBIOS)((PUCHAR)AddressType +
       sizeof (AddressType->AddressType) + sizeof (AddressType->AddressLength));
    AddressName->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;
    AddressName->NetbiosNameType = TDI_ADDRESS_NETBIOS_TYPE_UNIQUE;

    for (i=0;i<16;i++) {
        AddressName->NetbiosName[i] = Name[i];
    }

    Status = IoCreateFile (
                 FileHandle,
                 0, // desired access.
                 &ObjectAttributes,     // object attributes.
                 &IoStatusBlock,        // returned status information.
                 0,                     // block size (unused).
                 FO_SYNCHRONOUS_IO,     // file attributes.
                 0,
                 0,
                 0,                     // create options.
                 EaBuffer,                  // EA buffer.
                 (PUCHAR)&AddressName->NetbiosName[i] - (PUCHAR)EaBuffer + 1,                   // ea length
                 CreateFileTypeNone,
                 (PVOID)NULL,
                 0 );                    // EA length.

    if (!NT_SUCCESS( Status )) {
        DbgPrint ("TtdiOpenAddress:  FAILURE, NtCreateFile returned status code=%lC.\n", Status);
        return Status;
    }

    Status = IoStatusBlock.Status;

    if (!(NT_SUCCESS( Status ))) {
        DbgPrint ("TtdiOpenAddress:  FAILURE, IoStatusBlock.Status contains status code=%lC.\n", Status);
    }

    DbgPrint ("TtdiOpenAddress:  returning\n");

    return Status;
} /* TtdiOpenAddress */
Esempio n. 6
0
ULONG
RtlWalkFrameChain (

    OUT PVOID *Callers,
    IN ULONG Count,
    IN ULONG Flags)

/*++

Routine Description:

    RtlWalkFrameChain

Description:

    This function tries to walk the EBP chain and fill out a vector of
    return addresses. The function works only on x86. It is possible that
    the function cannot fill the requested number of callers because somewhere
    on the stack we have a function compiled FPO (the frame register (EBP) is
    used as a normal register. In this case the function will just return with
    a less then requested count. In kernel mode the function should not take
    any exceptions (page faults) because it can be called at all sorts of
    irql levels.

    The `Flags' parameter is used for future extensions. A zero value will be
    compatible with new stack walking algorithms.

    Note. The algorithm can be somewhat improved by unassembling the return
    addresses identified. However this is impractical in kernel mode because
    the function might get called at high irql levels where page faults are
    not allowed.

Return value:

    The number of identified return addresses on the stack. This can be less
    then the Count requested if the stack ends or we encounter a FPO compiled
    function.

--*/

{
#if defined(_X86_)

    ULONG_PTR Fp, NewFp, ReturnAddress;
    ULONG Index;
    ULONG_PTR StackEnd, StackStart;
    BOOLEAN Result;

    //
    // Get the current EBP pointer which is supposed to
    // be the start of the EBP chain.
    //

    _asm mov Fp, EBP;

    StackStart = Fp;

#if _KERNEL_MODE_STACK_TRACES_

    StackEnd = (ULONG_PTR)(KeGetCurrentThread()->StackBase);

    //
    // bugbug: find a reliable way to get the stack limit in kernel mode.
    // `StackBase' is not a reliable way to get the stack end in kernel
    // mode because we might execute a DPC routine on thread's behalf.
    // There are a few other reasons why we cannot trust this completely.
    //
    // Note. The condition `PAGE_START(StackEnd) - PAGE_START(StackStart) > PAGE_SIZE'
    // is not totally safe. We can encounter a situation where in this case we
    // do not have the same stack. Can we?
    //
    // The DPC stack is actually the stack of the idle thread corresponding to
    // the current processor. Based on that we probably can figure out in almost
    // all contexts what are the real limits of the stack.
    //

    if ((StackStart > StackEnd)
        || (PAGE_START(StackEnd) - PAGE_START(StackStart) > PAGE_SIZE)) {

        StackEnd = (StackStart + PAGE_SIZE) & ~((ULONG_PTR)PAGE_SIZE - 1);
    
        //
        // Try to get one more page if possible. Note that this is not
        // 100% reliable because a non faulting address can fault if
        // appropriate locks are not held.
        //

        if (MmIsAddressValid ((PVOID)StackEnd)) {
            StackEnd += PAGE_SIZE;
        }
    }

#else

    StackEnd = (ULONG_PTR)(NtCurrentTeb()->NtTib.StackBase);

#endif // #if _KERNEL_MODE_STACK_TRACES_

    try {

        for (Index = 0; Index < Count; Index++) {

            if (Fp + sizeof(ULONG_PTR) >= StackEnd) {
                break;
            }

            NewFp = *((PULONG_PTR)(Fp + 0));
            ReturnAddress = *((PULONG_PTR)(Fp + sizeof(ULONG_PTR)));

            //
            // Figure out if the new frame pointer is ok. This validation
            // should avoid all exceptions in kernel mode because we always
            // read within the current thread's stack and the stack is
            // guaranteed to be in memory (no page faults). It is also guaranteed
            // that we do not take random exceptions in user mode because we always
            // keep the frame pointer within stack limits.
            //

            if (! (Fp < NewFp && NewFp < StackEnd)) {
                break;
            }

            //
            // Figure out if the return address is ok. If return address
            // is a stack address or <64k then something is wrong. There is
            // no reason to return garbage to the caller therefore we stop.
            //

            if (StackStart < ReturnAddress && ReturnAddress < StackEnd) {
                break;
            }

            if (ReturnAddress < 64 * SIZE_1_KB) {
                break;
            }

            //
            // Store new fp and return address and move on.
            //

            Fp = NewFp;
            Callers[Index] = (PVOID)ReturnAddress;
        }
    }
    except (EXCEPTION_EXECUTE_HANDLER) {

        //
        // The frame traversal algorithm is written so that we should
        // not get any exception. Therefore if we get some exception
        // we better debug it.
        //
        // bugbug: enable bkpt only on checked builds
        // After we get some coverage on this we should leave it active
        // only on checked builds.
        //

        DbgPrint ("Unexpected exception in RtlWalkFrameChain ...\n");
        DbgBreakPoint ();
    }

    //
    // Return the number of return addresses identified on the stack.
    //

#if _COLLECT_FRAME_WALK_STATISTICS_
    CollectFrameWalkStatistics (Index);
#endif // #if _COLLECT_FRAME_WALK_STATISTICS_

    return Index;

#else

    return 0;

#endif // #if defined(_X86_)
}
Esempio n. 7
0
ULONG
SmpAllocateSessionId(
    IN PSMPKNOWNSUBSYS OwningSubsystem,
    IN PSMPKNOWNSUBSYS CreatorSubsystem OPTIONAL
    )

/*++

Routine Description:

    This function allocates a session id.

Arguments:

    OwningSubsystem - Supplies the address of the subsystem that should
        become the owner of this session.


    CreatorSubsystem - An optional parameter that if supplied supplies
        the address of the subsystem requesting the creation of this
        session.  This subsystem is notified when the session completes.

Return Value:

    This function returns the session id for this session.

--*/

{

    ULONG SessionId;
    PLIST_ENTRY SessionIdListInsertPoint;
    PSMPSESSION Session;

    RtlEnterCriticalSection(&SmpSessionListLock);

    //
    // SessionId's are allocated by incrementing a 32 bit counter.
    // If the counter wraps, then session id's are allocated by
    // scaning the sorted list of current session id's for a hole.
    //

    SessionId = SmpNextSessionId++;
    SessionIdListInsertPoint = SmpSessionListHead.Blink;

    if ( !SmpNextSessionIdScanMode ) {

        if ( SmpNextSessionId == 0 ) {

            //
            // We have used up 32 bits worth of session id's so
            // enable scan mode session id allocation.
            //

            SmpNextSessionIdScanMode = TRUE;
        }

    } else {

        //
        // Compute a session id by scanning the sorted session id list
        // until a  whole is found. When an id is found, then save it,
        // and re-calculate the inster point.
        //

        DbgPrint("SMSS: SessionId's Wraped\n");
        DbgBreakPoint();

    }

    Session = RtlAllocateHeap(SmpHeap, MAKE_TAG( SM_TAG ), sizeof(SMPSESSION));

    Session->SessionId = SessionId;
    Session->OwningSubsystem = OwningSubsystem;
    Session->CreatorSubsystem = CreatorSubsystem;

    InsertTailList(SessionIdListInsertPoint,&Session->SortedSessionIdListLinks);

    RtlLeaveCriticalSection(&SmpSessionListLock);

    return SessionId;
}
Esempio n. 8
0
/*
 * @implemented
 */
VOID
NTAPI
RtlAssert(IN PVOID FailedAssertion,
          IN PVOID FileName,
          IN ULONG LineNumber,
          IN PCHAR Message OPTIONAL)
{
    CHAR Action[2];
    CONTEXT Context;

    /* Capture caller's context for the debugger */
    RtlCaptureContext(&Context);

    /* Enter prompt loop */
    for (;;)
    {
        /* Print the assertion */
        DbgPrint("\n*** Assertion failed: %s%s\n"
                 "***   Source File: %s, line %ld\n\n",
                 Message != NULL ? Message : "",
                 (PSTR)FailedAssertion,
                 (PSTR)FileName,
                 LineNumber);

        /* Prompt for action */
        DbgPrompt("Break repeatedly, break Once, Ignore,"
                  " terminate Process or terminate Thread (boipt)? ",
                  Action,
                  sizeof(Action));
        switch (Action[0])
        {
            /* Break repeatedly */
            case 'B': case 'b':

                /* Do a breakpoint, then prompt again */
                DbgPrint("Execute '.cxr %p' to dump context\n", &Context);
                DbgBreakPoint();
                break;

            /* Ignore */
            case 'I': case 'i':

                /* Return to caller */
                return;

            /* Break once */
            case 'O': case 'o':

                /* Do a breakpoint and return */
                DbgPrint("Execute '.cxr %p' to dump context\n", &Context);
                DbgBreakPoint();
                return;

            /* Terminate process*/
            case 'P': case 'p':

                /* Terminate us */
                ZwTerminateProcess(ZwCurrentProcess(), STATUS_UNSUCCESSFUL);
                break;

            /* Terminate thread */
            case 'T': case 't':

                /* Terminate us */
                ZwTerminateThread(ZwCurrentThread(), STATUS_UNSUCCESSFUL);
                break;

            /* Unrecognized */
            default:

                /* Prompt again */
                break;
        }
    }

    /* Shouldn't get here */
    DbgBreakPoint();
    ZwTerminateProcess(ZwCurrentProcess(), STATUS_UNSUCCESSFUL);
}
Esempio n. 9
0
BOOLEAN
HalInitSystem (
    IN ULONG Phase,
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )


/*++

Routine Description:

    This function initializes the Hardware Architecture Layer (HAL) for an
    x86 system.

Arguments:

    None.

Return Value:

    A value of TRUE is returned is the initialization was successfully
    complete. Otherwise a value of FALSE is returend.

--*/

{
    PMEMORY_ALLOCATION_DESCRIPTOR Descriptor;
    PLIST_ENTRY NextMd;
    KIRQL CurrentIrql;
    extern VOID HalpAddMem(IN PLOADER_PARAMETER_BLOCK);
    PKPRCB   pPRCB;
    ULONG    BuildType;

    pPRCB = KeGetCurrentPrcb();

    if (Phase == 0) {

        if (CbusGetParameters (LoaderBlock)) {
            DbgBreakPoint();
        }

        HalpBusType = LoaderBlock->u.I386.MachineType & 0x00ff;

        //
        // Verify Prcb version and build flags conform to
        // this image
        //

        BuildType = 0;
#if DBG
        BuildType |= PRCB_BUILD_DEBUG;
#endif
#ifdef NT_UP
        BuildType |= PRCB_BUILD_UNIPROCESSOR;
#endif

        if (pPRCB->MajorVersion != PRCB_MAJOR_VERSION) {
            KeBugCheckEx (MISMATCHED_HAL,
                1, pPRCB->MajorVersion, PRCB_MAJOR_VERSION, 0);
        }

        if (pPRCB->BuildType != BuildType) {
            KeBugCheckEx (MISMATCHED_HAL,
                2, pPRCB->BuildType, BuildType, 0);
        }

        //
        // Phase 0 initialization
        // only called by P0
        //

        //
        // Check to make sure the MCA HAL is not running on an ISA/EISA
        // system, and vice-versa.
        //
#if MCA
        if (HalpBusType != MACHINE_TYPE_MCA) {
            KeBugCheckEx (MISMATCHED_HAL,
                3, HalpBusType, MACHINE_TYPE_MCA, 0);
        }
#else
        if (HalpBusType == MACHINE_TYPE_MCA) {
            KeBugCheckEx (MISMATCHED_HAL,
                3, HalpBusType, 0, 0);
        }
#endif

        //
        // Most HALs initialize their PICs at this point - we set up
        // the Cbus PICs in HalInitializeProcessor() long ago...
        // Now that the PICs are initialized, we need to mask them to
        // reflect the current Irql
        //

        CurrentIrql = KeGetCurrentIrql();
        KfRaiseIrql(CurrentIrql);

        //
        // Fill in handlers for APIs which this hal supports
        //

        HalQuerySystemInformation = HaliQuerySystemInformation;
        HalSetSystemInformation = HaliSetSystemInformation;

        //
        // Initialize CMOS
        //

        HalpInitializeCmos();


        //
        // Register the PC-compatible base IO space used by hal
        //

        HalpRegisterAddressUsage (&HalpDefaultPcIoSpace);
        if (HalpBusType == MACHINE_TYPE_EISA) {
            HalpRegisterAddressUsage (&HalpEisaIoSpace);
        }

        //
        // Cbus1: stall uses the APIC to figure it out (needed in phase0).
        //        the clock uses the APIC (needed in phase0)
        //        the perfcounter uses RTC irq8 (not needed till all cpus boot)
        //
        // Cbus2: stall uses the RTC irq8 to figure it out (needed in phase0).
        //        the clock uses the irq0 (needed in phase0)
        //        the perfcounter uses RTC irq8 (not needed till all cpus boot)
        //
        //
        // set up the stall execution and enable clock interrupts now.
        // APC, DPC and IPI are already enabled.
        //

        (*CbusBackend->HalInitializeInterrupts)(0);

        HalStopProfileInterrupt(0);

        HalpInitializeDisplay();

        //
        // Initialize spinlock used by HalGetBusData hardware access routines
        //

        KeInitializeSpinLock(&HalpSystemHardwareLock);

	//
	// Any additional memory must be recovered BEFORE Phase0 ends
	//
	HalpAddMem(LoaderBlock);

        //
        // Determine if there is physical memory above 16 MB.
        //

        LessThan16Mb = TRUE;

        NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;

        while (NextMd != &LoaderBlock->MemoryDescriptorListHead) {
            Descriptor = CONTAINING_RECORD( NextMd,
                                            MEMORY_ALLOCATION_DESCRIPTOR,
                                            ListEntry );

            if (Descriptor->BasePage + Descriptor->PageCount > 0x1000) {
                LessThan16Mb = FALSE;
            }

            NextMd = Descriptor->ListEntry.Flink;
        }

        //
        // Determine the size need for map buffers.  If this system has
        // memory with a physical address of greater than
        // MAXIMUM_PHYSICAL_ADDRESS, then allocate a large chunk; otherwise,
        // allocate a small chunk.
	//
	// This should probably create a memory descriptor which describes
	// the DMA map buffers reserved by the HAL, and then add it back in
	// to the LoaderBlock so the kernel can report the correct amount
	// of memory in the machine.
        //

        if (LessThan16Mb) {

            //
            // Allocate a small set of map buffers.  They are only need for
            // slave DMA devices.
            //

            HalpMapBufferSize = INITIAL_MAP_BUFFER_SMALL_SIZE;

        } else {

            //
            // Allocate a larger set of map buffers.  These are used for
            // slave DMA controllers and Isa cards.
            //

            HalpMapBufferSize = INITIAL_MAP_BUFFER_LARGE_SIZE;

        }

        //
        // Allocate map buffers for the adapter objects
        //

        HalpMapBufferPhysicalAddress.LowPart =
            HalpAllocPhysicalMemory (LoaderBlock, MAXIMUM_PHYSICAL_ADDRESS,
                HalpMapBufferSize >> PAGE_SHIFT, TRUE);
        HalpMapBufferPhysicalAddress.HighPart = 0;


        if (!HalpMapBufferPhysicalAddress.LowPart) {

            //
            // There was not a satisfactory block.  Clear the allocation.
            //

            HalpMapBufferSize = 0;
        }

    } else {
Esempio n. 10
0
NTSTATUS
LpxGetExportNameFromRegistry(
    IN  PUNICODE_STRING RegistryPath,
    IN  PUNICODE_STRING BindName,
    OUT PUNICODE_STRING ExportName
    )
{
    NTSTATUS OpenStatus;
    HANDLE ParametersHandle;
    HANDLE LpxConfigHandle;
    NTSTATUS Status;
    PWSTR RegistryPathBuffer;
    OBJECT_ATTRIBUTES TmpObjectAttributes;
    
    RTL_QUERY_REGISTRY_TABLE QueryTable[3];
    PWSTR Subkey = L"Linkage";
    PWSTR Bind = L"Bind";
    PWSTR Export = L"Export";
    LONG BindNumber;

    //
    // Open the registry.
    //

    InitializeObjectAttributes(
        &TmpObjectAttributes,
        RegistryPath,               // name
        OBJ_CASE_INSENSITIVE,       // attributes
        NULL,                       // root
        NULL                        // security descriptor
        );

    OpenStatus = ZwOpenKey(
                     &LpxConfigHandle,
                     KEY_WRITE,
                     &TmpObjectAttributes
                     );

    if (!NT_SUCCESS(OpenStatus)) {
        LpxPrint1("LPX: Could not open LPX key: %lx\n", OpenStatus);
        return OpenStatus;
    }

    Status = LpxOpenParametersKey (LpxConfigHandle, &ParametersHandle);

    if (Status != STATUS_SUCCESS) {
        ZwClose (LpxConfigHandle);
        return Status;
    }

    //
    // LpxReadLinkageInformation expects a null-terminated path,
    // so we have to create one from the UNICODE_STRING.
    //

    RegistryPathBuffer = (PWSTR)ExAllocatePoolWithTag(
                                    NonPagedPool,
                                    RegistryPath->Length + sizeof(WCHAR),
                                    LPX_MEM_TAG_REGISTRY_PATH);
                                    
    if (RegistryPathBuffer == NULL) {
        LpxCloseParametersKey (ParametersHandle);
        ZwClose (LpxConfigHandle);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlCopyMemory (RegistryPathBuffer, RegistryPath->Buffer, RegistryPath->Length);
    *(PWCHAR)(((PUCHAR)RegistryPathBuffer)+RegistryPath->Length) = (WCHAR)'\0';

    //
    // We have a new device whose binding was absent 
    // at boot - get export name given the bind name
    //

    // First we need to get index of the bind name
    
    // Set up QueryTable to do the following:

    //
    // 1) Switch to the Linkage key below LPX
    //

    QueryTable[0].QueryRoutine = NULL;
    QueryTable[0].Flags = RTL_QUERY_REGISTRY_SUBKEY;
    QueryTable[0].Name = Subkey;

    //
    // 2) Call LpxMatchBindName for each string in "Bind"
    //

    QueryTable[1].QueryRoutine = LpxMatchBindName;
    QueryTable[1].Flags = 0;
    QueryTable[1].Name = Bind;
    QueryTable[1].EntryContext = (PVOID)&BindNumber;
    QueryTable[1].DefaultType = REG_NONE;

    //
    // 3) Stop
    //

    QueryTable[2].QueryRoutine = NULL;
    QueryTable[2].Flags = 0;
    QueryTable[2].Name = NULL;


    BindNumber = -1;

    Status = RtlQueryRegistryValues(
                 RTL_REGISTRY_ABSOLUTE,
                 RegistryPathBuffer,
                 QueryTable,
                 (PVOID)BindName,
                 NULL);

    IF_LPXDBG (LPX_DEBUG_PNP) {
        LpxPrint2 ("Status from LpxMatchBindName's = %08x, Bind Number = %d\n",
                        Status, BindNumber);
    }

    if (Status != STATUS_NO_MORE_MATCHES)
    {
#if DBG
        DbgBreakPoint();
#endif
    
        if (Status == STATUS_SUCCESS) {
        
            // We did not find the device 'bind name'
            Status = NDIS_STATUS_ADAPTER_NOT_FOUND;
            
            IF_LPXDBG (LPX_DEBUG_PNP) {
                LpxPrint1 ("LPX - cannot find dynamic binding %S\n", BindName->Buffer);
            }
        }
Esempio n. 11
0
NTSTATUS
NTAPI
PinPropertyHandler(
    IN PIRP Irp,
    IN PKSIDENTIFIER  Request,
    IN OUT PVOID  Data)
{
    PIO_STACK_LOCATION IoStack;
    //PKSOBJECT_CREATE_ITEM CreateItem;
    PSUBDEVICE_DESCRIPTOR Descriptor;
    IIrpTarget * IrpTarget;
    IPort *Port;
    ISubdevice *SubDevice;
    PDISPATCH_CONTEXT DispatchContext;

    NTSTATUS Status = STATUS_UNSUCCESSFUL;

    Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
    PC_ASSERT(Descriptor);

    // get current irp stack
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    // get dispatch context
    DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;

    // Get the IrpTarget
    IrpTarget = DispatchContext->Target;
    PC_ASSERT(IrpTarget);

    // Get the parent
    Status = IrpTarget->QueryInterface(IID_IPort, (PVOID*)&Port);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Failed to obtain IPort interface from filter\n");
        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
        return STATUS_UNSUCCESSFUL;
    }

    // Get private ISubdevice interface
    Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Failed to obtain ISubdevice interface from port driver\n");
        DbgBreakPoint();
        while(TRUE);
    }

    // get current stack location
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    switch(Request->Id)
    {
    case KSPROPERTY_PIN_CTYPES:
    case KSPROPERTY_PIN_DATAFLOW:
    case KSPROPERTY_PIN_DATARANGES:
    case KSPROPERTY_PIN_INTERFACES:
    case KSPROPERTY_PIN_MEDIUMS:
    case KSPROPERTY_PIN_COMMUNICATION:
    case KSPROPERTY_PIN_CATEGORY:
    case KSPROPERTY_PIN_NAME:
    case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
        Status = KsPinPropertyHandler(Irp, Request, Data, Descriptor->Factory.PinDescriptorCount, Descriptor->Factory.KsPinDescriptor);
        break;
    case KSPROPERTY_PIN_GLOBALCINSTANCES:
        Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, TRUE, SubDevice);
        break;
    case KSPROPERTY_PIN_CINSTANCES:
        Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, FALSE, SubDevice);
        break;
    case KSPROPERTY_PIN_NECESSARYINSTANCES:
        Status = HandleNecessaryPropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, SubDevice);
        break;

    case KSPROPERTY_PIN_DATAINTERSECTION:
        Status = HandleDataIntersection(&Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor, SubDevice);
        break;
    case KSPROPERTY_PIN_PHYSICALCONNECTION:
        Status = HandlePhysicalConnection(&Irp->IoStatus, Request, IoStack->Parameters.DeviceIoControl.InputBufferLength, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor);
        break;
    case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
        UNIMPLEMENTED
        Status = STATUS_NOT_IMPLEMENTED;
        break;
    default:
        UNIMPLEMENTED
        Status = STATUS_UNSUCCESSFUL;
    }

    // Release reference
    Port->Release();

    // Release subdevice reference
    SubDevice->Release();

    return Status;
}
// =========================================================================
// This routine is the driver's entry point, called by the I/O system
// to load the driver.  The driver's entry points are initialized.
// In DBG mode, this routine also examines the registry for special
// debug parameters.
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    UNICODE_STRING devDirName;
    OBJECT_ATTRIBUTES dirObjAttribs;
    PDEVICE_OBJECT mainDevObj;
    PDEVICE_EXTENSION mainDevExt;
    
    // The following debug handling was ripped from the MS DDK "floppy.c"
    // example
#if DBG
    // We use this to query into the registry as to whether we
    // should break at driver entry.
    RTL_QUERY_REGISTRY_TABLE paramTable[3];
    ULONG default_ShouldBreak = 0;           // Default to 0; no break
//    ULONG default_DebugLevel  = 0xFFFFFFFF;  // Default to all on
    ULONG default_DebugLevel  = 0x0000001F;  // All except verbose debug
    ULONG debugLevel = 0;
    ULONG shouldBreak = 0;
    PWCHAR path;
    ULONG pathLength;
    
    // Since the registry path parameter is a "counted" UNICODE string, it
    // might not be zero terminated.  For a very short time allocate memory
    // to hold the registry path zero terminated so that we can use it to
    // delve into the registry.
    //
    // NOTE NOTE!!!! This is not an architected way of breaking into
    // a driver.  It happens to work for this driver because the original
    // DDK example code for DriverEntry happened to be written in this manner.
    pathLength = RegistryPath->Length + sizeof(WCHAR);

    if (path = FREEOTFE_MEMALLOC(pathLength)) {

        SecZeroMemory(&paramTable[0], sizeof(paramTable));
        SecZeroMemory(path, pathLength);
        RtlMoveMemory( path, RegistryPath->Buffer, RegistryPath->Length );

        paramTable[0].Flags         = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[0].Name          = L"BreakOnEntry";
        paramTable[0].EntryContext  = &shouldBreak;
        paramTable[0].DefaultType   = REG_DWORD;
        paramTable[0].DefaultData   = &default_ShouldBreak;
        paramTable[0].DefaultLength = sizeof(ULONG);

        paramTable[1].Flags         = RTL_QUERY_REGISTRY_DIRECT;
        paramTable[1].Name          = L"DebugLevel";
        paramTable[1].EntryContext  = &debugLevel;
        paramTable[1].DefaultType   = REG_DWORD;
        paramTable[1].DefaultData   = &default_DebugLevel;
        paramTable[1].DefaultLength = sizeof(ULONG);

        if (!(NT_SUCCESS(RtlQueryRegistryValues(
                            RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
                            path,
                            &paramTable[0],
                            NULL,
                            NULL)))) {

            shouldBreak = default_ShouldBreak;
            debugLevel = default_DebugLevel;
        }

        FREEOTFE_FREE(path);
    }

    FreeOTFEDebugLevel = debugLevel;
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Debug level: %d\n", FreeOTFEDebugLevel));
    
    if (shouldBreak == 1)
        {
        DbgBreakPoint();
        }

#endif

    DEBUGOUTHASHDRV(DEBUGLEV_ENTER, ("DriverEntry\n"));

    // Create main device dir
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Creating dir object (main)...\n"));
    status = CreateDeviceDir(
                DEVICE_FREEOTFE_ROOT,
                &DirFreeOTFERoot
               );
    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("Unable to CreateDeviceDir (main)\n"));
        return status;
        }

    // Create hash device dir
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Creating dir object (hash)...\n"));
    status = CreateDeviceDir(
                DEVICE_HASH_DIR_NAME,
                &DirFreeOTFEHash
               );
    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("Unable to CreateDeviceDir (hash)\n"));
        ZwClose(DirFreeOTFERoot);
        return status;
        }

    // Create main device
    DEBUGOUTHASHDRV(DEBUGLEV_INFO, ("Creating main device...\n"));
    status = CreateDevice(DriverObject, &mainDevObj);
    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTHASHDRV(DEBUGLEV_ERROR, ("Call to CreateDevice FAILED.\n"));
        return status;
        }
    
    // Store the device dir handle for closure on unload
    mainDevExt = (PDEVICE_EXTENSION)mainDevObj->DeviceExtension;
    

    // Initialize the driver object with this driver's entry points.
    DriverObject->MajorFunction[IRP_MJ_CREATE] = 
                                            FreeOTFE_MF_DispatchCreate;
                                            
    DriverObject->MajorFunction[IRP_MJ_CLOSE] =
                                            FreeOTFE_MF_DispatchClose;
                                            
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
                                            FreeOTFE_MF_DispatchDeviceControl;
                                            

    DriverObject->DriverUnload = DriverUnload;


    DEBUGOUTHASHDRV(DEBUGLEV_EXIT, ("DriverEntry\n"));    

    return status;
}
Esempio n. 13
0
VOID
NtProcessStartup(
    PPEB Peb
    )
{
    int argc;
    char **argv;
    char **envp;
    char **dst;
    char *nullPtr = NULL;
    PCH s, d;
    ULONG n, DebugParameter;
    PULONG BadPointer;
    PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
    PUNICODE_STRING p;
    ANSI_STRING AnsiString;

    ASSERT( Peb != NULL );
    ProcessParameters = RtlNormalizeProcessParams( Peb->ProcessParameters );

    DebugParameter = 0;
    argc = 0;
    argv = &nullPtr;
    envp = &nullPtr;

    if (ARGUMENT_PRESENT( ProcessParameters )) {
        DebugParameter = ProcessParameters->DebugFlags;

        dst = RtlAllocateHeap( Peb->ProcessHeap, 0, 512 * sizeof( PCH ) );
        argv = dst;
        *dst = NULL;

        //
        // Now extract the arguments from the process command line.
        // using whitespace as separator characters.
        //

        p = &ProcessParameters->CommandLine;
        if (p->Buffer == NULL || p->Length == 0) {
            p = &ProcessParameters->ImagePathName;
            }
        RtlUnicodeStringToAnsiString( &AnsiString, p, TRUE );
        s = AnsiString.Buffer;
        n = AnsiString.Length;
        if (s != NULL) {
            d = RtlAllocateHeap( Peb->ProcessHeap, 0, n+2 );
            while (*s) {
                //
                // Skip over any white space.
                //

                while (*s && *s <= ' ') {
                    s++;
                    }

                //
                // Copy token to next white space separator and null terminate
                //

                if (*s) {
                    *dst++ = d;
                    argc++;
                    while (*s > ' ') {
                        *d++ = *s++;
                        }
                    *d++ = '\0';
                    }
                }
            }
        *dst++ = NULL;

        envp = dst;
        s = ProcessParameters->Environment;
        if (s != NULL) {
            while (*s) {
                *dst++ = s;
                while (*s++) {
                    ;
                    }
                }
            }
        *dst++ = NULL;
        }

    if (DebugParameter != 0) {
        DbgBreakPoint();
        }

    NtTerminateProcess( NtCurrentProcess(),
                        main( argc, argv, envp, DebugParameter )
                      );

    BadPointer = (PULONG)1;
    *BadPointer = 0;
}
Esempio n. 14
0
BOOLEAN
KdInitSystem(
    IN PLOADER_PARAMETER_BLOCK LoaderBlock,
    BOOLEAN StopInDebugger
    )

/*++

Routine Description:

    This routine initializes the portable kernel debugger.

Arguments:

    LoaderBlock - Supplies a pointer to the LOADER_PARAMETER_BLOCK passed
        in from the OS Loader.

    StopInDebugger - Supplies a boolean value that determines whether a
        debug message and breakpoint are generated.

Return Value:

    None.

--*/

{

    ULONG Index;
    BOOLEAN Initialize;
    PCHAR Options;
    PCHAR BaudOption;
    PCHAR PortOption;

    //
    // If kernel debugger is already initialized, then return.
    //

    if (KdDebuggerEnabled != FALSE) {
        return TRUE;
    }

    KiDebugRoutine = KdpStub;

    //
    // Determine whether or not the debugger should be enabled.
    //
    // Note that if LoaderBlock == NULL, then KdInitSystem was called
    // from BugCheck code. For this case the debugger is always enabled
    // to report the bugcheck if possible.
    //

    if (LoaderBlock != NULL) {

        KdpNtosImageBase =  CONTAINING_RECORD(
                                    (LoaderBlock->LoadOrderListHead.Flink),
                                    LDR_DATA_TABLE_ENTRY,
                                    InLoadOrderLinks)->DllBase;

        if (LoaderBlock->LoadOptions != NULL) {
            Options = LoaderBlock->LoadOptions;
            _strupr(Options);

            //
            // If any of the port option, baud option, or debug is specified,
            // then enable the debugger unless it is explictly disabled.
            //

            Initialize = TRUE;
            PortOption = strstr(Options, PORT_OPTION);
            BaudOption = strstr(Options, BAUD_OPTION);
            if ((PortOption == NULL) && (BaudOption == NULL)) {
                if (strstr(Options, "DEBUG") == NULL) {
                    Initialize = FALSE;
                }

            } else {
                if (PortOption) {
                    PortOption = strstr(PortOption, "COM");
                    if (PortOption) {
                        KdDebugParameters.CommunicationPort =
                                                     atol(PortOption + 3);
                    }
                }

                if (BaudOption) {
                    BaudOption += strlen(BAUD_OPTION);
                    while (*BaudOption == ' ') {
                        BaudOption++;
                    }

                    if (*BaudOption != '\0') {
                        KdDebugParameters.BaudRate = atol(BaudOption + 1);
                    }
                }
            }

            //
            // If the debugger is explicitly disable, then set to NODEBUG.
            //

            if (strstr(Options, "NODEBUG")) {
                Initialize = FALSE;
                KdPitchDebugger = TRUE;
            }

            if (strstr(Options, "CRASHDEBUG")) {
                Initialize = FALSE;
                KdPitchDebugger = FALSE;
            }

        } else {

            //
            // If the load options are not specified, then set to NODEBUG.
            //

            KdPitchDebugger = TRUE;
            Initialize = FALSE;
        }

    } else {
        Initialize = TRUE;
    }

    if ((KdPortInitialize(&KdDebugParameters, LoaderBlock, Initialize) == FALSE) ||
        (Initialize == FALSE)) {
        return(TRUE);
    }

    KdPitchDebugger = FALSE;

    //
    // Set address of kernel debugger trap routine.
    //

    KiDebugRoutine = KdpTrap;
    KiDebugSwitchRoutine = KdpSwitchProcessor;
    KdpBreakpointInstruction = KDP_BREAKPOINT_VALUE;
    KdpOweBreakpoint = FALSE;

    //
    // Initialize the breakpoint table.
    //

    for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index += 1) {
        KdpBreakpointTable[Index].Flags = 0;
        KdpBreakpointTable[Index].Address = NULL;
        KdpBreakpointTable[Index].DirectoryTableBase = 0L;
    }

    KdDebuggerEnabled = TRUE;

    //
    //  Initialize timer facility - HACKHACK
    //

    KeQueryPerformanceCounter(&KdPerformanceCounterRate);
    KdTimerStart.HighPart = 0L;
    KdTimerStart.LowPart = 0L;

    //
    // Initialize ID for NEXT packet to send and Expect ID of next incoming
    // packet.
    //

    KdpNextPacketIdToSend = INITIAL_PACKET_ID | SYNC_PACKET_ID;
    KdpPacketIdExpected = INITIAL_PACKET_ID;

    //
    // If requested, stop in the kernel debugger.
    //

    if (StopInDebugger) {
        DbgBreakPoint();
    }

    return TRUE;
}
Esempio n. 15
0
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING str)
{
	DbgBreakPoint();
	NTSTATUS sta;
	global.contextnum = 0;
	global.mininum = 0;
	globalinfopool.count = 0;
	global.controlobj = NULL;
	NDIS_STATUS ndissta;
	NDIS_HANDLE wraphandle=NULL;
	NDIS_MINIPORT_CHARACTERISTICS minicha;
	NDIS_PROTOCOL_CHARACTERISTICS pc;
	NDIS_STRING ns = NDIS_STRING_CONST("zlzpass");
	NdisZeroMemory(&global, sizeof(GLOBAL));
	NdisInitializeWrapper(&wraphandle, driver, str, NULL);
	if (wraphandle == NULL)
	{
		return STATUS_UNSUCCESSFUL;
	}
	NdisZeroMemory(&minicha, sizeof(NDIS_MINIPORT_CHARACTERISTICS));
	minicha.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
	minicha.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
	minicha.InitializeHandler = MPInitialize;
	minicha.HaltHandler = MPHalt;
	minicha.SetInformationHandler = MPSetInformation;
	minicha.QueryInformationHandler = MPQueryInformation;
	minicha.ReturnPacketHandler = MPReturnPacket;
	minicha.ResetHandler = NULL;
	minicha.CheckForHangHandler = NULL;
	minicha.TransferDataHandler = MPTransferData;
	minicha.SendHandler = MPSend;
	ndissta=NdisIMRegisterLayeredMiniport(wraphandle, &minicha, sizeof(NDIS_MINIPORT_CHARACTERISTICS), &global.driverhandle);
	if (ndissta!=NDIS_STATUS_SUCCESS)
	{
		return STATUS_UNSUCCESSFUL;
	}
	sysadddevfunc = driver->DriverExtension->AddDevice;

	driver->DriverExtension->AddDevice = myAddDevice;

	pc.MajorNdisVersion = 5;
	pc.MinorNdisVersion = 0;
	pc.Name = ns;
	pc.CloseAdapterCompleteHandler = NdisProtCloseAdapterComplete;
	pc.SendCompleteHandler = NdisProtSendComplete;
	pc.TransferDataCompleteHandler = NdisProtTransferDataComplete;
	pc.ResetCompleteHandler = NdisProtResetComplete;
	pc.RequestCompleteHandler = NdisProtRequestComplete;
	pc.ReceiveHandler = NdisProtReceive;
	pc.ReceiveCompleteHandler = NdisProtReceiveComplete;
	pc.StatusHandler = NdisProtStatus;
	pc.StatusCompleteHandler = NdisProtStatusComplete;
	pc.BindAdapterHandler = NdisProtBindAdapter;
	pc.OpenAdapterCompleteHandler = NdisOpenAdapterComplete;
	pc.UnbindAdapterHandler = NdisProtUnbindAdapter;
	pc.UnloadHandler = NULL;
	pc.ReceivePacketHandler = NdisProtReceivePacket;
	pc.PnPEventHandler = NdisProtPnPEventHandler;
	pc.CoAfRegisterNotifyHandler = NdisProtRegisterAf;
	NdisRegisterProtocol(&ndissta,&global.protocolhandle, &pc, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
	if (ndissta != NDIS_STATUS_SUCCESS)
	{
		return STATUS_UNSUCCESSFUL;
	}
	NdisIMAssociateMiniport(global.driverhandle, global.protocolhandle);

	sta = ZlzCreateDevice(driver,wraphandle);
	if (!NT_SUCCESS(sta))
	{
		return STATUS_UNSUCCESSFUL;
	}

	NdisMRegisterUnloadHandler(wraphandle, unload);
    return STATUS_SUCCESS;
}
Esempio n. 16
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT    pDriverObject,
    IN PUNICODE_STRING   RegistryPathName
)
/*++

    DriverEntry()

Routine Description:

    This routine performs initialization for the sound blaster
    device driver when it is first loaded

Arguments:

    pDriverObject - Pointer to a driver object.
    RegistryPathName - the path to our driver services node

Return Value:

    The function value is the final status from the initialization operation.

--*/
{
    SOUND_CARD_INSTANCE CardInstance;
    NTSTATUS            Status;
    PGLOBAL_DEVICE_INFO pGDI;

   /********************************************************************
    *
    * Initialize debugging
    *
    ********************************************************************/
#if DBG
    DriverName = "SNDBLST";
#endif


#if DBG
    if (SoundDebugLevel >= 4) {
        DbgBreakPoint();
    }
#endif

   /********************************************************************
    *
    * Initialize each card in turn
    *
    ********************************************************************/

    CardInstance.PrevGDI = NULL;
    CardInstance.pDriverObject = pDriverObject;

    /*
    ** Initialize the driver object dispatch table.
    */

    pDriverObject->DriverUnload                         = SoundUnload;
    pDriverObject->MajorFunction[IRP_MJ_CREATE]         = SoundDispatch;
    pDriverObject->MajorFunction[IRP_MJ_CLOSE]          = SoundDispatch;
    pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SoundDispatch;
    pDriverObject->MajorFunction[IRP_MJ_READ]           = SoundDispatch;
    pDriverObject->MajorFunction[IRP_MJ_WRITE]          = SoundDispatch;
    pDriverObject->MajorFunction[IRP_MJ_CLEANUP]        = SoundDispatch;
    pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN]       = SoundShutdown;

    Status = SoundEnumSubkeys(RegistryPathName,
                              PARMS_SUBKEY,
                              SoundCardInstanceInit,
                              (PVOID)&CardInstance);

    /*
    **  Save the return statuses
    */

    if (CardInstance.PrevGDI) {
        pGDI = CardInstance.PrevGDI;

        for (;;) {
            //
            // Save the Driver load status in the registry for the
            // User-mode DLL to pick up
            //
            SoundWriteRegistryDWORD( pGDI->RegistryPathName,
                                     SOUND_REG_CONFIGERROR,
                                     pGDI->LoadStatus);

            pGDI = pGDI->Next;
            if (pGDI == CardInstance.PrevGDI) {
                break;
            }
        }
    }

    /*
    ** If this failed then free everything
    */

    if (!NT_SUCCESS(Status)) {
        if (CardInstance.PrevGDI) {
            SoundCleanup(CardInstance.PrevGDI);

            /*
            **  Log a meaningful error for the one that failed!
            */

        }
        return Status;
    }

    return STATUS_SUCCESS;

}
Esempio n. 17
0
NTSTATUS
MmRemovePhysicalMemory (
    IN PPHYSICAL_ADDRESS StartAddress,
    IN OUT PLARGE_INTEGER NumberOfBytes
    )

/*++

Routine Description:

    This routine attempts to remove the specified physical address range
    from the system.

Arguments:

    StartAddress  - Supplies the starting physical address.

    NumberOfBytes  - Supplies a pointer to the number of bytes being removed.

Return Value:

    NTSTATUS.

Environment:

    Kernel mode.  PASSIVE level.  No locks held.

--*/

{
    ULONG i;
    ULONG Additional;
    PFN_NUMBER Page;
    PFN_NUMBER LastPage;
    PFN_NUMBER OriginalLastPage;
    PFN_NUMBER start;
    PFN_NUMBER PagesReleased;
    PMMPFN Pfn1;
    PMMPFN StartPfn;
    PMMPFN EndPfn;
    KIRQL OldIrql;
    PFN_NUMBER StartPage;
    PFN_NUMBER EndPage;
    PFN_COUNT NumberOfPages;
    SPFN_NUMBER MaxPages;
    PFN_NUMBER PageFrameIndex;
    PFN_NUMBER RemovedPages;
    LOGICAL Inserted;
    NTSTATUS Status;
    PMMPTE PointerPte;
    PMMPTE EndPte;
    PVOID VirtualAddress;
    PPHYSICAL_MEMORY_DESCRIPTOR OldPhysicalMemoryBlock;
    PPHYSICAL_MEMORY_DESCRIPTOR NewPhysicalMemoryBlock;
    PPHYSICAL_MEMORY_RUN NewRun;
    LOGICAL PfnDatabaseIsPhysical;

    ASSERT (KeGetCurrentIrql() == PASSIVE_LEVEL);

    ASSERT (BYTE_OFFSET(NumberOfBytes->LowPart) == 0);
    ASSERT (BYTE_OFFSET(StartAddress->LowPart) == 0);

    if (MI_IS_PHYSICAL_ADDRESS(MmPfnDatabase)) {

        //
        // The system must be configured for dynamic memory addition.  This is
        // not strictly required to remove the memory, but it's better to check
        // for it now under the assumption that the administrator is probably
        // going to want to add this range of memory back in - better to give
        // the error now and refuse the removal than to refuse the addition
        // later.
        //
    
        if (MmDynamicPfn == FALSE) {
            return STATUS_NOT_SUPPORTED;
        }

        PfnDatabaseIsPhysical = TRUE;
    }
    else {
        PfnDatabaseIsPhysical = FALSE;
    }

    StartPage = (PFN_NUMBER)(StartAddress->QuadPart >> PAGE_SHIFT);
    NumberOfPages = (PFN_COUNT)(NumberOfBytes->QuadPart >> PAGE_SHIFT);

    EndPage = StartPage + NumberOfPages;

    if (EndPage - 1 > MmHighestPossiblePhysicalPage) {

        //
        // Truncate the request into something that can be mapped by the PFN
        // database.
        //

        EndPage = MmHighestPossiblePhysicalPage + 1;
        NumberOfPages = (PFN_COUNT)(EndPage - StartPage);
    }

    //
    // The range cannot wrap.
    //

    if (StartPage >= EndPage) {
        return STATUS_INVALID_PARAMETER_1;
    }

    StartPfn = MI_PFN_ELEMENT (StartPage);
    EndPfn = MI_PFN_ELEMENT (EndPage);

    ExAcquireFastMutex (&MmDynamicMemoryMutex);

#if DBG
    MiDynmemData[0] += 1;
#endif

    //
    // Decrease all commit limits to reflect the removed memory.
    //

    ExAcquireSpinLock (&MmChargeCommitmentLock, &OldIrql);

    ASSERT (MmTotalCommitLimit <= MmTotalCommitLimitMaximum);

    if ((NumberOfPages + 100 > MmTotalCommitLimit - MmTotalCommittedPages) ||
        (MmTotalCommittedPages > MmTotalCommitLimit)) {

#if DBG
        MiDynmemData[1] += 1;
#endif
        ExReleaseSpinLock (&MmChargeCommitmentLock, OldIrql);
        ExReleaseFastMutex (&MmDynamicMemoryMutex);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    MmTotalCommitLimit -= NumberOfPages;
    MmTotalCommitLimitMaximum -= NumberOfPages;

    ExReleaseSpinLock (&MmChargeCommitmentLock, OldIrql);

    //
    // Check for outstanding promises that cannot be broken.
    //

    LOCK_PFN (OldIrql);

    MaxPages = MI_NONPAGABLE_MEMORY_AVAILABLE() - 100;

    if ((SPFN_NUMBER)NumberOfPages > MaxPages) {
#if DBG
        MiDynmemData[2] += 1;
#endif
        UNLOCK_PFN (OldIrql);
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto giveup2;
    }

    MmResidentAvailablePages -= NumberOfPages;
    MmNumberOfPhysicalPages -= NumberOfPages;

    //
    // The range must be contained in a single entry.  It is permissible for
    // it to be part of a single entry, but it must not cross multiple entries.
    //

    Additional = (ULONG)-2;

    start = 0;
    do {

        Page = MmPhysicalMemoryBlock->Run[start].BasePage;
        LastPage = Page + MmPhysicalMemoryBlock->Run[start].PageCount;

        if ((StartPage >= Page) && (EndPage <= LastPage)) {
            if ((StartPage == Page) && (EndPage == LastPage)) {
                Additional = (ULONG)-1;
            }
            else if ((StartPage == Page) || (EndPage == LastPage)) {
                Additional = 0;
            }
            else {
                Additional = 1;
            }
            break;
        }

        start += 1;

    } while (start != MmPhysicalMemoryBlock->NumberOfRuns);

    if (Additional == (ULONG)-2) {
#if DBG
        MiDynmemData[3] += 1;
#endif
        MmResidentAvailablePages += NumberOfPages;
        MmNumberOfPhysicalPages += NumberOfPages;
        UNLOCK_PFN (OldIrql);
        Status = STATUS_CONFLICTING_ADDRESSES;
        goto giveup2;
    }

    for (Pfn1 = StartPfn; Pfn1 < EndPfn; Pfn1 += 1) {
        Pfn1->u3.e1.RemovalRequested = 1;
    }

    //
    // The free and zero lists must be pruned now before releasing the PFN
    // lock otherwise if another thread allocates the page from these lists,
    // the allocation will clear the RemovalRequested flag forever.
    //

    RemovedPages = MiRemovePhysicalPages (StartPage, EndPage);

    if (RemovedPages != NumberOfPages) {

#if DBG
retry:
#endif
    
        Pfn1 = StartPfn;
    
        InterlockedIncrement (&MiDelayPageFaults);
    
        for (i = 0; i < 5; i += 1) {
    
            UNLOCK_PFN (OldIrql);
    
            //
            // Attempt to move pages to the standby list.  Note that only the
            // pages with RemovalRequested set are moved.
            //
    
            MiTrimRemovalPagesOnly = TRUE;
    
            MiEmptyAllWorkingSets ();
    
            MiTrimRemovalPagesOnly = FALSE;
    
            MiFlushAllPages ();
    
            KeDelayExecutionThread (KernelMode, FALSE, &MmHalfSecond);
    
            LOCK_PFN (OldIrql);
    
            RemovedPages += MiRemovePhysicalPages (StartPage, EndPage);
    
            if (RemovedPages == NumberOfPages) {
                break;
            }
    
            //
            // RemovedPages doesn't include pages that were freed directly to
            // the bad page list via MiDecrementReferenceCount.  So use the above
            // check purely as an optimization - and walk here when necessary.
            //
    
            for ( ; Pfn1 < EndPfn; Pfn1 += 1) {
                if (Pfn1->u3.e1.PageLocation != BadPageList) {
                    break;
                }
            }
    
            if (Pfn1 == EndPfn) {
                RemovedPages = NumberOfPages;
                break;
            }
        }

        InterlockedDecrement (&MiDelayPageFaults);
    }

    if (RemovedPages != NumberOfPages) {
#if DBG
        MiDynmemData[4] += 1;
        if (MiShowStuckPages != 0) {

            RemovedPages = 0;
            for (Pfn1 = StartPfn; Pfn1 < EndPfn; Pfn1 += 1) {
                if (Pfn1->u3.e1.PageLocation != BadPageList) {
                    RemovedPages += 1;
                }
            }

            ASSERT (RemovedPages != 0);

            DbgPrint("MmRemovePhysicalMemory : could not get %d of %d pages\n",
                RemovedPages, NumberOfPages);

            if (MiShowStuckPages & 0x2) {

                ULONG PfnsPrinted;
                ULONG EnoughShown;
                PMMPFN FirstPfn;
                PFN_COUNT PfnCount;

                PfnCount = 0;
                PfnsPrinted = 0;
                EnoughShown = 100;
    
                if (MiShowStuckPages & 0x4) {
                    EnoughShown = (ULONG)-1;
                }
    
                DbgPrint("Stuck PFN list: ");
                for (Pfn1 = StartPfn; Pfn1 < EndPfn; Pfn1 += 1) {
                    if (Pfn1->u3.e1.PageLocation != BadPageList) {
                        if (PfnCount == 0) {
                            FirstPfn = Pfn1;
                        }
                        PfnCount += 1;
                    }
                    else {
                        if (PfnCount != 0) {
                            DbgPrint("%x -> %x ; ", FirstPfn - MmPfnDatabase,
                                                    (FirstPfn - MmPfnDatabase) + PfnCount - 1);
                            PfnsPrinted += 1;
                            if (PfnsPrinted == EnoughShown) {
                                break;
                            }
                            PfnCount = 0;
                        }
                    }
                }
                if (PfnCount != 0) {
                    DbgPrint("%x -> %x ; ", FirstPfn - MmPfnDatabase,
                                            (FirstPfn - MmPfnDatabase) + PfnCount - 1);
                }
                DbgPrint("\n");
            }
            if (MiShowStuckPages & 0x8) {
                DbgBreakPoint ();
            }
            if (MiShowStuckPages & 0x10) {
                goto retry;
            }
        }
#endif
        UNLOCK_PFN (OldIrql);
        Status = STATUS_NO_MEMORY;
        goto giveup;
    }

#if DBG
    for (Pfn1 = StartPfn; Pfn1 < EndPfn; Pfn1 += 1) {
        ASSERT (Pfn1->u3.e1.PageLocation == BadPageList);
    }
#endif

    //
    // All the pages in the range have been removed.  Update the physical
    // memory blocks and other associated housekeeping.
    //

    if (Additional == 0) {

        //
        // The range can be split off from an end of an existing chunk so no
        // pool growth or shrinkage is required.
        //

        NewPhysicalMemoryBlock = MmPhysicalMemoryBlock;
        OldPhysicalMemoryBlock = NULL;
    }
    else {

        //
        // The range cannot be split off from an end of an existing chunk so
        // pool growth or shrinkage is required.
        //

        UNLOCK_PFN (OldIrql);

        i = (sizeof(PHYSICAL_MEMORY_DESCRIPTOR) +
             (sizeof(PHYSICAL_MEMORY_RUN) * (MmPhysicalMemoryBlock->NumberOfRuns + Additional)));

        NewPhysicalMemoryBlock = ExAllocatePoolWithTag (NonPagedPool,
                                                        i,
                                                        '  mM');

        if (NewPhysicalMemoryBlock == NULL) {
            Status = STATUS_INSUFFICIENT_RESOURCES;
#if DBG
            MiDynmemData[5] += 1;
#endif
            goto giveup;
        }

        OldPhysicalMemoryBlock = MmPhysicalMemoryBlock;
        RtlZeroMemory (NewPhysicalMemoryBlock, i);

        LOCK_PFN (OldIrql);
    }

    //
    // Remove or split the requested range from the existing memory block.
    //

    NewPhysicalMemoryBlock->NumberOfRuns = MmPhysicalMemoryBlock->NumberOfRuns + Additional;
    NewPhysicalMemoryBlock->NumberOfPages = MmPhysicalMemoryBlock->NumberOfPages - NumberOfPages;

    NewRun = &NewPhysicalMemoryBlock->Run[0];
    start = 0;
    Inserted = FALSE;

    do {

        Page = MmPhysicalMemoryBlock->Run[start].BasePage;
        LastPage = Page + MmPhysicalMemoryBlock->Run[start].PageCount;

        if (Inserted == FALSE) {

            if ((StartPage >= Page) && (EndPage <= LastPage)) {

                if ((StartPage == Page) && (EndPage == LastPage)) {
                    ASSERT (Additional == -1);
                    start += 1;
                    continue;
                }
                else if ((StartPage == Page) || (EndPage == LastPage)) {
                    ASSERT (Additional == 0);
                    if (StartPage == Page) {
                        MmPhysicalMemoryBlock->Run[start].BasePage += NumberOfPages;
                    }
                    MmPhysicalMemoryBlock->Run[start].PageCount -= NumberOfPages;
                }
                else {
                    ASSERT (Additional == 1);

                    OriginalLastPage = LastPage;

                    MmPhysicalMemoryBlock->Run[start].PageCount =
                        StartPage - MmPhysicalMemoryBlock->Run[start].BasePage;

                    *NewRun = MmPhysicalMemoryBlock->Run[start];
                    NewRun += 1;

                    NewRun->BasePage = EndPage;
                    NewRun->PageCount = OriginalLastPage - EndPage;
                    NewRun += 1;

                    start += 1;
                    continue;
                }

                Inserted = TRUE;
            }
        }

        *NewRun = MmPhysicalMemoryBlock->Run[start];
        NewRun += 1;
        start += 1;

    } while (start != MmPhysicalMemoryBlock->NumberOfRuns);

    //
    // Repoint the MmPhysicalMemoryBlock at the new chunk.
    // Free the old block after releasing the PFN lock.
    //

    MmPhysicalMemoryBlock = NewPhysicalMemoryBlock;

    if (EndPage - 1 == MmHighestPhysicalPage) {
        MmHighestPhysicalPage = StartPage - 1;
    }

    //
    // Throw away all the removed pages that are currently enqueued.
    //

    for (Pfn1 = StartPfn; Pfn1 < EndPfn; Pfn1 += 1) {

        ASSERT (Pfn1->u3.e1.PageLocation == BadPageList);
        ASSERT (Pfn1->u3.e1.RemovalRequested == 1);

        MiUnlinkPageFromList (Pfn1);

        ASSERT (Pfn1->u1.Flink == 0);
        ASSERT (Pfn1->u2.Blink == 0);
        ASSERT (Pfn1->u3.e2.ReferenceCount == 0);
        ASSERT64 (Pfn1->UsedPageTableEntries == 0);

        Pfn1->PteAddress = PFN_REMOVED;
        Pfn1->u3.e2.ShortFlags = 0;
        Pfn1->OriginalPte.u.Long = ZeroKernelPte.u.Long;
        Pfn1->PteFrame = 0;
    }

    //
    // Now that the removed pages have been discarded, eliminate the PFN
    // entries that mapped them.  Straddling entries left over from an
    // adjacent earlier removal are not collapsed at this point.
    //
    //

    PagesReleased = 0;

    if (PfnDatabaseIsPhysical == FALSE) {

        VirtualAddress = (PVOID)ROUND_TO_PAGES(MI_PFN_ELEMENT(StartPage));
        PointerPte = MiGetPteAddress (VirtualAddress);
        EndPte = MiGetPteAddress (PAGE_ALIGN(MI_PFN_ELEMENT(EndPage)));

        while (PointerPte < EndPte) {
            PageFrameIndex = MI_GET_PAGE_FRAME_FROM_PTE (PointerPte);
            Pfn1 = MI_PFN_ELEMENT (PageFrameIndex);
            ASSERT (Pfn1->u2.ShareCount == 1);
            ASSERT (Pfn1->u3.e2.ReferenceCount == 1);
            Pfn1->u2.ShareCount = 0;
            MI_SET_PFN_DELETED (Pfn1);
#if DBG
            Pfn1->u3.e1.PageLocation = StandbyPageList;
#endif //DBG
            MiDecrementReferenceCount (PageFrameIndex);
    
            KeFlushSingleTb (VirtualAddress,
                             TRUE,
                             TRUE,
                             (PHARDWARE_PTE)PointerPte,
                             ZeroKernelPte.u.Flush);
    
            PagesReleased += 1;
            PointerPte += 1;
            VirtualAddress = (PVOID)((PCHAR)VirtualAddress + PAGE_SIZE);
        }

        MmResidentAvailablePages += PagesReleased;
    }

#if DBG
    MiDynmemData[6] += 1;
#endif

    UNLOCK_PFN (OldIrql);

    if (PagesReleased != 0) {
        MiReturnCommitment (PagesReleased);
    }

    ExReleaseFastMutex (&MmDynamicMemoryMutex);

    if (OldPhysicalMemoryBlock != NULL) {
        ExFreePool (OldPhysicalMemoryBlock);
    }

    NumberOfBytes->QuadPart = (ULONGLONG)NumberOfPages * PAGE_SIZE;

    return STATUS_SUCCESS;

giveup:

    //
    // All the pages in the range were not obtained.  Back everything out.
    //

    PageFrameIndex = StartPage;
    Pfn1 = MI_PFN_ELEMENT (PageFrameIndex);

    LOCK_PFN (OldIrql);

    while (PageFrameIndex < EndPage) {

        ASSERT (Pfn1->u3.e1.RemovalRequested == 1);

        Pfn1->u3.e1.RemovalRequested = 0;

        if ((Pfn1->u3.e1.PageLocation == BadPageList) &&
            (Pfn1->u3.e1.ParityError == 0)) {

            MiUnlinkPageFromList (Pfn1);
            MiInsertPageInList (MmPageLocationList[FreePageList],
                                PageFrameIndex);
        }

        Pfn1 += 1;
        PageFrameIndex += 1;
    }

    MmResidentAvailablePages += NumberOfPages;
    MmNumberOfPhysicalPages += NumberOfPages;

    UNLOCK_PFN (OldIrql);

giveup2:

    ExAcquireSpinLock (&MmChargeCommitmentLock, &OldIrql);
    MmTotalCommitLimit += NumberOfPages;
    MmTotalCommitLimitMaximum += NumberOfPages;
    ExReleaseSpinLock (&MmChargeCommitmentLock, OldIrql);

    ExReleaseFastMutex (&MmDynamicMemoryMutex);

    return Status;
}
Esempio n. 18
0
int FS_NormalCase()
{
    int NumErrors = 0;            // error count - to be returned
    int rc;                       // return code


#ifdef PERF

  DbgBreakPoint();

#endif


    //
    //  cbDest = 0.
    //

    //  Variation 1  -  cbSrc = -1
    rc = FoldStringW( MAP_PRECOMPOSED,
                      FoldSrc1,
                      -1,
                      FoldDest,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       FoldSrc1,
                       "cbDest (0) cbSrc (-1)",
                       &NumErrors );

    //  Variation 2  -  cbSrc = value
    rc = FoldStringW( MAP_PRECOMPOSED,
                      FoldSrc1,
                      WC_STRING_LEN_NULL(FoldSrc1),
                      FoldDest,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       FoldSrc1,
                       "cbDest (0) cbSrc (value)",
                       &NumErrors );

    //  Variation 3  -  lpDestStr = NULL
    rc = FoldStringW( MAP_PRECOMPOSED,
                      FoldSrc1,
                      -1,
                      NULL,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       FoldSrc1,
                       "cbDest (0) lpDestStr NULL",
                       &NumErrors );


    //
    //  cbSrc.
    //

    //  Variation 1  -  cbSrc = -1
    rc = FoldStringW( MAP_PRECOMPOSED,
                      FoldSrc1,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       FoldSrc1,
                       "cbSrc (-1)",
                       &NumErrors );

    //  Variation 2  -  cbSrc = value
    rc = FoldStringW( MAP_PRECOMPOSED,
                      FoldSrc1,
                      WC_STRING_LEN(FoldSrc1),
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       WC_STRING_LEN(FoldSrc1),
                       FoldDest,
                       FoldSrc1,
                       "cbSrc (value)",
                       &NumErrors );

    //  Variation 3  -  cbSrc = -1, no DestStr
    rc = FoldStringW( MAP_PRECOMPOSED,
                      FoldSrc1,
                      -1,
                      NULL,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       FoldSrc1,
                       "cbSrc (-1), no DestStr",
                       &NumErrors );

    //  Variation 4  -  cbSrc = value, no DestStr
    rc = FoldStringW( MAP_PRECOMPOSED,
                      FoldSrc1,
                      WC_STRING_LEN(FoldSrc1),
                      NULL,
                      0 );
    CheckReturnValidW( rc,
                       WC_STRING_LEN(FoldSrc1),
                       NULL,
                       FoldSrc1,
                       "cbSrc (value), no DestStr",
                       &NumErrors );


    //
    //  MAP_PRECOMPOSED Flag.
    //

    //  Variation 1  -  precomposed
    rc = FoldStringW( MAP_PRECOMPOSED,
                      FoldSrc2,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       FoldSrc2,
                       "precomposed",
                       &NumErrors );

    //  Variation 2  -  precomposed
    rc = FoldStringW( MAP_PRECOMPOSED,
                      L"\x006e\x0303",
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x00f1",
                       "precomposed (n tilde)",
                       &NumErrors );

    //  Variation 3  -  precomposed
    rc = FoldStringW( MAP_PRECOMPOSED,
                      L"\x006e\x0303",
                      -1,
                      NULL,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       L"\x00f1",
                       "precomposed (n tilde), no DestStr",
                       &NumErrors );

    //  Variation 4  -  precomposed
    rc = FoldStringW( MAP_PRECOMPOSED,
                      L"\x0062\x0303",
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x0062\x0303",
                       "precomposed (b tilde)",
                       &NumErrors );

    //  Variation 5  -  precomposed
    rc = FoldStringW( MAP_PRECOMPOSED,
                      L"\x0062\x0303",
                      -1,
                      NULL,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       L"\x0062\x0303",
                       "precomposed (b tilde), no DestStr",
                       &NumErrors );


    //
    //  MAP_COMPOSITE Flag.
    //

    //  Variation 1  -  composite
    rc = FoldStringW( MAP_COMPOSITE,
                      FoldSrc2,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       FoldSrc2,
                       "composite",
                       &NumErrors );

    //  Variation 2  -  composite
    rc = FoldStringW( MAP_COMPOSITE,
                      L"\x00f1",
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x006e\x0303",
                       "composite (n tilde)",
                       &NumErrors );

    //  Variation 3  -  composite
    rc = FoldStringW( MAP_COMPOSITE,
                      L"\x00f1",
                      -1,
                      NULL,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       L"\x006e\x0303",
                       "composite (n tilde), no DestStr",
                       &NumErrors );

    //  Variation 4  -  composite
    rc = FoldStringW( MAP_COMPOSITE,
                      L"\x01c4",
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x0044\x017d",
                       "composite (dz hacek)",
                       &NumErrors );

    //  Variation 5  -  composite
    rc = FoldStringW( MAP_COMPOSITE,
                      L"\x01c4",
                      -1,
                      NULL,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       L"\x0044\x017d",
                       "composite (dz hacek), no DestStr",
                       &NumErrors );

    //  Variation 6  -  composite
    rc = FoldStringW( MAP_COMPOSITE,
                      L"\x0062\x0303",
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x0062\x0303",
                       "composite (b tilde)",
                       &NumErrors );

    //  Variation 7  -  composite
    rc = FoldStringW( MAP_COMPOSITE,
                      L"\x0062\x0303",
                      -1,
                      NULL,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       L"\x0062\x0303",
                       "composite (b tilde), no DestStr",
                       &NumErrors );


    //
    //  MAP_FOLDCZONE Flag.
    //

    //  Variation 1  -  fold compatibility zone
    rc = FoldStringW( MAP_FOLDCZONE,
                      FoldSrc2,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       FoldSrc2,
                       "fold czone",
                       &NumErrors );

    //  Variation 2  -  fold compatibility zone
    rc = FoldStringW( MAP_FOLDCZONE,
                      L"\x004a\xff24\xff22",
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x004a\x0044\x0042",
                       "fold czone (JDB)",
                       &NumErrors );

    //  Variation 3  -  fold compatibility zone
    rc = FoldStringW( MAP_FOLDCZONE,
                      L"\x004a\xff24\xff22",
                      -1,
                      NULL,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       L"\x004a\x0044\x0042",
                       "fold czone (JDB), no DestStr",
                       &NumErrors );


    //
    //  MAP_FOLDDIGITS Flag.
    //

    //  Variation 1  -  fold digits
    rc = FoldStringW( MAP_FOLDDIGITS,
                      FoldSrc2,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       FoldSrc2,
                       "fold digits",
                       &NumErrors );

    //  Variation 2  -  fold digits
    rc = FoldStringW( MAP_FOLDDIGITS,
                      L"\x00b2\x00b3",
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x0032\x0033",
                       "fold digits (23)",
                       &NumErrors );

    //  Variation 3  -  fold digits
    rc = FoldStringW( MAP_FOLDDIGITS,
                      L"\x00b2\x00b3",
                      -1,
                      NULL,
                      0 );
    CheckReturnValidW( rc,
                       -1,
                       NULL,
                       L"\x0032\x0033",
                       "fold digits (23), no DestStr",
                       &NumErrors );



    //
    //  Check precomposed with multiple diacritics.
    //
    //  Variation 1  -  precomp, multi diacritics
    rc = FoldStringW( MAP_PRECOMPOSED,
                      wcMultiComp,
                      3,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       2,
                       FoldDest,
                       L"\x00e9\x0300",
                       "precomp, multi diacritics",
                       &NumErrors );

    //  Variation 2  -  precomp, czone
    rc = FoldStringW( MAP_PRECOMPOSED | MAP_FOLDCZONE,
                      wcCompDigitCZone,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x00e9\x0300\x00b2\x003c",
                       "precomp, czone",
                       &NumErrors );

    //  Variation 3  -  precomp, digits
    rc = FoldStringW( MAP_PRECOMPOSED | MAP_FOLDDIGITS,
                      wcCompDigitCZone,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x00e9\x0300\x0032\xfe64",
                       "precomp, digits",
                       &NumErrors );

    //  Variation 4  -  precomp, czone, digits
    rc = FoldStringW( MAP_PRECOMPOSED | MAP_FOLDCZONE | MAP_FOLDDIGITS,
                      wcCompDigitCZone,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x00e9\x0300\x0032\x003c",
                       "precomp, czone, digits",
                       &NumErrors );


    //
    //  Check composite.
    //

    //  Variation 1  -  comp, czone
    rc = FoldStringW( MAP_COMPOSITE | MAP_FOLDCZONE,
                      wcPrecompDigitCZone,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x0065\x0301\x0300\x00b2\x003c",
                       "comp, czone",
                       &NumErrors );

    //  Variation 2  -  comp, digits
    rc = FoldStringW( MAP_COMPOSITE | MAP_FOLDDIGITS,
                      wcPrecompDigitCZone,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x0065\x0301\x0300\x0032\xfe64",
                       "comp, digits",
                       &NumErrors );

    //  Variation 3  -  comp, czone, digits
    rc = FoldStringW( MAP_COMPOSITE | MAP_FOLDCZONE | MAP_FOLDDIGITS,
                      wcPrecompDigitCZone,
                      -1,
                      FoldDest,
                      BUFSIZE );
    CheckReturnValidW( rc,
                       -1,
                       FoldDest,
                       L"\x0065\x0301\x0300\x0032\x003c",
                       "comp, czone, digits",
                       &NumErrors );


    //
    //  Return total number of errors found.
    //
    return (NumErrors);
}
Esempio n. 19
0
VOID
CollectFrameWalkStatistics (

    ULONG Index)

/*++

Routine description:

    CollectFrameWalkStatistics

Description:

    This function computes the distribution of detectable chain
    lengths. This is used only for debugging the frame traversal
    algorithm. It proves that it is worth trying to get stack
    traces on optimized images because only about 8% of the calls
    cannot be resolved to more than two callers. A sample distribution
    computed by calling RtlWalkFrameChain for every call to
    ExAllocatePoolWithTag gave the results below:

         Length       Percentage
         0-2          5%
         3-5          20%
         6-10         40%
         10-16        35%

    With a failure rate of 5% it is worth using it.

--*/

{
    KIRQL PreviousIrql;
    ULONG I;
    ULONG Percentage;
    ULONG TotalPercentage;

    //
    // Spin lock initialization is not safe in the code below
    // but this code is used only during frame walk algorithm
    // development so there is no reason to make it bulletproof.
    //

    if (! FrameWalkStatisticsInitialized) {
        KeInitializeSpinLock (&FrameWalkStatisticsLock);
        FrameWalkStatisticsInitialized = TRUE;
    }

    KeAcquireSpinLock (
        &FrameWalkStatisticsLock,
        &PreviousIrql);

    FrameWalkCollectStatisticsCalls++;

    if (Index < 32) {
        FrameWalkStatisticsCounters[Index]++;
    }

    if (FrameWalkCollectStatisticsCalls != 0
        && (FrameWalkCollectStatisticsCalls % 60000 == 0)) {

        DbgPrint ("FrameWalk: %u calls \n", FrameWalkCollectStatisticsCalls);

        TotalPercentage = 0;

        for (I = 0; I < 32; I++) {

            Percentage = FrameWalkStatisticsCounters[I] * 100
                / FrameWalkCollectStatisticsCalls;

            DbgPrint ("FrameWalk: [%02u] %02u \n", I, Percentage);

            TotalPercentage += Percentage;
        }

        DbgPrint ("FrameWalk: total %u \n", TotalPercentage);
        DbgBreakPoint ();
    }

    KeReleaseSpinLock (
        &FrameWalkStatisticsLock,
        PreviousIrql);
}
Esempio n. 20
0
BOOL xxxActivateDebugger(
    UINT fsModifiers)
{
    ULONG ArgLength;
    USER_API_MSG m;
    PACTIVATEDEBUGGERMSG a = &m.u.ActivateDebugger;
    PEPROCESS Process;
    HANDLE hDebugPort;
    NTSTATUS Status;

    if (fsModifiers & MOD_CONTROL) {
#ifdef DEBUG
        if (RipOutput(0, RIP_WARNING, "User debugger", 0, "Debug prompt", NULL)) {
            DbgBreakPoint();
        }
#endif
        return FALSE;
    } else if (fsModifiers & MOD_SHIFT) {

        /*
         * Bail out if the process is not being debugged.
         */
        if (gpepCSRSS->DebugPort == NULL)
            return FALSE;

        a->ClientId.UniqueProcess = gpepCSRSS->UniqueProcessId;
    } else {

        if ((gpqForeground == NULL) || (gpqForeground->ptiKeyboard == NULL))
            return FALSE;

        a->ClientId = gpqForeground->ptiKeyboard->Thread->Cid;

        /*
         * Bail out if the process is not being debugged.
         */
        if (!NT_SUCCESS(LockProcessByClientId(a->ClientId.UniqueProcess,
                &Process)))
            return FALSE;
        hDebugPort = Process->DebugPort;
        UnlockProcess(Process);

        if (hDebugPort == NULL)
            return FALSE;
    }

    /*
     * Send the datagram to CSR
     */
    if (CsrApiPort != NULL) {
        ArgLength = sizeof(*a);
        ArgLength |= (ArgLength << 16);
        ArgLength +=     ((sizeof( CSR_API_MSG ) - sizeof( m.u )) << 16) |
                        (FIELD_OFFSET( CSR_API_MSG, u ) - sizeof( m.h ));
        m.h.u1.Length = ArgLength;
        m.h.u2.ZeroInit = 0;
        m.CaptureBuffer = NULL;
        m.ApiNumber = CSR_MAKE_API_NUMBER( USERSRV_SERVERDLL_INDEX,
                                           UserpActivateDebugger);
        LeaveCrit();
        Status = LpcRequestPort(CsrApiPort, (PPORT_MESSAGE)&m);
        EnterCrit();
        UserAssert(NT_SUCCESS(Status));
    }

    /*
     * Don't eat this event unless we are breaking into CSR! Since we have
     * choosen an arbitrary hot key like F12 for the debug key, we need to
     * pass on the key to the application, or apps that want this key would
     * never see it. If we had an api for installing a debug hot key
     * (export or MOD_DEBUG flag to RegisterHotKey()), then it would be ok
     * to eat because the user selected the hot key. But it is not ok to
     * eat it as long as we've picked an arbitrary hot key. scottlu.
     */
    if (fsModifiers & MOD_SHIFT)
        return TRUE;
    else
        return FALSE;
}
Esempio n. 21
0
BOOLEAN NTAPI
i8042KbdInterruptService(
	IN PKINTERRUPT Interrupt,
	PVOID Context)
{
	PI8042_KEYBOARD_EXTENSION DeviceExtension;
	PPORT_DEVICE_EXTENSION PortDeviceExtension;
	PKEYBOARD_INPUT_DATA InputData;
	ULONG Counter;
	UCHAR PortStatus = 0, Output = 0;
	BOOLEAN ToReturn = FALSE;
	NTSTATUS Status;

	UNREFERENCED_PARAMETER(Interrupt);

	DeviceExtension = (PI8042_KEYBOARD_EXTENSION)Context;
	PortDeviceExtension = DeviceExtension->Common.PortDeviceExtension;
	InputData = DeviceExtension->KeyboardBuffer + DeviceExtension->KeysInBuffer;
	Counter = PortDeviceExtension->Settings.PollStatusIterations;

	while (Counter)
	{
		Status = i8042ReadStatus(PortDeviceExtension, &PortStatus);
		if (!NT_SUCCESS(Status))
		{
			WARN_(I8042PRT, "i8042ReadStatus() failed with status 0x%08lx\n", Status);
			return FALSE;
		}
		Status = i8042ReadKeyboardData(PortDeviceExtension, &Output);
		if (NT_SUCCESS(Status))
			break;
		KeStallExecutionProcessor(1);
		Counter--;
	}
	if (Counter == 0)
	{
		WARN_(I8042PRT, "Spurious i8042 keyboard interrupt\n");
		return FALSE;
	}

	INFO_(I8042PRT, "Got: 0x%02x\n", Output);

	if (PortDeviceExtension->Settings.CrashOnCtrlScroll)
	{
		/* Test for CTRL + SCROLL LOCK twice */
		static const UCHAR ScanCodes[] = { 0x1d, 0x46, 0xc6, 0x46, 0 };

		if (Output == ScanCodes[DeviceExtension->ComboPosition])
		{
			DeviceExtension->ComboPosition++;
			if (ScanCodes[DeviceExtension->ComboPosition] == 0)
				KeBugCheck(MANUALLY_INITIATED_CRASH);
		}
		else if (Output == 0xfa)
		{
		    /* Ignore ACK */
		}
		else if (Output == ScanCodes[0])
			DeviceExtension->ComboPosition = 1;
		else
			DeviceExtension->ComboPosition = 0;

		/* Test for TAB + key combination */
		if (InputData->MakeCode == 0x0F)
			DeviceExtension->TabPressed = !(InputData->Flags & KEY_BREAK);
		else if (DeviceExtension->TabPressed)
		{
			DeviceExtension->TabPressed = FALSE;

            /* Check which action to do */
            if (InputData->MakeCode == 0x25)
            {
                /* k - Breakpoint */
                DbgBreakPoint();
            }
            else if (InputData->MakeCode == 0x30)
            {
                /* b - Bugcheck */
                KeBugCheck(MANUALLY_INITIATED_CRASH);
            }
            else
            {
			    /* Send request to the kernel debugger.
			     * Unknown requests will be ignored. */
			    KdSystemDebugControl(' soR',
			                         (PVOID)(ULONG_PTR)InputData->MakeCode,
			                         0,
			                         NULL,
			                         0,
			                         NULL,
			                         KernelMode);
            }
		}
	}

	if (i8042KbdCallIsrHook(DeviceExtension, PortStatus, Output, &ToReturn))
		return ToReturn;

	if (i8042PacketIsr(PortDeviceExtension, Output))
	{
		if (PortDeviceExtension->PacketComplete)
		{
			TRACE_(I8042PRT, "Packet complete\n");
			KeInsertQueueDpc(&DeviceExtension->DpcKeyboard, NULL, NULL);
		}
		TRACE_(I8042PRT, "Irq eaten by packet\n");
		return TRUE;
	}

	TRACE_(I8042PRT, "Irq is keyboard input\n");

	if (DeviceExtension->KeyboardScanState == Normal)
	{
		switch (Output)
		{
			case 0xe0:
				DeviceExtension->KeyboardScanState = GotE0;
				return TRUE;
			case 0xe1:
				DeviceExtension->KeyboardScanState = GotE1;
				return TRUE;
			default:
				break;
		}
	}

	/* Update InputData */
	InputData->Flags = 0;
	switch (DeviceExtension->KeyboardScanState)
	{
		case GotE0:
			InputData->Flags |= KEY_E0;
			break;
		case GotE1:
			InputData->Flags |= KEY_E1;
			break;
		default:
			break;
	}
	DeviceExtension->KeyboardScanState = Normal;
	if (Output & 0x80)
		InputData->Flags |= KEY_BREAK;
	else
		InputData->Flags |= KEY_MAKE;
	InputData->MakeCode = Output & 0x7f;
	InputData->Reserved = 0;

	DeviceExtension->KeyboardHook.QueueKeyboardPacket(DeviceExtension->KeyboardHook.CallContext);

	return TRUE;
}
Esempio n. 22
0
NTSTATUS
ReinjectPendedPacket(
	IN PENDED_PACKET *packet,
	IN FLOW_DATA *flowData)
{
	NTSTATUS status;
	UINT32 flags;
	NET_BUFFER_LIST* netBufferList = NULL;
	FLOW_DATA *flowCtx;
	ULONG dataLength;

	if(packet->dataLength == 0 || packet->data == NULL)
	{
		return STATUS_UNSUCCESSFUL;
	}

	packet->mdl = IoAllocateMdl(
		packet->data,
		packet->dataLength,
		FALSE,
		FALSE,
		NULL);
	
	if (packet->mdl == NULL)
	{
		status = STATUS_NO_MEMORY;
		goto Exit;
	}

	MmBuildMdlForNonPagedPool(packet->mdl);
	
	status = FwpsAllocateNetBufferAndNetBufferList(
						gNetBufferListPool,
						0,
						0,
						packet->mdl,
						0,
						packet->dataLength,
						&netBufferList);

	if(!NT_SUCCESS(status))
	{
		goto Exit;
	}

	flags = packet->flags;
	dataLength = packet->dataLength;
	flowCtx = packet->flowContext;

#ifdef DEBUG
	debugPacket(packet);
	DbgPrintEx(
		DPFLTR_IHVNETWORK_ID,
		DPFLTR_ERROR_LEVEL,
		"\n localCtr=%d, remoteCtr=%d\n", flowCtx->localCounter, flowCtx->remoteCounter);
#endif

	// Keep correct sequence numbers
	// (Assume every reinjection is successful, otherwise synchronous injection is
	// needed for consistent sequence numbers implementation)
	if(flags & FWPS_STREAM_FLAG_SEND)
	{
		flowCtx->localCounter += dataLength;
	}
	else if(flags & FWPS_STREAM_FLAG_RECEIVE)
	{
		flowCtx->remoteCounter += dataLength;
	}
	else
	{
#ifdef DEBUG
		DbgBreakPoint();
#endif
	}

	status = FwpsStreamInjectAsync(
		gInjectionHandle,
		NULL,
		0,
		flowData->flowHandle,
		gStreamCalloutIdV4,
		FWPS_LAYER_STREAM_V4,
		flags, 
		netBufferList,
		packet->dataLength,
		StreamInjectCompletionFn,
		packet);

	if (!NT_SUCCESS(status))
	{
		goto Exit;
	}

	// Ownership transferred
	netBufferList = NULL;
	packet = NULL;

	

Exit:

	if (netBufferList != NULL)
	{
		FwpsFreeNetBufferList(netBufferList);
	}

	if (packet != NULL)
	{
		FreePendedPacket(packet);
	}

	return status;
}
Esempio n. 23
0
NTSTATUS
TtdiOpenConnection (IN PHANDLE FileHandle, IN ULONG ConnectionContext)
{
    IO_STATUS_BLOCK IoStatusBlock;
    NTSTATUS Status;
    UNICODE_STRING NameString;
    OBJECT_ATTRIBUTES ObjectAttributes;
    PFILE_FULL_EA_INFORMATION EaBuffer;
    int i;

    DbgPrint ("TtdiOpenConnection: Opening Context %lx...\n ",
        ConnectionContext);
    RtlInitUnicodeString (&NameString, TRANSPORT_NAME);
    InitializeObjectAttributes (
        &ObjectAttributes,
        &NameString,
        0,
        NULL,
        NULL);

    EaBuffer = (PFILE_FULL_EA_INFORMATION)ExAllocatePool (NonPagedPool, 100);
    if (EaBuffer == NULL) {
        DbgBreakPoint ();
    }

    EaBuffer->NextEntryOffset =0;
    EaBuffer->Flags = 0;
    EaBuffer->EaNameLength = TDI_CONNECTION_CONTEXT_LENGTH;
    EaBuffer->EaValueLength = sizeof (ULONG);
    for (i=0;i<(int)EaBuffer->EaNameLength;i++) {
        EaBuffer->EaName[i] = TdiConnectionContext[i];
    }

    RtlMoveMemory (
        &EaBuffer->EaName[EaBuffer->EaValueLength + 1],
        &ConnectionContext,
        sizeof (PVOID));

    Status = NtCreateFile (
                 FileHandle,
                 0,
                 &ObjectAttributes,     // object attributes.
                 &IoStatusBlock,        // returned status information.
                 0,                     // block size (unused).
                 FO_SYNCHRONOUS_IO,     // file attributes.
                 0,
                 0,
                 0,                     // create options.
                 EaBuffer,                  // EA buffer.
                 100);                    // EA length.

    if (!NT_SUCCESS( Status )) {
        DbgPrint ("TtdiOpenConnection:  FAILURE, NtCreateFile returned status code=%lC.\n", Status);
        return Status;
    }

    Status = IoStatusBlock.Status;

    if (!(NT_SUCCESS( Status ))) {
        DbgPrint ("TtdiOpenConnection:  FAILURE, IoStatusBlock.Status contains status code=%lC.\n", Status);
    }

    DbgPrint ("TtdiOpenConnection:  returning\n");

    return Status;
} /* TtdiOpenEndpoint */
Esempio n. 24
0
DWORD
main(
    int argc,
    char *argv[],
    char *envp[]
    )
{
    int i;
    HANDLE hMod,x;
    CHAR Buff[256];
    PCHAR s;
    FARPROC f;
    DWORD Version;
    HANDLE Handle;
    DWORD  rc;
    STARTUPINFO StartupInfo;


    GetStartupInfo(&StartupInfo);
    printf("Title %s\n",StartupInfo.lpTitle);


    printf( "TBASE: Entering Test Program\n" );

    assert(GetModuleFileName(0,Buff,256) < 255);
    printf("Image Name %s\n",Buff);
#if 0
    printf( "argc: %ld\n", argc );
    for (i=0; i<argc; i++) {
        printf( "argv[ %3ld ]: '%s'\n", i, argv[ i ] );
        }

    for (i=0; envp[ i ]; i++) {
        printf( "envp[ %3ld ]: %s\n", i, envp[ i ] );
        }

    DbgBreakPoint();

    s = "ync ""Yes or No""";
    printf( "Invoking: '%s'\nResult: %d\n", s, system(s) );

    TestEnvironment();
    for (i=1; i<=256; i++) {
        rc = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
                            NULL,
                            i, NULL, sizeof( Buff ), (va_list *)Inserts );
        if (rc != 0) {
            rc = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY, NULL,
                                i, Buff, rc, (va_list *)Inserts );
            if (rc != 0) {
                cprintf( "SYS%05u: %s\r\n", i, Buff );
                }
            }
        }

    Handle = CreateFile( "\\config.sys",
                         GENERIC_READ,
                         FILE_SHARE_READ | FILE_SHARE_WRITE,
                         NULL,
                         OPEN_EXISTING,
                         0,
                         NULL
                       );
    if (Handle != INVALID_HANDLE_VALUE) {
        printf( "CreateFile successful, handle = %lX\n", Handle );
        }
    else {
        printf( "CreateFile failed\n" );
        }

    rc = SetFilePointer(Handle, 0, NULL, FILE_END);
    if (rc != -1) {
        printf( "File size = %ld\n", rc );
        }
    else {
        printf( "SetFilePointer failed\n" );
        }

    Version = GetVersion();
    assert( (Version & 0x0000ffff) == 4);
    assert( (Version >> 16) == 0);
#endif
    hMod = LoadLibrary("dbgdll");
    assert(hMod);
    assert(hMod == GetModuleHandle("dbgdll"));

    hMod = LoadLibrary("c:\\nt\\dll\\csr.dll");
    assert(hMod);

    assert(GetModuleFileName(hMod,Buff,256) == strlen("c:\\nt\\dll\\csr.dll")+1);
    assert(_strcmpi(Buff,"c:\\nt\\dll\\csr.dll") == 0 );

    hMod = LoadLibrary("nt\\dll\\csrrtl.dll");
    assert(hMod);

    x = LoadLibrary("csrrtl");
    assert( x && x == hMod);
    assert(FreeLibrary(x));
    assert(FreeLibrary(x));
    hMod = GetModuleHandle("csrrtl");
    assert(hMod == NULL);
    x = LoadLibrary("csrrtl");
    assert( x );
    assert(FreeLibrary(x));

    hMod = LoadLibrary("kernel32");
    assert(hMod);

    f = GetProcAddress(hMod,"GetProcAddress");
    assert(f);
    assert(f == (f)(hMod,"GetProcAddress"));
    assert(f == MakeProcInstance(f,hMod));
    FreeProcInstance(f);
    DebugBreak();
    assert(FreeLibrary(hMod));

//    hMod = LoadLibrary("baddll");
//    assert(!hMod);

    printf( "TBASE: Exiting Test Program\n" );

    return 0;
}
Esempio n. 25
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    The entry point that the system point calls to initialize
    any driver.

Arguments:

    DriverObject - Just what it says,  really of little use
    to the driver itself, it is something that the IO system
    cares more about.

    PathToRegistry - points to the entry for this driver
    in the current control set of the registry.

Return Value:

    Always STATUS_SUCCESS

--*/

{
    WDF_DRIVER_CONFIG config;
    WDFDRIVER hDriver;
    NTSTATUS status;
    WDF_OBJECT_ATTRIBUTES attributes;

    //
    // Initialize WPP Tracing
    //
    WPP_INIT_TRACING( DriverObject, RegistryPath );

    SerialDbgPrintEx(TRACE_LEVEL_INFORMATION, DBG_INIT,
                    "Serial Sample (WDF Version)\n");
    //
    // Register a cleanup callback so that we can call WPP_CLEANUP when
    // the framework driver object is deleted during driver unload.
    //
    WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
    attributes.EvtCleanupCallback = SerialEvtDriverContextCleanup;

    WDF_DRIVER_CONFIG_INIT(&config, SerialEvtDeviceAdd);

    status = WdfDriverCreate(DriverObject,
                           RegistryPath,
                           &attributes,
                           &config,
                           &hDriver);
    if (!NT_SUCCESS(status)) {
        SerialDbgPrintEx(TRACE_LEVEL_ERROR, DBG_INIT,
                         "WdfDriverCreate failed with status 0x%x\n",
                         status);
        //
        // Cleanup tracing here because DriverContextCleanup will not be called
        // as we have failed to create WDFDRIVER object itself.
        // Please note that if your return failure from DriverEntry after the
        // WDFDRIVER object is created successfully, you don't have to
        // call WPP cleanup because in those cases DriverContextCleanup
        // will be executed when the framework deletes the DriverObject.
        //
        WPP_CLEANUP(DriverObject);
        return status;
    }

    //
    // Call to find out default values to use for all the devices that the
    // driver controls, including whether or not to break on entry.
    //

    SerialGetConfigDefaults(&driverDefaults, hDriver);

    //
    // Break on entry if requested via registry
    //
    if (driverDefaults.ShouldBreakOnEntry) {
        DbgBreakPoint();
    }


    return status;
}
Esempio n. 26
0
VOID
MiDeleteVirtualAddresses (
    IN PUCHAR StartingAddress,
    IN PUCHAR EndingAddress,
    IN ULONG AddressSpaceDeletion,
    IN PMMVAD Vad
    )

/*++

Routine Description:

    This routine deletes the specified virtual address range within
    the current process.

Arguments:

    StartingAddress - Supplies the first virtual address to delete.

    EndingAddress - Supplies the last address to delete.

    AddressSpaceDeletion - Supplies TRUE if the address space is being
                           deleted, FALSE otherwise.  If TRUE is specified
                           the TB is not flushed and valid addresses are
                           not removed from the working set.

    Vad - Supplies the virtual address descriptor which maps this range
          or NULL if we are not concerned about views.  From the Vad the
          range of prototype PTEs is determined and this information is
          used to uncover if the PTE refers to a prototype PTE or a
          fork PTE.

Return Value:

    None.


Environment:

    Kernel mode, called with APCs disabled working set mutex and PFN lock
    held.  These mutexes may be released and reacquired to fault pages in.

--*/

{
    PUCHAR Va;
    PVOID TempVa;
    PMMPTE PointerPte;
    PMMPTE PointerPde;
    PMMPTE OriginalPointerPte;
    PMMPTE ProtoPte;
    PMMPTE LastProtoPte;
    PEPROCESS CurrentProcess;
    ULONG FlushTb = FALSE;
    PSUBSECTION Subsection;
    PUSHORT UsedPageTableCount;
    KIRQL OldIrql = APC_LEVEL;
    MMPTE_FLUSH_LIST FlushList;

    FlushList.Count = 0;

    MM_PFN_LOCK_ASSERT();
    CurrentProcess = PsGetCurrentProcess();

    Va = StartingAddress;
    PointerPde = MiGetPdeAddress (Va);
    PointerPte = MiGetPteAddress (Va);
    OriginalPointerPte = PointerPte;
    UsedPageTableCount =
            &MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Va)];

    while (MiDoesPdeExistAndMakeValid (PointerPde,
                                       CurrentProcess,
                                       TRUE)           ==  FALSE) {

        //
        // This page directory entry is empty, go to the next one.
        //

        PointerPde += 1;
        PointerPte = MiGetVirtualAddressMappedByPte (PointerPde);
        Va = MiGetVirtualAddressMappedByPte (PointerPte);

        if (Va > EndingAddress) {

            //
            // All done, return.
            //

            return;

        }
        UsedPageTableCount += 1;
    }

    //
    // A valid PDE has been located, examine each PTE and delete them.
    //

    if ((Vad == (PMMVAD)NULL) ||
        (Vad->u.VadFlags.PrivateMemory) ||
        (Vad->FirstPrototypePte == (PMMPTE)NULL)) {
        ProtoPte = (PMMPTE)NULL;
        LastProtoPte = (PMMPTE)NULL;
    } else {
        ProtoPte = Vad->FirstPrototypePte;
        LastProtoPte = (PMMPTE)4;
    }

    //
    // Examine each PTE within the address range and delete it.
    //

    while (Va <= EndingAddress) {

        if (((ULONG)Va & PAGE_DIRECTORY_MASK) == 0) {

            //
            // Note, the initial address could be aligned on a 4mb boundary.
            //

            //
            // The virtual address is on a page directory (4mb) boundary,
            // check the next PDE for validity and flush PTEs for previous
            // page table page.
            //

            MiFlushPteList (&FlushList, FALSE, ZeroPte);

            //
            // If all the entries have been eliminated from the previous
            // page table page, delete the page table page itself.
            //

            if ((*UsedPageTableCount == 0) && (PointerPde->u.Long != 0)) {

                TempVa = MiGetVirtualAddressMappedByPte(PointerPde);
                MiDeletePte (PointerPde,
                             TempVa,
                             AddressSpaceDeletion,
                             CurrentProcess,
                             NULL,
                             NULL);
            }

            //
            // Release the PFN lock.  This prevents a single thread
            // from forcing other high priority threads from being
            // blocked while a large address range is deleted.  There
            // is nothing magic about the instruction within the
            // lock and unlock.
            //

            UNLOCK_PFN (OldIrql);
            PointerPde = MiGetPdeAddress (Va);
            LOCK_PFN (OldIrql);

            UsedPageTableCount =
                   &MmWorkingSetList->UsedPageTableEntries[MiGetPdeOffset(Va)];

            while (MiDoesPdeExistAndMakeValid (
                                  PointerPde, CurrentProcess, TRUE) == FALSE) {

                //
                // This page directory entry is empty, go to the next one.
                //

                PointerPde += 1;
                PointerPte = MiGetVirtualAddressMappedByPte (PointerPde);
                Va = MiGetVirtualAddressMappedByPte (PointerPte);

                if (Va > EndingAddress) {

                    //
                    // All done, return.
                    //

                    return;
                }

                UsedPageTableCount += 1;
                if (LastProtoPte != NULL) {
                    ProtoPte = MiGetProtoPteAddress(Vad,Va);
                    Subsection = MiLocateSubsection (Vad,Va);
                    LastProtoPte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
#if DBG
                    if (Vad->u.VadFlags.ImageMap != 1) {
                        if ((ProtoPte < Subsection->SubsectionBase) ||
                            (ProtoPte >= LastProtoPte)) {
                            DbgPrint ("bad proto pte %lx va %lx Vad %lx sub %lx\n",
                            ProtoPte,Va,Vad,Subsection);
                            DbgBreakPoint();
                        }
                    }
#endif //DBG
                }
            }
        }

        //
        // The PDE is now valid, delete the ptes
        //

        if (PointerPte->u.Long != 0) {
#ifdef R4000
            ASSERT (PointerPte->u.Hard.Global == 0);
#endif

            //
            // One less used page table entry in this page table page.
            //

            *UsedPageTableCount -= 1;
            ASSERT (*UsedPageTableCount < PTE_PER_PAGE);

            if (IS_PTE_NOT_DEMAND_ZERO (*PointerPte)) {

                if (LastProtoPte != NULL) {
                    if (ProtoPte >= LastProtoPte) {
                        ProtoPte = MiGetProtoPteAddress(Vad,Va);
                        Subsection = MiLocateSubsection (Vad,Va);
                        LastProtoPte = &Subsection->SubsectionBase[Subsection->PtesInSubsection];
                    }
#if DBG
                    if (Vad->u.VadFlags.ImageMap != 1) {
                        if ((ProtoPte < Subsection->SubsectionBase) ||
                            (ProtoPte >= LastProtoPte)) {
                            DbgPrint ("bad proto pte %lx va %lx Vad %lx sub %lx\n",
                                        ProtoPte,Va,Vad,Subsection);
                            DbgBreakPoint();
                        }
                    }
#endif //DBG
                }

                MiDeletePte (PointerPte,
                             (PVOID)Va,
                             AddressSpaceDeletion,
                             CurrentProcess,
                             ProtoPte,
                             &FlushList);
            } else {
                *PointerPte = ZeroPte;
            }
        }
        Va = Va + PAGE_SIZE;
        PointerPte++;
        ProtoPte++;

    }

    //
    // Flush out entries for the last page table page.
    //

    MiFlushPteList (&FlushList, FALSE, ZeroPte);

    //
    // If all the entries have been eliminated from the previous
    // page table page, delete the page table page itself.
    //

    if ((*UsedPageTableCount == 0) && (PointerPde->u.Long != 0)) {

        TempVa = MiGetVirtualAddressMappedByPte(PointerPde);
        MiDeletePte (PointerPde,
                     TempVa,
                     AddressSpaceDeletion,
                     CurrentProcess,
                     NULL,
                     NULL);
    }

    //
    // All done, return.
    //

    return;
}
Esempio n. 27
0
BOOL GetThreadIDHTASKALIAS(
    DWORD  dwThreadID32,
    HTASKALIAS *ha
) {
    OBJECT_ATTRIBUTES   obja;
    THREAD_BASIC_INFORMATION ThreadInfo;
    HANDLE      hThread;
    NTSTATUS    Status;
    FILETIME    ftDummy;
    CLIENT_ID   cid;

    InitializeObjectAttributes(
            &obja,
            NULL,
            0,
            NULL,
            0 );

    cid.UniqueProcess = 0;      // Don't know it, 0 means any process
    cid.UniqueThread  = (HANDLE)dwThreadID32;

    Status = NtOpenThread(
                &hThread,
                THREAD_QUERY_INFORMATION,
                &obja,
                &cid );

    if ( !NT_SUCCESS(Status) ) {
#if DBG
        DbgPrint("WOW32: Could not get open thread handle\n");
#endif
        return( FALSE );
    }

    Status = NtQueryInformationThread(
        hThread,
        ThreadBasicInformation,
        (PVOID)&ThreadInfo,
        sizeof(THREAD_BASIC_INFORMATION),
        NULL
        );

    ha->dwProcessID32 = (DWORD)ThreadInfo.ClientId.UniqueProcess;
    ha->dwThreadID32  = dwThreadID32;

    GetThreadTimes( hThread,
        &ha->ftCreationTime,
        &ftDummy,
        &ftDummy,
        &ftDummy );

    Status = NtClose( hThread );
    if ( !NT_SUCCESS(Status) ) {
#if DBG
        DbgPrint("WOW32: Could not close thread handle\n");
        DbgBreakPoint();
#endif
        return( FALSE );
    }
    return( TRUE );
}
Esempio n. 28
0
NTSTATUS ZlzDeviceCreate(PDEVICE_OBJECT dev, PIRP irp)
{
		DbgBreakPoint();
		DbgPrint("Creae Success!\n");
		return STATUS_SUCCESS;
}
Esempio n. 29
0
BOOL bTestGOTM (
    HDC     hdc
    )
{
    ULONG   row = 0;                    // screen row coordinate to print at
    HFONT   hfont;
    HFONT   hfontOriginal;
    LOGFONT lfnt;
    POUTLINETEXTMETRIC  potm;
    ULONG   cjotm;
    PSZ     pszPitch, pszFamily;


// Clear the screen to black.

    BitBlt(hdc, 0, 0, CX, CY, (HDC) 0, 0, 0, 0);

// Get a font.

    memset(&lfnt, 0, sizeof(lfnt));
    lstrcpy(lfnt.lfFaceName, "Arial");
    lfnt.lfHeight = -14;
    lfnt.lfWeight = 400;

    if ((hfont = CreateFontIndirect(&lfnt)) == NULL)
    {
        DbgPrint("ft!bTestGOTM(): Logical font creation failed.\n");
        return FALSE;
    }

    hfontOriginal = SelectObject(hdc, hfont);

// Determine size needed for OTM.

    if ( (cjotm = (ULONG) GetOutlineTextMetrics(hdc, 0, (POUTLINETEXTMETRIC) NULL)) == (ULONG) 0 )
    {
        DbgPrint("ft!bTestGOTM(): could not get size info from GetOutlineTextMetrics\n");
        return FALSE;
    }

// Allocate memory.

    if ( (potm = (POUTLINETEXTMETRIC) LocalAlloc(LPTR, cjotm)) == (POUTLINETEXTMETRIC) NULL )
    {
        DbgPrint("ft!bTestGOTM(): LocalAlloc(LPTR, 0x%lx) failed\n", cjotm);
        return FALSE;
    }

// Get the OTM.

    if ( GetOutlineTextMetrics(hdc, cjotm, potm) == (DWORD) 0 )
    {
        LocalFree(potm);

        DbgPrint("ft!bTestGOTM(): GetOutlineTextMetrics call failed\n");
        return FALSE;
    }

// Print TEXTMETRIC.

    vPrintTM(hdc, &potm->otmTextMetrics);
    DbgBreakPoint();

// Print TEXTMETRIC.

    vPrintOTM(hdc, potm);
    DbgBreakPoint();

// Restore the font.

    SelectObject(hdc, hfontOriginal);
    DeleteObject(hfont);

    LocalFree(potm);

    return TRUE;
}
Esempio n. 30
0
NTSTATUS
NTAPI
PciDispatchIrp(IN PDEVICE_OBJECT DeviceObject,
               IN PIRP Irp)
{
    PPCI_FDO_EXTENSION DeviceExtension;
    PIO_STACK_LOCATION IoStackLocation;
    PPCI_MJ_DISPATCH_TABLE IrpDispatchTable;
    BOOLEAN PassToPdo;
    NTSTATUS Status;
    PPCI_MN_DISPATCH_TABLE TableArray = NULL, Table;
    USHORT MaxMinor;
    PCI_DISPATCH_STYLE DispatchStyle = 0;
    PCI_DISPATCH_FUNCTION DispatchFunction = NULL;
    DPRINT1("PCI: Dispatch IRP\n");

    /* Get the extension and I/O stack location for this IRP */
    DeviceExtension = (PPCI_FDO_EXTENSION)DeviceObject->DeviceExtension;
    IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
    ASSERT((DeviceExtension->ExtensionType == PciPdoExtensionType) ||
           (DeviceExtension->ExtensionType == PciFdoExtensionType));

    /* Deleted extensions don't respond to IRPs */
    if (DeviceExtension->DeviceState == PciDeleted)
    {
        /* Fail this IRP */
        Status = STATUS_NO_SUCH_DEVICE;
        PassToPdo = FALSE;
    }
    else
    {
        /* Otherwise, get the dispatch table for the extension */
        IrpDispatchTable = DeviceExtension->IrpDispatchTable;

        /* And choose which function table to use */
        switch (IoStackLocation->MajorFunction)
        {
            case IRP_MJ_POWER:

                /* Power Manager IRPs */
                TableArray = IrpDispatchTable->PowerIrpDispatchTable;
                MaxMinor = IrpDispatchTable->PowerIrpMaximumMinorFunction;
                break;

            case IRP_MJ_PNP:

                /* Plug-and-Play Manager IRPs */
                TableArray = IrpDispatchTable->PnpIrpDispatchTable;
                MaxMinor = IrpDispatchTable->PnpIrpMaximumMinorFunction;
                break;

            case IRP_MJ_SYSTEM_CONTROL:

                /* WMI IRPs */
                DispatchFunction = IrpDispatchTable->SystemControlIrpDispatchFunction;
                DispatchStyle = IrpDispatchTable->SystemControlIrpDispatchStyle;
                MaxMinor = 0xFFFF;
                break;

            default:

                /* Unrecognized IRPs */
                DispatchFunction = IrpDispatchTable->OtherIrpDispatchFunction;
                DispatchStyle = IrpDispatchTable->OtherIrpDispatchStyle;
                MaxMinor = 0xFFFF;
                break;
        }

        /* Only deal with recognized IRPs */
        if (MaxMinor != 0xFFFF)
        {
            /* Make sure the function is recognized */
            if (IoStackLocation->MinorFunction > MaxMinor)
            {
                /* Pick the terminator, which should return unrecognized */
                Table = &TableArray[MaxMinor + 1];
            }
            else
            {
                /* Pick the appropriate table for this function */
                Table = &TableArray[IoStackLocation->MinorFunction];
            }

            /* From that table, get the function code and dispatch style */
            DispatchStyle = Table->DispatchStyle;
            DispatchFunction = Table->DispatchFunction;
        }

        /* Print out debugging information, and see if we should break */
        if (PciDebugIrpDispatchDisplay(IoStackLocation,
                                       DeviceExtension,
                                       MaxMinor))
        {
            /* The developer/user wants us to break for this IRP, do it */
            DbgBreakPoint();
        }

        /* Check if this IRP should be sent up the stack first */
        if (DispatchStyle == IRP_UPWARD)
        {
            /* Do it now before handling it ourselves */
            PciCallDownIrpStack(DeviceExtension, Irp);
        }

        /* Call the our driver's handler for this IRP and deal with the IRP */
        Status = DispatchFunction(Irp, IoStackLocation, DeviceExtension);
        switch (DispatchStyle)
        {
            /* Complete IRPs are completely immediately by our driver */
            case IRP_COMPLETE:
                PassToPdo = FALSE;
                break;

            /* Downward IRPs are send to the attached FDO */
            case IRP_DOWNWARD:
                PassToPdo = TRUE;
                break;

            /* Upward IRPs are completed immediately by our driver */
            case IRP_UPWARD:
                PassToPdo = FALSE;
                break;

            /* Dispatch IRPs are immediately returned */
            case IRP_DISPATCH:
                return Status;

            /* There aren't any other dispatch styles! */
            default:
                ASSERT(FALSE);
                return Status;
        }
    }

    /* Pending IRPs are returned immediately */
    if (Status == STATUS_PENDING) return Status;

    /* Handled IRPs return their status in the status block */
    if (Status != STATUS_NOT_SUPPORTED) Irp->IoStatus.Status = Status;

    /* Successful, or unhandled IRPs that are "DOWNWARD" are sent to the PDO */
    if ((PassToPdo) && ((NT_SUCCESS(Status)) || (Status == STATUS_NOT_SUPPORTED)))
    {
        /* Let the PDO deal with it */
        Status = PciPassIrpFromFdoToPdo(DeviceExtension, Irp);
    }
    else
    {
        /* Otherwise, the IRP is returned with its status */
        Status = Irp->IoStatus.Status;

        /* Power IRPs need to notify the Power Manager that the next IRP can go */
        if (IoStackLocation->MajorFunction == IRP_MJ_POWER) PoStartNextPowerIrp(Irp);

        /* And now this IRP can be completed */
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

    /* And the status returned back to the caller */
    return Status;
}