示例#1
0
/*! .

	\param [in]
	\param [out]
	\param [in,out]

	\pre
	\post
	\return

*/
NTSTATUS
FlTimerThreadCreate()
{
    NTSTATUS status = STATUS_SUCCESS;
    HANDLE handle;
    OBJECT_ATTRIBUTES objectAttribs;


    TimerThreadStopExec = FALSE;

    InitializeObjectAttributes(
        &objectAttribs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

    KeInitializeEvent(&ThreadSleepWakeup, SynchronizationEvent, FALSE);
    DriverInfoData->TimerThreadSleepWakeup = &ThreadSleepWakeup;

    KeInitializeTimer(&Timer);
    DriverInfoData->Timer = &Timer;



    status = PsCreateSystemThread(&handle,
                                  THREAD_ALL_ACCESS,
                                  &objectAttribs,
                                  NULL,
                                  NULL,
                                  (PKSTART_ROUTINE)TimerThreadExecRoutine,
                                  NULL);

    if (!NT_SUCCESS(status))
    {
        KeCancelTimer(&Timer);
        DriverInfoData->Timer = NULL;
        DriverInfoData->TimerThreadSleepWakeup = NULL;

        DBGPRINT_ARG1("[flmonflt] PsCreateSystemThread failed: 0x%X\n", status);
    }
    else
    {
        ObReferenceObjectByHandle(handle, THREAD_ALL_ACCESS, NULL,
                                  KernelMode, &DriverInfoData->TimerThread, NULL);

        ZwClose(handle);

        DBGPRINT("[flmonflt] PsCreateSystemThread succeeded.\n");
    }

    return status;
}
示例#2
0
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath) 
{
	Debug(("Enter DriverEntry\n"));

	pDriverObject->DriverUnload = DriverUnload;
	pDriverObject->MajorFunction[IRP_MJ_CREATE]	= DriverCreate;
	pDriverObject->MajorFunction[IRP_MJ_CLOSE]	= DriverClose;
	pDriverObject->MajorFunction[IRP_MJ_WRITE]	= DriverWrite;
	pDriverObject->MajorFunction[IRP_MJ_READ]	= DriverRead;

	//创建设备
	PDEVICE_OBJECT tDev;
	UNICODE_STRING tDevName;
	RtlInitUnicodeString(&tDevName,DEVICE_NAME);

	NTSTATUS tRetStatus;
	tRetStatus = IoCreateDevice(pDriverObject,
								sizeof(MyDeviceExtend),
								&tDevName,
								FILE_DEVICE_UNKNOWN,
								0,
								FALSE,
								&tDev);

	if(false == NT_SUCCESS(tRetStatus))
	{
		Debug("IoCreateDevice fail");
		return tRetStatus;
	}

	//创建符号链接
	UNICODE_STRING tSymbolicName;
	RtlInitUnicodeString(&tSymbolicName,DEVICE_SYMBOLICLINK);
	tRetStatus = IoCreateSymbolicLink(&tSymbolicName,&tDevName);
	if(false == NT_SUCCESS(tRetStatus))
	{
		Debug("IoCreateSymbolicLink fail");
		IoDeleteDevice(tDev);
		return tRetStatus;
	}

	tDev->Flags |= DO_BUFFERED_IO;

	MyDeviceExtend* tMyDevExtend	= (MyDeviceExtend*)tDev->DeviceExtension;

	KeInitializeTimer(&tMyDevExtend->Timer);
	KeInitializeDpc(&tMyDevExtend->DPC,OnTimeDPC,(void*)tDev);
	return STATUS_SUCCESS;
}
示例#3
0
VOID
NTAPI
CmpCmdInit(IN BOOLEAN SetupBoot)
{
    LARGE_INTEGER DueTime;
    PAGED_CODE();

    /* Setup the lazy DPC */
    KeInitializeDpc(&CmpLazyFlushDpc, CmpLazyFlushDpcRoutine, NULL);

    /* Setup the lazy timer */
    KeInitializeTimer(&CmpLazyFlushTimer);

    /* Setup the lazy worker */
    ExInitializeWorkItem(&CmpLazyWorkItem, CmpLazyFlushWorker, NULL);

    /* Setup the forced-lazy DPC and timer */
    KeInitializeDpc(&CmpEnableLazyFlushDpc,
                    CmpEnableLazyFlushDpcRoutine,
                    NULL);
    KeInitializeTimer(&CmpEnableLazyFlushTimer);

    /* Enable lazy flushing after 10 minutes */
    DueTime.QuadPart = Int32x32To64(600, -10 * 1000 * 1000);
    KeSetTimer(&CmpEnableLazyFlushTimer, DueTime, &CmpEnableLazyFlushDpc);

    /* Setup flush variables */
    CmpNoWrite = CmpMiniNTBoot;
    CmpWasSetupBoot = SetupBoot;

    /* Testing: Force Lazy Flushing */
    CmpHoldLazyFlush = FALSE;

    /* Setup the hive list */
    CmpInitializeHiveList(SetupBoot);
}
示例#4
0
文件: input.c 项目: RPG-7/reactos
/*
 * InitInputImpl
 *
 * Inits input implementation
 */
INIT_FUNCTION
NTSTATUS
NTAPI
InitInputImpl(VOID)
{
    MasterTimer = ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), USERTAG_SYSTEM);
    if (!MasterTimer)
    {
        ERR("Failed to allocate memory\n");
        ASSERT(FALSE);
        return STATUS_UNSUCCESSFUL;
    }
    KeInitializeTimer(MasterTimer);

    return STATUS_SUCCESS;
}
示例#5
0
文件: retry.c 项目: uri247/wdk80
VOID TransferPacketQueueRetryDpc(PTRANSFER_PACKET Pkt)
{
    KeInitializeDpc(&Pkt->RetryTimerDPC, TransferPacketRetryTimerDpc, Pkt);

    if (Pkt->RetryIn100nsUnits == 0){
        KeInsertQueueDpc(&Pkt->RetryTimerDPC, NULL, NULL);
    }
    else {
        LARGE_INTEGER timerPeriod;

        NT_ASSERT(Pkt->RetryIn100nsUnits < 100 * 1000 * 1000 * 10); // sanity check -- 100 seconds is normally too long
        timerPeriod.QuadPart = -(Pkt->RetryIn100nsUnits);
        KeInitializeTimer(&Pkt->RetryTimer);
        KeSetTimer(&Pkt->RetryTimer, timerPeriod, &Pkt->RetryTimerDPC);
    }
}
示例#6
0
文件: write.c 项目: Axure/Ext3Fsd
VOID
Ext2StartFloppyFlushDpc (
    PEXT2_VCB   Vcb,
    PEXT2_FCB   Fcb,
    PFILE_OBJECT FileObject )
{
    LARGE_INTEGER          OneSecond;
    PEXT2_FLPFLUSH_CONTEXT Context;

    ASSERT(IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK));

    Context = Ext2AllocatePool(
                  NonPagedPool,
                  sizeof(EXT2_FLPFLUSH_CONTEXT),
                  EXT2_FLPFLUSH_MAGIC
              );

    if (!Context) {
        DEBUG(DL_ERR, ( "Ex2StartFloppy...: failed to allocate Context\n"));
        DbgBreak();
        return;
    }

    KeInitializeTimer(&Context->Timer);

    KeInitializeDpc( &Context->Dpc,
                     Ext2FloppyFlushDpc,
                     Context );

    ExInitializeWorkItem( &Context->Item,
                          Ext2FloppyFlush,
                          Context );

    Context->Vcb = Vcb;
    Context->Fcb = Fcb;
    Context->FileObject = FileObject;

    if (FileObject) {
        ObReferenceObject(FileObject);
    }

    OneSecond.QuadPart = (LONGLONG)-1*1000*1000*10;
    KeSetTimer( &Context->Timer,
                OneSecond,
                &Context->Dpc );
}
示例#7
0
NTSTATUS
NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,
            IN PUNICODE_STRING RegistryPath)
{
    PDEVICE_EXTENSION DeviceExtension;
    PDEVICE_OBJECT DeviceObject;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Beep");
    NTSTATUS Status;

    UNREFERENCED_PARAMETER(RegistryPath);

    /* Create the device */
    Status = IoCreateDevice(DriverObject,
                            sizeof(DEVICE_EXTENSION),
                            &DeviceName,
                            FILE_DEVICE_BEEP,
                            0,
                            FALSE,
                            &DeviceObject);
    if (!NT_SUCCESS(Status)) return Status;

    /* Make it use buffered I/O */
    DeviceObject->Flags |= DO_BUFFERED_IO;

    /* Setup the Driver Object */
    DriverObject->MajorFunction[IRP_MJ_CREATE] = BeepCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = BeepClose;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = BeepCleanup;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BeepDeviceControl;
    DriverObject->DriverUnload = BeepUnload;
    DriverObject->DriverStartIo = BeepStartIo;

    /* Set up device extension */
    DeviceExtension = DeviceObject->DeviceExtension;
    DeviceExtension->ReferenceCount = 0;
    DeviceExtension->TimerActive = FALSE;
    IoInitializeDpcRequest(DeviceObject, (PIO_DPC_ROUTINE)BeepDPC);
    KeInitializeTimer(&DeviceExtension->Timer);
    ExInitializeFastMutex(&DeviceExtension->Mutex);

    /* Page the entire driver */
    MmPageEntireDriver(DriverEntry);
    return STATUS_SUCCESS;
}
示例#8
0
PSRV_TIMER
SrvAllocateTimer (
    VOID
    )

/*++

Routine Description:

    This routine allocates a timer structure.

Arguments:

    None.

Return Value:

    PSRV_TIMER -- pointer to the allocated timer structure, or NULL.

--*/

{
    PSINGLE_LIST_ENTRY entry;
    PSRV_TIMER timer;

    PAGED_CODE( );

    entry = ExInterlockedPopEntrySList( &SrvTimerList, &GLOBAL_SPIN_LOCK(Timer) );
    if ( entry == NULL ) {
        timer = ALLOCATE_NONPAGED_POOL( sizeof(SRV_TIMER), BlockTypeTimer );
        if ( timer != NULL ) {
            KeInitializeEvent( &timer->Event, NotificationEvent, FALSE );
            KeInitializeTimer( &timer->Timer );
        }
    } else {
        timer = CONTAINING_RECORD( entry, SRV_TIMER, Next );
    }

    return timer;

} // SrvAllocateTimer
示例#9
0
void STDCALL flush_thread(void* context) {
    device_extension* Vcb = context;
    LARGE_INTEGER due_time;
    
    KeInitializeTimer(&Vcb->flush_thread_timer);
    
    due_time.QuadPart = -INTERVAL * 10000;
    
    KeSetTimer(&Vcb->flush_thread_timer, due_time, NULL);
    
    while (TRUE) {
        KeWaitForSingleObject(&Vcb->flush_thread_timer, Executive, KernelMode, FALSE, NULL);        

        do_flush(Vcb);
        
        KeSetTimer(&Vcb->flush_thread_timer, due_time, NULL);
    }
    
    KeCancelTimer(&Vcb->flush_thread_timer);
    PsTerminateSystemThread(STATUS_SUCCESS);
}
VBOXDRVTOOL_DECL(VOID) VBoxDrvToolRefWaitEqual(PVBOXDRVTOOL_REF pRef, uint32_t u32Val)
{
    LARGE_INTEGER Interval;
    Interval.QuadPart = -(int64_t) 2 /* ms */ * 10000;
    uint32_t cRefs;
    size_t loops = 0; 
    KTIMER kTimer;
    NTSTATUS status = STATUS_SUCCESS;

    KeInitializeTimer(&kTimer);
    
    while ((cRefs = ASMAtomicReadU32(&pRef->cRefs)) > u32Val && loops < 256)
    {
        Assert(cRefs >= u32Val);
        Assert(cRefs < UINT32_MAX/2);

        KeSetTimer(&kTimer, Interval, NULL);
        status = KeWaitForSingleObject(&kTimer, Executive, KernelMode, false, NULL);
        Assert(NT_SUCCESS(status));
        loops++;
    }
}
示例#11
0
文件: write.c 项目: layerfsd/ffsfsd
VOID
FFSStartFloppyFlushDpc(
	PFFS_VCB     Vcb,
	PFFS_FCB     Fcb,
	PFILE_OBJECT FileObject)
{
	LARGE_INTEGER          OneSecond;
	PFFS_FLPFLUSH_CONTEXT Context;

	ASSERT(IsFlagOn(Vcb->Flags, VCB_FLOPPY_DISK));

	Context = ExAllocatePool(NonPagedPool, sizeof(PFFS_FLPFLUSH_CONTEXT));

	if (!Context)
	{
		FFSBreakPoint();
		return;
	}

	KeInitializeTimer(&Context->Timer);

	KeInitializeDpc(&Context->Dpc,
			FFSFloppyFlushDpc,
			Context);

	Context->Vcb = Vcb;
	Context->Fcb = Fcb;
	Context->FileObject = FileObject;

	if (FileObject)
	{
		ObReferenceObject(FileObject);
	}

	OneSecond.QuadPart = (LONGLONG) - 1 * 1000 * 1000 * 10;
	KeSetTimer(&Context->Timer,
			OneSecond,
			&Context->Dpc);
}
示例#12
0
PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext )
{
    PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)
        ExAllocatePoolWithTag(NonPagedPool, sizeof(CONNECTION_ENDPOINT), CONN_ENDPT_TAG);

    if (!Connection)
        return Connection;

    TI_DbgPrint(DEBUG_CPOINT, ("Connection point file object allocated at (0x%X).\n", Connection));

    RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT));

    /* Initialize spin lock that protects the connection endpoint file object */
    KeInitializeSpinLock(&Connection->Lock);
    InitializeListHead(&Connection->ConnectRequest);
    InitializeListHead(&Connection->ListenRequest);
    InitializeListHead(&Connection->ReceiveRequest);
    InitializeListHead(&Connection->SendRequest);
    InitializeListHead(&Connection->ShutdownRequest);
    InitializeListHead(&Connection->PacketQueue);

    /* Initialize disconnect timer */
    KeInitializeTimer(&Connection->DisconnectTimer);
    KeInitializeDpc(&Connection->DisconnectDpc, DisconnectTimeoutDpc, Connection);

    /* Save client context pointer */
    Connection->ClientContext = ClientContext;

    Connection->RefCount = 1;
    Connection->Free = ConnectionFree;

    /* Add connection endpoint to global list */
    ExInterlockedInsertTailList(&ConnectionEndpointListHead,
                                &Connection->ListEntry,
                                &ConnectionEndpointListLock);

    return Connection;
}
示例#13
0
// Public interface
void BackupRegistersInit(HANDLE_DEV dev)
{
    memset(gs_backupRegisters, BKP_UNINITIALIZED_VALUE, sizeof(gs_backupRegisters));
    ReadBackupRegistersFromRegistry(dev);

#ifdef ENABLE_TIMER_DPC
    LARGE_INTEGER due;
    due.QuadPart = 10000*10000UL;
    dpc = (PRKDPC)SAFE_ALLOCATE_POOL(NonPagedPool, sizeof(KDPC), IVH_BACKUP_POOL_TAG);

    if (dpc)
    {   // init it!
        KeInitializeDpc(dpc, TimerHandle, dev);
        TraceLog(TRACE_LEVEL_INFORMATION, TRACE_ALGO, "malloc memory for backup dpc");
    }
    else 
    {
        //  No memory
        TraceLog(TRACE_LEVEL_ERROR, TRACE_ALGO, "[%!FUNC!]not enough memory");
        return;
    }

    timer = (PKTIMER)SAFE_ALLOCATE_POOL(NonPagedPool, sizeof(KTIMER), IVH_BACKUP_POOL_TAG);
    if (timer)
    {   // init it!
        KeInitializeTimer(timer);
        TraceLog(TRACE_LEVEL_INFORMATION, TRACE_ALGO, "malloc memory for backup timer");
    }
    else 
    {
        //  No memory
        TraceLog(TRACE_LEVEL_ERROR, TRACE_ALGO, "[%!FUNC!]not enough memory");
        return;
    }

    KeSetTimerEx(timer, due, (ULONG)(due.QuadPart), dpc);
#endif
}
示例#14
0
NTSTATUS
SpxTimerInit(
    VOID
)
/*++

Routine Description:

 	Initialize the timer component for the appletalk stack.

Arguments:


Return Value:


--*/
{
#if      !defined(_PNP_POWER)
    BOOLEAN	TimerStarted;
#endif  !_PNP_POWER

    // Initialize the timer and its associated Dpc. timer will be kicked
    // off when we get the first card arrival notification from ipx
    KeInitializeTimer(&spxTimer);
    CTEInitLock(&spxTimerLock);
    KeInitializeDpc(&spxTimerDpc, spxTimerDpcRoutine, NULL);
    spxTimerTick = RtlConvertLongToLargeInteger(SPX_TIMER_TICK);
#if      !defined(_PNP_POWER)
    TimerStarted = KeSetTimer(&spxTimer,
                              spxTimerTick,
                              &spxTimerDpc);
    CTEAssert(!TimerStarted);
#endif  !_PNP_POWER
    return STATUS_SUCCESS;
}
示例#15
0
文件: error.c 项目: hoangduit/reactos
VOID
NTAPI
IopRestartLogWorker(VOID)
{
    PIOP_ERROR_LOG_WORKER_DPC WorkerDpc;
    LARGE_INTEGER Timeout;

    /* Allocate a DPC Context */
    WorkerDpc = ExAllocatePool(NonPagedPool, sizeof(IOP_ERROR_LOG_WORKER_DPC));
    if (!WorkerDpc)
    {
        /* Fail */
        IopLogWorkerRunning = FALSE;
        return;
    }

    /* Initialize DPC and Timer */
    KeInitializeDpc(&WorkerDpc->Dpc, IopLogDpcRoutine, WorkerDpc);
    KeInitializeTimer(&WorkerDpc->Timer);

    /* Restart after 30 seconds */
    Timeout.QuadPart = (LONGLONG)-300000000;
    KeSetTimer(&WorkerDpc->Timer, Timeout, &WorkerDpc->Dpc);
}
示例#16
0
文件: work.c 项目: killvxk/NT_OS
/*++
 * @name ExpWorkerThreadBalanceManager
 *
 *     The ExpWorkerThreadBalanceManager routine is the entrypoint for the
 *     worker thread balance set manager.
 *
 * @param Context
 *        Unused.
 *
 * @return None.
 *
 * @remarks The worker thread balance set manager listens every second, but can
 *          also be woken up by an event when a new thread is needed, or by the
 *          special shutdown event. This thread runs at priority 7.
 *
 *          This routine must run at IRQL == PASSIVE_LEVEL.
 *
 *--*/
VOID
NTAPI
ExpWorkerThreadBalanceManager(IN PVOID Context)
{
    KTIMER Timer;
    LARGE_INTEGER Timeout;
    NTSTATUS Status;
    PVOID WaitEvents[3];
    PAGED_CODE();
    UNREFERENCED_PARAMETER(Context);

    /* Raise our priority above all other worker threads */
    KeSetBasePriorityThread(KeGetCurrentThread(),
                            EX_CRITICAL_QUEUE_PRIORITY_INCREMENT + 1);

    /* Setup the timer */
    KeInitializeTimer(&Timer);
    Timeout.QuadPart = Int32x32To64(-1, 10000000);

    /* We'll wait on the periodic timer and also the emergency event */
    WaitEvents[0] = &Timer;
    WaitEvents[1] = &ExpThreadSetManagerEvent;
    WaitEvents[2] = &ExpThreadSetManagerShutdownEvent;

    /* Start wait loop */
    for (;;)
    {
        /* Wait for the timer */
        KeSetTimer(&Timer, Timeout, NULL);
        Status = KeWaitForMultipleObjects(3,
                                          WaitEvents,
                                          WaitAny,
                                          Executive,
                                          KernelMode,
                                          FALSE,
                                          NULL,
                                          NULL);
        if (Status == 0)
        {
            /* Our timer expired. Check for deadlocks */
            ExpDetectWorkerThreadDeadlock();
        }
        else if (Status == 1)
        {
            /* Someone notified us, verify if we should create a new thread */
            ExpCheckDynamicThreadCount();
        }
        else if (Status == 2)
        {
            /* We are shutting down. Cancel the timer */
            DPRINT1("System shutdown\n");
            KeCancelTimer(&Timer);

            /* Make sure we have a final thread */
            ASSERT(ExpLastWorkerThread);

            /* Wait for it */
            KeWaitForSingleObject(ExpLastWorkerThread,
                                  Executive,
                                  KernelMode,
                                  FALSE,
                                  NULL);

            /* Dereference it and kill us */
            ObDereferenceObject(ExpLastWorkerThread);
            PsTerminateSystemThread(STATUS_SYSTEM_SHUTDOWN);
        }
    }
}
示例#17
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This is the initialization routine for the Ntfs file system
    device driver.  This routine creates the device object for the FileSystem
    device and performs all other driver initialization.

Arguments:

    DriverObject - Pointer to driver object created by the system.

Return Value:

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

--*/

{
    NTSTATUS Status;
    UNICODE_STRING UnicodeString;
    PDEVICE_OBJECT DeviceObject;

    UNICODE_STRING KeyName;
    UNICODE_STRING ValueName;
    ULONG Value;

    UNREFERENCED_PARAMETER( RegistryPath );

    PAGED_CODE();

    //
    //  Compute the last access increment.  We convert the number of
    //  minutes to number of 1/100 of nanoseconds.  We have to be careful
    //  not to overrun 32 bits for any multiplier.
    //
    //  To reach 1/100 of nanoseconds per minute we take
    //
    //      1/100 nanoseconds * 10      = 1 microsecond
    //                        * 1000    = 1 millesecond
    //                        * 1000    = 1 second
    //                        * 60      = 1 minute
    //
    //  Then multiply this by the last access increment in minutes.
    //

    NtfsLastAccess = Int32x32To64( ( 10 * 1000 * 1000 * 60 ), LAST_ACCESS_INCREMENT_MINUTES );

    //
    // Create the device object.
    //

    RtlInitUnicodeString( &UnicodeString, L"\\Ntfs" );

    Status = IoCreateDevice( DriverObject,
                             0,
                             &UnicodeString,
                             FILE_DEVICE_DISK_FILE_SYSTEM,
                             0,
                             FALSE,
                             &DeviceObject );

    if (!NT_SUCCESS( Status )) {

        return Status;
    }

    //
    //  Note that because of the way data caching is done, we set neither
    //  the Direct I/O or Buffered I/O bit in DeviceObject->Flags.  If
    //  data is not in the cache, or the request is not buffered, we may,
    //  set up for Direct I/O by hand.
    //

    //
    // Initialize the driver object with this driver's entry points.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE]                   = (PDRIVER_DISPATCH)NtfsFsdCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]                    = (PDRIVER_DISPATCH)NtfsFsdClose;
    DriverObject->MajorFunction[IRP_MJ_READ]                     = (PDRIVER_DISPATCH)NtfsFsdRead;
    DriverObject->MajorFunction[IRP_MJ_WRITE]                    = (PDRIVER_DISPATCH)NtfsFsdWrite;
    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION]        = (PDRIVER_DISPATCH)NtfsFsdQueryInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]          = (PDRIVER_DISPATCH)NtfsFsdSetInformation;
    DriverObject->MajorFunction[IRP_MJ_QUERY_EA]                 = (PDRIVER_DISPATCH)NtfsFsdQueryEa;
    DriverObject->MajorFunction[IRP_MJ_SET_EA]                   = (PDRIVER_DISPATCH)NtfsFsdSetEa;
    DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]            = (PDRIVER_DISPATCH)NtfsFsdFlushBuffers;
    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = (PDRIVER_DISPATCH)NtfsFsdQueryVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION]   = (PDRIVER_DISPATCH)NtfsFsdSetVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL]        = (PDRIVER_DISPATCH)NtfsFsdDirectoryControl;
    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL]      = (PDRIVER_DISPATCH)NtfsFsdFileSystemControl;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]           = (PDRIVER_DISPATCH)NtfsFsdDeviceControl;
    DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL]             = (PDRIVER_DISPATCH)NtfsFsdLockControl;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP]                  = (PDRIVER_DISPATCH)NtfsFsdCleanup;
    DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY]           = (PDRIVER_DISPATCH)NtfsFsdQuerySecurityInfo;
    DriverObject->MajorFunction[IRP_MJ_SET_SECURITY]             = (PDRIVER_DISPATCH)NtfsFsdSetSecurityInfo;
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN]                 = (PDRIVER_DISPATCH)NtfsFsdShutdown;

    DriverObject->FastIoDispatch = &NtfsFastIoDispatch;

    NtfsFastIoDispatch.SizeOfFastIoDispatch =    sizeof(FAST_IO_DISPATCH);
    NtfsFastIoDispatch.FastIoCheckIfPossible =   NtfsFastIoCheckIfPossible;  //  CheckForFastIo
    NtfsFastIoDispatch.FastIoRead =              NtfsCopyReadA;              //  Read
    NtfsFastIoDispatch.FastIoWrite =             NtfsCopyWriteA;             //  Write
    NtfsFastIoDispatch.FastIoQueryBasicInfo =    NtfsFastQueryBasicInfo;     //  QueryBasicInfo
    NtfsFastIoDispatch.FastIoQueryStandardInfo = NtfsFastQueryStdInfo;       //  QueryStandardInfo
    NtfsFastIoDispatch.FastIoLock =              NtfsFastLock;               //  Lock
    NtfsFastIoDispatch.FastIoUnlockSingle =      NtfsFastUnlockSingle;       //  UnlockSingle
    NtfsFastIoDispatch.FastIoUnlockAll =         NtfsFastUnlockAll;          //  UnlockAll
    NtfsFastIoDispatch.FastIoUnlockAllByKey =    NtfsFastUnlockAllByKey;     //  UnlockAllByKey
    NtfsFastIoDispatch.FastIoDeviceControl =     NULL;                       //  IoDeviceControl
    NtfsFastIoDispatch.FastIoDetachDevice            = NULL;
    NtfsFastIoDispatch.FastIoQueryNetworkOpenInfo    = NtfsFastQueryNetworkOpenInfo;
    NtfsFastIoDispatch.AcquireFileForNtCreateSection =  NtfsAcquireForCreateSection;
    NtfsFastIoDispatch.ReleaseFileForNtCreateSection =  NtfsReleaseForCreateSection;
    NtfsFastIoDispatch.AcquireForModWrite =          NtfsAcquireFileForModWrite;
    NtfsFastIoDispatch.MdlRead =                     NtfsMdlReadA;
    NtfsFastIoDispatch.MdlReadComplete =             FsRtlMdlReadCompleteDev;
    NtfsFastIoDispatch.PrepareMdlWrite =             NtfsPrepareMdlWriteA;
    NtfsFastIoDispatch.MdlWriteComplete =            FsRtlMdlWriteCompleteDev;
#ifdef _CAIRO_
    NtfsFastIoDispatch.FastIoReadCompressed =        NtfsCopyReadC;
    NtfsFastIoDispatch.FastIoWriteCompressed =       NtfsCopyWriteC;
    NtfsFastIoDispatch.MdlReadCompleteCompressed =   NtfsMdlReadCompleteCompressed;
    NtfsFastIoDispatch.MdlWriteCompleteCompressed =  NtfsMdlWriteCompleteCompressed;
#endif _CAIRO_
    NtfsFastIoDispatch.FastIoQueryOpen =             NtfsNetworkOpenCreate;
    NtfsFastIoDispatch.AcquireForCcFlush =           NtfsAcquireFileForCcFlush;
    NtfsFastIoDispatch.ReleaseForCcFlush =           NtfsReleaseFileForCcFlush;

    //
    //  Initialize the global ntfs data structure
    //

    NtfsInitializeNtfsData( DriverObject );

    ExInitializeFastMutex( &StreamFileCreationFastMutex );

    //
    //  Initialize the Ntfs Mcb global data queue and variables
    //

    ExInitializeFastMutex( &NtfsMcbFastMutex );
    InitializeListHead( &NtfsMcbLruQueue );
    NtfsMcbCleanupInProgress = FALSE;

    switch ( MmQuerySystemSize() ) {

    case MmSmallSystem:

        NtfsMcbHighWaterMark = 1000;
        NtfsMcbLowWaterMark = 500;
        NtfsMcbCurrentLevel = 0;
        break;

    case MmMediumSystem:

        NtfsMcbHighWaterMark = 1000;
        NtfsMcbLowWaterMark = 500;
        NtfsMcbCurrentLevel = 0;
        break;

    case MmLargeSystem:
    default:

        NtfsMcbHighWaterMark = 1000;
        NtfsMcbLowWaterMark = 500;
        NtfsMcbCurrentLevel = 0;
        break;
    }

    //
    //  Allocate and initialize the free Eresource array
    //

    if ((NtfsData.FreeEresourceArray =
         ExAllocatePoolWithTag(NonPagedPool, (NtfsData.FreeEresourceTotal * sizeof(PERESOURCE)), 'rftN')) == NULL) {

        KeBugCheck( NTFS_FILE_SYSTEM );
    }

    RtlZeroMemory( NtfsData.FreeEresourceArray, NtfsData.FreeEresourceTotal * sizeof(PERESOURCE) );

    //
    //
    //  Register the file system with the I/O system
    //

    IoRegisterFileSystem(DeviceObject);

    //
    //  Initialize logging.
    //

    NtfsInitializeLogging();

    //
    //  Initialize global variables.  (ntfsdata.c assumes 2-digit value for
    //  $FILE_NAME)
    //

    ASSERT(($FILE_NAME >= 0x10) && ($FILE_NAME < 0x100));

    RtlInitUnicodeString( &NtfsFileNameIndex, NtfsFileNameIndexName );

    //
    //  Support extended character in shortname
    //

    //
    //  Read the registry to determine if we are to create short names.
    //

    KeyName.Buffer = COMPATIBILITY_MODE_KEY_NAME;
    KeyName.Length = sizeof( COMPATIBILITY_MODE_KEY_NAME ) - sizeof( WCHAR );
    KeyName.MaximumLength = sizeof( COMPATIBILITY_MODE_KEY_NAME );

    ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME;
    ValueName.Length = sizeof( COMPATIBILITY_MODE_VALUE_NAME ) - sizeof( WCHAR );
    ValueName.MaximumLength = sizeof( COMPATIBILITY_MODE_VALUE_NAME );

    Status = NtfsGet8dot3NameStatus( &KeyName, &ValueName, &Value );

    //
    //  If we didn't find the value or the value is zero then create the 8.3
    //  names.
    //

    if (!NT_SUCCESS( Status ) || Value == 0) {

        SetFlag( NtfsData.Flags, NTFS_FLAGS_CREATE_8DOT3_NAMES );
    }

    //
    //  Read the registry to determine if we allow extended character in short name.
    //

    ValueName.Buffer = EXTENDED_CHAR_MODE_VALUE_NAME;
    ValueName.Length = sizeof( EXTENDED_CHAR_MODE_VALUE_NAME ) - sizeof( WCHAR );
    ValueName.MaximumLength = sizeof( EXTENDED_CHAR_MODE_VALUE_NAME );

    Status = NtfsGet8dot3NameStatus( &KeyName, &ValueName, &Value );

    //
    //  If we didn't find the value or the value is zero then does not allow
    //  extended character in 8.3 names.
    //

    if (NT_SUCCESS( Status ) && Value == 1) {

        SetFlag( NtfsData.Flags, NTFS_FLAGS_ALLOW_EXTENDED_CHAR );
    }

    //
    //  Read the registry to determine if we should disable last access updates.
    //

    ValueName.Buffer = DISABLE_LAST_ACCESS_VALUE_NAME;
    ValueName.Length = sizeof( DISABLE_LAST_ACCESS_VALUE_NAME ) - sizeof( WCHAR );
    ValueName.MaximumLength = sizeof( DISABLE_LAST_ACCESS_VALUE_NAME );

    Status = NtfsGet8dot3NameStatus( &KeyName, &ValueName, &Value );

    //
    //  If we didn't find the value or the value is zero then does not allow
    //  extended character in 8.3 names.
    //

    if (NT_SUCCESS( Status ) && Value == 1) {

        SetFlag( NtfsData.Flags, NTFS_FLAGS_DISABLE_LAST_ACCESS );
    }

    //
    //  Setup the CheckPointAllVolumes callback item, timer, dpc, and
    //  status.
    //

    ExInitializeWorkItem( &NtfsData.VolumeCheckpointItem,
                          NtfsCheckpointAllVolumes,
                          (PVOID)NULL );

    KeInitializeTimer( &NtfsData.VolumeCheckpointTimer );

    KeInitializeDpc( &NtfsData.VolumeCheckpointDpc,
                     NtfsVolumeCheckpointDpc,
                     NULL );
    NtfsData.TimerStatus = TIMER_NOT_SET;

    //
    //  Allocate first reserved buffer for USA writes
    //

    NtfsReserved1 = NtfsAllocatePool( NonPagedPool, LARGE_BUFFER_SIZE );
    NtfsReserved2 = NtfsAllocatePool( NonPagedPool, LARGE_BUFFER_SIZE );
    NtfsReserved3 = NtfsAllocatePool( NonPagedPool, LARGE_BUFFER_SIZE );
    ExInitializeFastMutex( &NtfsReservedBufferMutex );
    ExInitializeResource( &NtfsReservedBufferResource );

    //
    //  Zero out the global upcase table, that way we'll fill it in on
    //  our first successful mount
    //

    NtfsData.UpcaseTable = NULL;
    NtfsData.UpcaseTableSize = 0;

#ifdef _CAIRO_

    ExInitializeFastMutex( &NtfsScavengerLock );
    NtfsScavengerWorkList = NULL;
    NtfsScavengerRunning = FALSE;

    //
    // Request the load add-on routine be called after all the drivers have
    // initialized.
    //

    IoRegisterDriverReinitialization( DriverObject, NtfsLoadAddOns, NULL);

#endif

    //
    //  And return to our caller
    //

    return( STATUS_SUCCESS );
}
示例#18
0
文件: mwdm.C 项目: souri/MWDMDriver
NTSTATUS
PsdoDispatchWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
	NTSTATUS status;
	PIO_STACK_LOCATION p_IO_STK;
	PDEVICE_EXTENSION p_DVCEXT;
	ANSI_STRING RxChoice;
	UNICODE_STRING U_RxChoiceDrv;

	PVOID Buf;		//Buffer provided by user program
	ULONG BufLen;	//Buffer length for user provided buffer
	LONGLONG Offset;//Buffer Offset
	PVOID DataBuf;  //Buffer provided by Driver
	ULONG DataLen;  //Buffer length for Driver Data Buffer

	HANDLE tmrthreadhandle;
	DbgPrint("MWDM_DRIVER: DispatchWrite | Started\n");
	/*p_IO_STK = IoGetCurrentIrpStackLocation(Irp);
	p_DVCEXT = DeviceObject->DeviceExtension;

	BufLen = p_IO_STK->Parameters.Read.Length;
	Offset = p_IO_STK->Parameters.Read.ByteOffset.QuadPart;
	Buf = (PUCHAR)(Irp->AssociatedIrp.SystemBuffer) + Offset;*/
	
	if (dispatch_write_callcount == 0) //update count and exit routine
	{
	KdPrint(("Count = 0, so updating choice"));
	KdPrint(("UserBuffer: %s\n", Irp->AssociatedIrp.SystemBuffer));
	choice = atoi(Irp->AssociatedIrp.SystemBuffer);
	KdPrint(("Choice: %d\n", choice));
	dispatch_write_callcount =1;
	Irp->IoStatus.Status=STATUS_SUCCESS;
	Irp->IoStatus.Information=0;
	IoCompleteRequest(Irp,IO_NO_INCREMENT);	    
	KdPrint(("MWDM_DRIVER: DispatchWrite | Done | Choice: %d | Callcount: %d\n",choice,dispatch_write_callcount));
	return STATUS_SUCCESS;
	}

	/*RtlInitAnsiString(&RxChoice, Irp->AssociatedIrp.SystemBuffer);
	RtlAnsiStringToUnicodeString(&U_RxChoiceDrv,&RxChoice,TRUE);
	choice = (char)U_RxChoiceDrv.Buffer;
	KdPrint(("Recieved Choice: %ws | Choice:%d\n", U_RxChoiceDrv.Buffer, choice));*/
	
	if(choice==1 && dispatch_write_callcount ==1)
	{
		//only choice gets registered in the first call of write, at next call this routine works
		KdPrint (("User Entered 1 | Starting Task 1\n"));
		KdPrint(("UserString: %s\n", Irp->AssociatedIrp.SystemBuffer));
		RtlCopyMemory(&looptext, Irp->AssociatedIrp.SystemBuffer,100);
		KdPrint(("LoopText: %s\n", looptext));
		dispatch_write_callcount=0;

	}
	else if(choice==2 && dispatch_write_callcount ==1)
	{
		KdPrint(("User Entered 2 | Starting Task 2"));
		KeInitializeTimer(&timer); /* pointer to timer object */
		KeInitializeDpc(&dpc, /* pointer to dpc	object */TimerDpc, /* pointer to timer dpc routine */&p_DVCEXT); /* context (device extension) */
		//KeInitializeSpinLock(&dev_ext_ptr->lock); /* pointer to spin lock */
		(void) KeSetTimerEx(&timer, /* pointer to timer object */	DueTime, /* due time, for one-shot only */
		timer_period, /* period in	milliseconds */	&dpc); /* pointer to dpc object */

		status = PsCreateSystemThread(&tmrthreadhandle, GENERIC_READ | GENERIC_WRITE, NULL, NULL, NULL, waitontimer, NULL);
		
		KdPrint(("Done with task 2, | Final TimerCount = %d\n",timercount));
		dispatch_write_callcount=0;
	}
	else if (choice==3 && dispatch_write_callcount ==1)
	{
		KdPrint (("User Entered 3 | Starting Task 3"));
		dispatch_write_callcount=0;
	}
	else if (choice==4 && dispatch_write_callcount ==1)
	{
		KdPrint (("User Entered 4 | Starting Task 4"));
		dispatch_write_callcount=0;
	}
	else if (choice==5 && dispatch_write_callcount ==1)
	{
		KdPrint (("User Entered 5 | Starting Task 5"));
		dispatch_write_callcount=0; 
	}
	else {
		KdPrint (("Could not determine what User entered | Wrong choice entered! | Choice: %d | Callcount: %d\n",choice,dispatch_write_callcount));
		dispatch_write_callcount=0;
	}
	Irp->IoStatus.Status=STATUS_SUCCESS;
	Irp->IoStatus.Information=0;
	IoCompleteRequest(Irp,IO_NO_INCREMENT);	    
	KdPrint(("MWDM_DRIVER: DispatchWrite | Done | Choice: %d | Callcount: %d\n",choice,dispatch_write_callcount));
	return STATUS_SUCCESS;
}
示例#19
0
文件: pstat.c 项目: mingpen/OpenNT
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This routine initializes the stat driver.

Arguments:

    DriverObject - Pointer to driver object created by system.

    RegistryPath - Pointer to the Unicode name of the registry path
        for this driver.

Return Value:

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

--*/

{
    UNICODE_STRING unicodeString;
    PDEVICE_OBJECT deviceObject;
    NTSTATUS status;
    ULONG i;

    KdPrint(( "STAT: DriverEntry()\n" ));

    //
    // Create non-exclusive device object for beep device.
    //

    RtlInitUnicodeString(&unicodeString, L"\\Device\\PStat");

    status = IoCreateDevice(
                DriverObject,
                0,
                &unicodeString,
                FILE_DEVICE_UNKNOWN,    // DeviceType
                0,
                FALSE,
                &deviceObject
                );

    if (status != STATUS_SUCCESS) {
        KdPrint(( "Stat - DriverEntry: unable to create device object: %X\n", status ));
        return(status);
    }

    deviceObject->Flags |= DO_BUFFERED_IO;

    //
    // Set up the device driver entry points.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE] = StatOpen;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]  = StatClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = StatDeviceControl;

    //
    // Initialize globals
    //

    for (i = 0; i < MAXIMUM_PROCESSORS; i++) {
        StatProcessorAccumulators[i] =
            &StatGlobalAccumulators[i];
    }
    ExInitializeFastMutex (&HookLock);
    KeInitializeDpc (&LazyFreeDpc, LazyFreePoolDPC, 0);
    ExInitializeWorkItem (&LazyFreePoolWorkItem, LazyFreePool, NULL)
    KeInitializeTimer (&LazyFreeTimer);

    if (strcmp (CurrentPcr()->Prcb->VendorString, "GenuineIntel") == 0) {
        switch (CurrentPcr()->Prcb->CpuType) {
            case 5:
                NoCESR    = 1;
                MsrCESR   = 0x11;
                MsrCount  = 0x12;
                Events    = P5Events;
                ProcType  = INTEL_P5;
                ProfileSupported = FALSE;
                break;

            case 6:
                NoCESR    = 2;
                MsrCESR   = 0x186;
                MsrCount  = 0xc1;
                Events    = P6Events;
                ProcType  = INTEL_P6;
                ProfileSupported = TRUE;
                break;

        }
    }

    if (Events) {
        while (Events[MaxEvent].Description) {
            MaxEvent += 1;
        }
    }

    if (ProfileSupported) {
        i = (ULONG) StatProfileInterrupt;
        status = HalSetSystemInformation (
                    HalProfileSourceInterruptHandler,
                    sizeof (i),
                    &i
                    );

        if (!NT_SUCCESS(status)) {
            // hal did not support hooking the performance interrupt
            ProfileSupported = FALSE;
        }
    }

    if (ProfileSupported) {
        //
        // Allocate ProfileEvents
        //

        ProfileEvents = ExAllocatePool (NonPagedPool, sizeof (PROFILE_EVENT) * MaxEvent);

        if (!ProfileEvents) {

            ProfileSupported = FALSE;

        } else {

            RtlZeroMemory (ProfileEvents, sizeof (PROFILE_EVENT) * MaxEvent);

        }
    }


    if (!StatHookTimer()) {
        IoDeleteDevice(DriverObject->DeviceObject);
        return STATUS_UNSUCCESSFUL;
    }

    InitializeListHead (&HookedThunkList);
    InitializeListHead (&LazyFreeList);

    return(STATUS_SUCCESS);
}
示例#20
0
文件: data.c 项目: GYGit/reactos
BOOLEAN
NTAPI
InitializeDeviceData(IN PDEVICE_OBJECT DeviceObject)
{
    PSAC_DEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
    BOOLEAN EnableData;
    ULONG PriorityValue;
    NTSTATUS Status;
    LARGE_INTEGER DueTime;
    PWCHAR Message;
    PAGED_CODE();
    SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n");

    /* If we already did this, bail out */
    if (DeviceExtension->Initialized) goto SuccessExit;

    /* Setup the DO flags */
    DeviceObject->Flags |= DO_DIRECT_IO;
    DeviceObject->StackSize = 16;

    /* Setup the device extension */
    DeviceExtension->DeviceObject = DeviceObject;
    DeviceExtension->PriorityBoost = IO_SERIAL_INCREMENT;
    DeviceExtension->PriorityFail = 0;
    DeviceExtension->RundownInProgress = 0;

    /* Initialize locks, events, timers, DPCs, etc... */
    KeInitializeTimer(&DeviceExtension->Timer);
    KeInitializeDpc(&DeviceExtension->Dpc, TimerDpcRoutine, DeviceExtension);
    KeInitializeSpinLock(&DeviceExtension->Lock);
    KeInitializeEvent(&DeviceExtension->Event, SynchronizationEvent, FALSE);
    InitializeListHead(&DeviceExtension->List);

    /* Attempt to enable HDL support */
    EnableData = TRUE;
    Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
                              &EnableData,
                              sizeof(EnableData),
                              NULL,
                              0);
    if (!NT_SUCCESS(Status))
    {
        /* Bail out if we couldn't even get this far */
        SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (1) with status FALSE\n");
        return FALSE;
    }

    /* Remember which process we started in */
    DeviceExtension->Process = IoGetCurrentProcess();

    /* Protect the device against non-admins */
    Status = CreateDeviceSecurityDescriptor(&DeviceExtension->DeviceObject);
    if (!NT_SUCCESS(Status))
    {
        /* Write down why we failed */
        SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (2) with status FALSE\n");

        /* Disable the HDL terminal on failure */
        EnableData = FALSE;
        Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
                                  &EnableData,
                                  sizeof(EnableData),
                                  NULL,
                                  NULL);
        if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n");

        /* Bail out */
        return FALSE;
    }

    /* Create the worker thread */
    Status = PsCreateSystemThread(&DeviceExtension->WorkerThreadHandle,
                                  THREAD_ALL_ACCESS,
                                  NULL,
                                  NULL,
                                  NULL,
                                  WorkerThreadStartUp,
                                  DeviceExtension);
    if (!NT_SUCCESS(Status))
    {
        /* Write down why we failed */
        SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (3) with status FALSE\n");

        /* Disable the HDL terminal on failure */
        EnableData = FALSE;
        Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
                                  &EnableData,
                                  sizeof(EnableData),
                                  NULL,
                                  NULL);
        if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n");

        /* Bail out */
        return FALSE;
    }

    /* Set the priority of our thread to highest */
    PriorityValue = HIGH_PRIORITY;
    Status = NtSetInformationThread(DeviceExtension->WorkerThreadHandle,
                                    ThreadPriority,
                                    &PriorityValue,
                                    sizeof(PriorityValue));
    if (!NT_SUCCESS(Status))
    {
        /* For debugging, write down why we failed */
        SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting (6) with status FALSE\n");
        DeviceExtension->PriorityFail = TRUE;

        /* Initialize rundown and wait for the thread to do it */
        KeInitializeEvent(&DeviceExtension->RundownEvent, SynchronizationEvent, FALSE);
        KeSetEvent(&DeviceExtension->Event, DeviceExtension->PriorityBoost, FALSE);
        Status = KeWaitForSingleObject(&DeviceExtension->RundownEvent,
                                       Executive,
                                       KernelMode,
                                       FALSE,
                                       NULL);
        ASSERT(Status == STATUS_SUCCESS);

        /* Disable the HDL terminal on failure */
        EnableData = FALSE;
        Status = HeadlessDispatch(HeadlessCmdEnableTerminal,
                                  &EnableData,
                                  sizeof(EnableData),
                                  NULL,
                                  0);
        if (!NT_SUCCESS(Status)) SAC_DBG(SAC_DBG_INIT, "Failed dispatch\n");

        /* Bail out */
        return FALSE;
    }

    /* The first "packet" is the machine information in XML... */
    Status = TranslateMachineInformationXML(&Message, NULL);
    if (NT_SUCCESS(Status))
    {
        /* Go ahead and send it */
        UTF8EncodeAndSend(L"<?xml version=\"1.0\"?>\r\n");
        UTF8EncodeAndSend(Message);

        /* Free the temporary buffer */
        SacFreePool(Message);
    }

    /* Finally, initialize the I/O Manager */
    Status = ConMgrInitialize();
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Set the timer. Once this is done, the device is initialized */
    DueTime.QuadPart = -4000;
    KeSetTimerEx(&DeviceExtension->Timer, DueTime, 4, &DeviceExtension->Dpc);
    DeviceExtension->Initialized = TRUE;

SuccessExit:
    /* Success path -- everything worked */
    SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status TRUE\n");
    return TRUE;
}
示例#21
0
文件: retry.c 项目: hoangduit/reactos
/*
 *  RetryTransferPacket
 *
 *      Retry sending a TRANSFER_PACKET.
 *
 *      Return TRUE iff the packet is complete.
 *          (if so the status in pkt->irp is the final status).
 */
BOOLEAN NTAPI RetryTransferPacket(PTRANSFER_PACKET Pkt)
{
    BOOLEAN packetDone;

    DBGTRACE(ClassDebugTrace, ("retrying failed transfer (pkt=%ph, op=%s)", Pkt, DBGGETSCSIOPSTR(&Pkt->Srb)));

    ASSERT(Pkt->NumRetries > 0);
    Pkt->NumRetries--;

    /*
     *  Tone down performance on the retry.  
     *  This increases the chance for success on the retry.
     *  We've seen instances of drives that fail consistently but then start working
     *  once this scale-down is applied.
     */
    SET_FLAG(Pkt->Srb.SrbFlags, SRB_FLAGS_DISABLE_DISCONNECT);
    SET_FLAG(Pkt->Srb.SrbFlags, SRB_FLAGS_DISABLE_SYNCH_TRANSFER);
    CLEAR_FLAG(Pkt->Srb.SrbFlags, SRB_FLAGS_QUEUE_ACTION_ENABLE);
    Pkt->Srb.QueueTag = SP_UNTAGGED;

    if (Pkt->Irp->IoStatus.Status == STATUS_INSUFFICIENT_RESOURCES){
        PCDB pCdb = (PCDB)Pkt->Srb.Cdb;
        BOOLEAN isReadWrite = ((pCdb->CDB10.OperationCode == SCSIOP_READ) ||
                                                (pCdb->CDB10.OperationCode == SCSIOP_WRITE));
    
        if (Pkt->InLowMemRetry || !isReadWrite){
            /*
             *  This should never happen.
             *  The memory manager guarantees that at least four pages will
             *  be available to allow forward progress in the port driver.
             *  So a one-page transfer should never fail with insufficient resources.
             */
            ASSERT(isReadWrite && !Pkt->InLowMemRetry);
            packetDone = TRUE;
        }
        else {
            /*
             *  We are in low-memory stress.  
             *  Start the low-memory retry state machine, which tries to
             *  resend the packet in little one-page chunks.
             */
            InitLowMemRetry(  Pkt, 
                                        Pkt->BufPtrCopy, 
                                        Pkt->BufLenCopy, 
                                        Pkt->TargetLocationCopy); 
            StepLowMemRetry(Pkt);
            packetDone = FALSE;
        }
    }
    else {      
        /*
         *  Retry the packet by simply resending it after a delay.
         *  Put the packet back in the pending queue and
         *  schedule a timer to retry the transfer.
         *
         *  Do not call SetupReadWriteTransferPacket again because:
         *  (1)  The minidriver may have set some bits 
         *       in the SRB that it needs again and
         *  (2)  doing so would reset numRetries.
         *
         *  BECAUSE we do not call SetupReadWriteTransferPacket again,
         *  we have to reset a couple fields in the SRB that
         *  some miniports overwrite when they fail an SRB.
         */
         
        Pkt->Srb.DataBuffer = Pkt->BufPtrCopy;
        Pkt->Srb.DataTransferLength = Pkt->BufLenCopy;
        
        if (Pkt->RetryIntervalSec == 0){
            /*
             *  Always delay by at least a little when retrying.
             *  Some problems (e.g. CRC errors) are not recoverable without a slight delay.
             */
            LARGE_INTEGER timerPeriod;

            timerPeriod.HighPart = -1;
            timerPeriod.LowPart = -(LONG)((ULONG)MINIMUM_RETRY_UNITS*KeQueryTimeIncrement());
            KeInitializeTimer(&Pkt->RetryTimer);
            KeInitializeDpc(&Pkt->RetryTimerDPC, TransferPacketRetryTimerDpc, Pkt);
            KeSetTimer(&Pkt->RetryTimer, timerPeriod, &Pkt->RetryTimerDPC);            
        }
        else {
            LARGE_INTEGER timerPeriod;

            ASSERT(Pkt->RetryIntervalSec < 100);    // sanity check
            timerPeriod.HighPart = -1;
            timerPeriod.LowPart = Pkt->RetryIntervalSec*-10000000;
            KeInitializeTimer(&Pkt->RetryTimer);
            KeInitializeDpc(&Pkt->RetryTimerDPC, TransferPacketRetryTimerDpc, Pkt);
            KeSetTimer(&Pkt->RetryTimer, timerPeriod, &Pkt->RetryTimerDPC);
        }
        packetDone = FALSE;
    }

    return packetDone;
}
示例#22
0
/*++

ClasspInitializeIdleTimer

Routine Description:

    Initialize the idle timer for the given device.

Arguments:

    FdoExtension    - Pointer to the device extension
    IdleInterval    - Timer interval

Return Value:

    None

--*/
VOID
ClasspInitializeIdleTimer(
    PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
    )
{
    PCLASS_PRIVATE_FDO_DATA fdoData = FdoExtension->PrivateFdoData;
    ULONG idleInterval = CLASS_IDLE_INTERVAL;
    ULONG idlePrioritySupported = TRUE;
    ULONG activeIdleIoMax = 1;

    ClassGetDeviceParameter(FdoExtension,
                            CLASSP_REG_SUBKEY_NAME,
                            CLASSP_REG_IDLE_PRIORITY_SUPPORTED,
                            &idlePrioritySupported);


    if (idlePrioritySupported == FALSE) {
        //
        // User has set the registry to disable idle priority for this disk.
        // No need to initialize any further.
        // Always ensure that none of the other fields used for idle priority
        // io are ever used without checking if it is supported.
        //
        TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_TIMER, "ClasspInitializeIdleTimer: Idle priority not supported for disk %p\n", FdoExtension));
        fdoData->IdlePrioritySupported = FALSE;
        fdoData->IdleIoCount = 0;
        fdoData->ActiveIoCount = 0;
        return;
    }

    ClassGetDeviceParameter(FdoExtension,
                            CLASSP_REG_SUBKEY_NAME,
                            CLASSP_REG_IDLE_INTERVAL_NAME,
                            &idleInterval);

    if ((idleInterval < CLASS_IDLE_TIMER_TICKS) || (idleInterval > USHORT_MAX)) {
        //
        // If the interval is too low or too high, reset it to the default value.
        //
        idleInterval = CLASS_IDLE_INTERVAL;
    }

    fdoData->IdlePrioritySupported = TRUE;
    KeInitializeSpinLock(&fdoData->IdleListLock);
    KeInitializeTimer(&fdoData->IdleTimer);
    KeInitializeDpc(&fdoData->IdleDpc, ClasspIdleTimerDpc, FdoExtension);
    InitializeListHead(&fdoData->IdleIrpList);
    fdoData->IdleTimerStarted = FALSE;
    fdoData->IdleTimerInterval = (USHORT) (idleInterval / CLASS_IDLE_TIMER_TICKS);
    fdoData->StarvationCount = CLASS_STARVATION_INTERVAL / fdoData->IdleTimerInterval;

    //
    // Due to the coarseness of the idle timer frequency, some variability in
    // the idle interval will be tolerated such that it is the desired idle
    // interval on average.
    fdoData->IdleInterval =
        (USHORT)(idleInterval - (fdoData->IdleTimerInterval / 2));

    fdoData->IdleTimerTicks = 0;
    fdoData->IdleTicks = 0;
    fdoData->IdleIoCount = 0;
    fdoData->ActiveIoCount = 0;
    fdoData->ActiveIdleIoCount = 0;

    ClassGetDeviceParameter(FdoExtension,
                            CLASSP_REG_SUBKEY_NAME,
                            CLASSP_REG_IDLE_ACTIVE_MAX,
                            &activeIdleIoMax);

    activeIdleIoMax = max(activeIdleIoMax, 1);
    activeIdleIoMax = min(activeIdleIoMax, USHORT_MAX);

    fdoData->IdleActiveIoMax = (USHORT)activeIdleIoMax;

    return;
}
示例#23
0
NTSTATUS NTAPI
TiDispatch(
  PDEVICE_OBJECT DeviceObject,
  PIRP Irp)
/*
 * FUNCTION: Dispatch routine for IRP_MJ_DEVICE_CONTROL requests
 * ARGUMENTS:
 *     DeviceObject = Pointer to a device object for this driver
 *     Irp          = Pointer to a I/O request packet
 * RETURNS:
 *     Status of the operation
 */
{


  NTSTATUS Status;
  PIO_STACK_LOCATION IrpSp;

  IrpSp  = IoGetCurrentIrpStackLocation(Irp);

  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Called. IRP is at (0x%X).\n", Irp));
  DbgPrint("TiDispatch Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp);
  Irp->IoStatus.Information = 0;

#if 0
  Status = TdiMapUserRequest(DeviceObject, Irp, IrpSp);
  if (NT_SUCCESS(Status)) {
    TiDispatchInternal(DeviceObject, Irp);
    Status = STATUS_PENDING;
  } else {
#else
  if (TRUE) {
#endif
    /* See if this request is TCP/IP specific */
    switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) {
    case IOCTL_TCP_QUERY_INFORMATION_EX:
      TI_DbgPrint(MIN_TRACE, ("TCP_QUERY_INFORMATION_EX\n"));
      Status = DispTdiQueryInformationEx(Irp, IrpSp);
      break;

    case IOCTL_TCP_SET_INFORMATION_EX:
      TI_DbgPrint(MIN_TRACE, ("TCP_SET_INFORMATION_EX\n"));
      Status = DispTdiSetInformationEx(Irp, IrpSp);
      break;

    case IOCTL_SET_IP_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("SET_IP_ADDRESS\n"));
      Status = DispTdiSetIPAddress(Irp, IrpSp);
      break;

    case IOCTL_DELETE_IP_ADDRESS:
      TI_DbgPrint(MIN_TRACE, ("DELETE_IP_ADDRESS\n"));
      Status = DispTdiDeleteIPAddress(Irp, IrpSp);
      break;

    default:
      TI_DbgPrint(MIN_TRACE, ("Unknown IOCTL 0x%X\n",
          IrpSp->Parameters.DeviceIoControl.IoControlCode));
      Status = STATUS_NOT_IMPLEMENTED;
      break;
    }
  }

  TI_DbgPrint(DEBUG_IRP, ("[TCPIP, TiDispatch] Leaving. Status = (0x%X).\n", Status));

  return IRPFinish( Irp, Status );


}
NTSTATUS
DriverEntry(
		  PDRIVER_OBJECT DriverObject,
		  PUNICODE_STRING RegistryPath)
{
  NTSTATUS Status;
  UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
  UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
  UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
  UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
  UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME);
  NDIS_STATUS NdisStatus;
  LARGE_INTEGER DueTime;
  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] \n"));
  
  //_asm int 3;

  KdPrint(("driver entery..................\n"));

  /* TdiInitialize() ? */

  /* FIXME: Create symbolic links in Win32 namespace */

  /* Initialize our periodic timer and its associated DPC object. When the
     timer expires, the IPTimeout deferred procedure call (DPC) is queued */
  KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
  KeInitializeTimer(&IPTimer);
	 
  /* Create IP device object */
  Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  ChewInit( IPDeviceObject );
	 

  /* Create RawIP device object */
  Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create UDP device object */
  Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create TCP device object */
  Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }


  /* Setup network layer and transport layer entities */
  KeInitializeSpinLock(&EntityListLock);
  EntityList = ExAllocatePoolWithTag(NonPagedPool,
                                     sizeof(TDIEntityID) * MAX_TDI_ENTITIES,
                                     TDI_ENTITY_TAG );

  if (!EntityList) {
    TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  EntityCount = 0;
  EntityMax   = MAX_TDI_ENTITIES;

  /* Allocate NDIS packet descriptors */
  NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT));
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Allocate NDIS buffer descriptors */
  NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000);
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Initialize address file list and protecting spin lock */
  InitializeListHead(&AddressFileListHead);
  KeInitializeSpinLock(&AddressFileListLock);

  /* Initialize connection endpoint list and protecting spin lock */
  InitializeListHead(&ConnectionEndpointListHead);
  KeInitializeSpinLock(&ConnectionEndpointListLock);

  /* Initialize interface list and protecting spin lock */
  InitializeListHead(&InterfaceListHead);
  KeInitializeSpinLock(&InterfaceListLock);



  /* Initialize network level protocol subsystem */
  IPStartup(RegistryPath);

  /* Initialize transport level protocol subsystems */
  Status = RawIPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = UDPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = TCPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = ICMPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  /* Use direct I/O */
  IPDeviceObject->Flags    |= DO_DIRECT_IO;
  RawIPDeviceObject->Flags |= DO_DIRECT_IO;
  UDPDeviceObject->Flags   |= DO_DIRECT_IO;
  TCPDeviceObject->Flags   |= DO_DIRECT_IO;

  /* Initialize the driver object with this driver's entry points */
  DriverObject->MajorFunction[IRP_MJ_CREATE]  = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_CLOSE]   = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch;

  DriverObject->DriverUnload = TiUnload;

  /* Open loopback adapter */
  Status = LoopRegisterAdapter(NULL, NULL);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Register protocol with NDIS */
  /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
  Status = LANRegisterProtocol(&strNdisDeviceName);
  if (!NT_SUCCESS(Status)) {
	  TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
	  TiWriteErrorLog(
      DriverObject,
      EVENT_TRANSPORT_REGISTER_FAILED,
      TI_ERROR_DRIVERENTRY,
      Status,
      NULL,
      0,
      NULL);
      TiUnload(DriverObject);
      return Status;
  }

  /* Start the periodic timer with an initial and periodic
     relative expiration time of IP_TIMEOUT milliseconds */
  DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
  KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n"));


  return STATUS_SUCCESS;

}
示例#24
0
文件: kdinit.c 项目: conioh/os-design
BOOLEAN
KdInitSystem(
    IN PLOADER_PARAMETER_BLOCK LoaderBlock OPTIONAL,
    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;

        //
        // Initialize the debugger data block list when called at startup time.
        //

        InitializeListHead(&KdpDebuggerDataListHead);

        //
        // Fill in and register the debugger's debugger data block.
        // Most fields are already initialized, some fields will not be
        // filled in until later.
        //

        KdDebuggerDataBlock.KernBase = (ULONG_PTR) KdpNtosImageBase;
        KdDebuggerDataBlock.KeUserCallbackDispatcher = (ULONG_PTR) KeUserCallbackDispatcher;

        KdRegisterDebuggerDataBlock(KDBG_TAG,
                                    &KdDebuggerDataBlock.Header,
                                    sizeof(KdDebuggerDataBlock));

        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 disabled, 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);
    }

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

    KiDebugRoutine = KdpTrap;

    if (!KdpDebuggerStructuresInitialized) {

        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;
        }

        //
        // Initialize TimeSlip
        //
        KeInitializeDpc(&KdpTimeSlipDpc, KdpTimeSlipDpcRoutine, NULL);
        KeInitializeTimer(&KdpTimeSlipTimer);
        ExInitializeWorkItem(&KdpTimeSlipWorkItem, KdpTimeSlipWork, NULL);

        KdpDebuggerStructuresInitialized = 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;

    //
    // Mark debugger enabled.
    //
    KdPitchDebugger = FALSE;
    KdDebuggerEnabled = TRUE;
    SharedUserData->KdDebuggerEnabled = TRUE;

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

    if (StopInDebugger) {
        DbgBreakPoint();
    }

    return TRUE;
}
示例#25
0
/*	Main entry point into the driver, is called when the driver is loaded */
NTSTATUS DriverEntry(
	IN PDRIVER_OBJECT DriverObject, 
	IN PUNICODE_STRING RegistryPath
	)
{
	NTSTATUS status;
	OBJECT_ATTRIBUTES objectAttributes;
	PSECURITY_DESCRIPTOR pSecurityDescriptor;
	UNICODE_STRING fileMonitorPortName;
	LARGE_INTEGER fileEventsTimeout;
	busy = FALSE;
	fileManager.bReady = FALSE;
	fileManager.bCollectDeletedFiles = FALSE;
	KeInitializeSpinLock(&fileManager.lQueuedFileEventsSpinLock);
	InitializeListHead(&fileManager.lQueuedFileEvents);
	fileManager.pDriverObject = DriverObject;
	//fileManager.logDirectory.Buffer = NULL;

	/* Register driver with the filter manager */
	status = FltRegisterFilter(DriverObject, &FilterRegistration, &fileManager.pFilter);

	if (!NT_SUCCESS(status))
	{
		DbgPrint("CaptureFileMonitor: ERROR FltRegisterFilter - %08x\n", status); 
		return status;
	}

	status  = FltBuildDefaultSecurityDescriptor( &pSecurityDescriptor, FLT_PORT_ALL_ACCESS );

	if (!NT_SUCCESS(status))
	{
		DbgPrint("CaptureFileMonitor: ERROR FltBuildDefaultSecurityDescriptor - %08x\n", status);
		return status;
	}

	RtlInitUnicodeString( &fileMonitorPortName, CAPTURE_FILEMON_PORT_NAME );
	InitializeObjectAttributes( &objectAttributes,
								&fileMonitorPortName,
								OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
								NULL,
								pSecurityDescriptor);

	/* Create the communications port to communicate with the user space process (pipe) */
	status = FltCreateCommunicationPort( fileManager.pFilter,
                                             &fileManager.pServerPort,
                                             &objectAttributes,
                                             NULL,
                                             ConnectCallback,
                                             DisconnectCallback,
                                             MessageCallback,
                                             1 );

	FltFreeSecurityDescriptor(pSecurityDescriptor);

	/* Start the filtering */
	if(NT_SUCCESS(status))
	{
		status = FltStartFiltering(fileManager.pFilter);
		if(!NT_SUCCESS(status))
		{
			DbgPrint("CaptureFileMonitor: ERROR FltStartFiltering - %08x\n", status);
		}
	} else {
		DbgPrint("CaptureFileMonitor: ERROR FltCreateCommunicationPort - %08x\n", status);
	}

	/* If there was a problem during initialisation of the filter then uninstall everything */
	if(!NT_SUCCESS(status))
	{
		if (fileManager.pServerPort != NULL)
			FltCloseCommunicationPort(fileManager.pServerPort);
		if (fileManager.pFilter != NULL)
			FltUnregisterFilter(fileManager.pFilter);
		return status;
	}

	UpdateLastContactTime();

	/* Create a DPC routine so that it can be called periodically */
	KeInitializeDpc(&fileManager.connectionCheckerFunction, 
		(PKDEFERRED_ROUTINE)ConnectionChecker, &fileManager);
	KeInitializeTimer(&fileManager.connectionCheckerTimer);
	fileEventsTimeout.QuadPart = 0;

	/* Set the ConnectionChecker routine to be called every so often */
	KeSetTimerEx(&fileManager.connectionCheckerTimer, 
		fileEventsTimeout, 
		(USERSPACE_CONNECTION_TIMEOUT+(USERSPACE_CONNECTION_TIMEOUT/2))*1000, 
		&fileManager.connectionCheckerFunction);

	fileManager.bReady = TRUE;
	fileManager.logDirectory.Length = 0;
	fileManager.logDirectory.Buffer = NULL;
	DbgPrint("CaptureFileMonitor: Successfully Loaded\n");

	return STATUS_SUCCESS;
}
示例#26
0
VOID
ExpWorkerThreadBalanceManager (
    IN PVOID StartContext
    )

/*++

Routine Description:

    This function is the startup code for the worker thread manager thread.
    The worker thread manager thread is created during system initialization
    and begins execution in this function.

    This thread is responsible for detecting and breaking circular deadlocks
    in the system worker thread queues.  It will also create and destroy
    additional worker threads as needed based on loading.

Arguments:

    Context - Supplies a pointer to an arbitrary data structure (NULL).

Return Value:

    None.

--*/
{
    KTIMER PeriodTimer;
    LARGE_INTEGER DueTime;
    PVOID WaitObjects[MaximumBalanceObject];
    NTSTATUS Status;

    PAGED_CODE();

    UNREFERENCED_PARAMETER (StartContext);

    //
    // Raise the thread priority to just higher than the priority of the
    // critical work queue.
    //

    KeSetBasePriorityThread (KeGetCurrentThread(),
                             CRITICAL_WORK_QUEUE_PRIORITY + 1);

    //
    // Initialize the periodic timer and set the manager period.
    //

    KeInitializeTimer (&PeriodTimer);
    DueTime.QuadPart = - THREAD_SET_INTERVAL;

    //
    // Initialize the wait object array.
    //

    WaitObjects[TimerExpiration] = (PVOID)&PeriodTimer;
    WaitObjects[ThreadSetManagerEvent] = (PVOID)&ExpThreadSetManagerEvent;
    WaitObjects[ShutdownEvent] = (PVOID)&ExpThreadSetManagerShutdownEvent;

    //
    // Loop forever processing events.
    //

    while (TRUE) {

        //
        // Set the timer to expire at the next periodic interval.
        //

        KeSetTimer (&PeriodTimer, DueTime, NULL);

        //
        // Wake up when the timer expires or the set manager event is
        // signaled.
        //

        Status = KeWaitForMultipleObjects (MaximumBalanceObject,
                                           WaitObjects,
                                           WaitAny,
                                           Executive,
                                           KernelMode,
                                           FALSE,
                                           NULL,
                                           NULL);

        switch (Status) {

            case TimerExpiration:

                //
                // Periodic timer expiration - go see if any work queues
                // are deadlocked.
                //

                ExpDetectWorkerThreadDeadlock ();
                break;

            case ThreadSetManagerEvent:

                //
                // Someone has asked us to check some metrics to determine
                // whether we should create another worker thread.
                //

                ExpCheckDynamicThreadCount ();
                break;

            case ShutdownEvent:

                //
                // Time to exit...
                //

                KeCancelTimer (&PeriodTimer);

                ASSERT (ExpLastWorkerThread);

                //
                // Wait for the last worker thread to terminate
                //

                KeWaitForSingleObject (ExpLastWorkerThread,
                                       Executive,
                                       KernelMode,
                                       FALSE,
                                       NULL);

                ObDereferenceObject (ExpLastWorkerThread);

                PsTerminateSystemThread(STATUS_SYSTEM_SHUTDOWN);

                break;
        }

        //
        // Special debugger support.
        //
        // This checks if special debugging routines need to be run on the
        // behalf of the debugger.
        //

        if (ExpDebuggerWork == 1) {

             ExInitializeWorkItem(&ExpDebuggerWorkItem, ExpDebuggerWorker, NULL);
             ExpDebuggerWork = 2;
             ExQueueWorkItem(&ExpDebuggerWorkItem, DelayedWorkQueue);
        }
    }
}
示例#27
0
static NTSTATUS NTAPI
InitController(PCONTROLLER_INFO ControllerInfo)
/*
 * FUNCTION:  Initialize a newly-found controller
 * ARGUMENTS:
 *     ControllerInfo: pointer to the controller to be initialized
 * RETURNS:
 *     STATUS_SUCCESS if the controller is successfully initialized
 *     STATUS_IO_DEVICE_ERROR otherwise
 */
{
    int i;
    UCHAR HeadLoadTime;
    UCHAR HeadUnloadTime;
    UCHAR StepRateTime;

    PAGED_CODE();
    ASSERT(ControllerInfo);

    TRACE_(FLOPPY, "InitController called with Controller 0x%p\n", ControllerInfo);

    KeClearEvent(&ControllerInfo->SynchEvent);

    INFO_(FLOPPY, "InitController: resetting the controller\n");

    /* Reset the controller */
    if(HwReset(ControllerInfo) != STATUS_SUCCESS)
    {
        WARN_(FLOPPY, "InitController: unable to reset controller\n");
        return STATUS_IO_DEVICE_ERROR;
    }

    /* All controllers should support this so
     * if we get something strange back then we
     * know that this isn't a floppy controller
     */
    if (HwGetVersion(ControllerInfo) <= 0)
    {
        WARN_(FLOPPY, "InitController: unable to contact controller\n");
        return STATUS_NO_SUCH_DEVICE;
    }

    /* Reset the controller to avoid interrupt garbage on certain controllers */
    if(HwReset(ControllerInfo) != STATUS_SUCCESS)
    {
        WARN_(FLOPPY, "InitController: unable to reset controller #2\n");
        return STATUS_IO_DEVICE_ERROR;
    }

    INFO_(FLOPPY, "InitController: setting data rate\n");

    /* Set data rate */
    if(HwSetDataRate(ControllerInfo, DRSR_DSEL_500KBPS) != STATUS_SUCCESS)
    {
        WARN_(FLOPPY, "InitController: unable to set data rate\n");
        return STATUS_IO_DEVICE_ERROR;
    }

    INFO_(FLOPPY, "InitController: waiting for initial interrupt\n");

    /* Wait for an interrupt */
    WaitForControllerInterrupt(ControllerInfo);

    /* Reset means you have to clear each of the four interrupts (one per drive) */
    for(i = 0; i < MAX_DRIVES_PER_CONTROLLER; i++)
    {
        INFO_(FLOPPY, "InitController: Sensing interrupt %d\n", i);

        if(HwSenseInterruptStatus(ControllerInfo) != STATUS_SUCCESS)
        {
            WARN_(FLOPPY, "InitController: Unable to clear interrupt 0x%x\n", i);
            return STATUS_IO_DEVICE_ERROR;
        }
    }

    INFO_(FLOPPY, "InitController: done sensing interrupts\n");

    /* Next, see if we have the right version to do implied seek */
    if(HwGetVersion(ControllerInfo) == VERSION_ENHANCED)
    {
        /* If so, set that up -- all defaults below except first TRUE for EIS */
        if(HwConfigure(ControllerInfo, TRUE, TRUE, FALSE, 0, 0) != STATUS_SUCCESS)
        {
            WARN_(FLOPPY, "InitController: unable to set up implied seek\n");
            ControllerInfo->ImpliedSeeks = FALSE;
        }
        else
        {
            INFO_(FLOPPY, "InitController: implied seeks set!\n");
            ControllerInfo->ImpliedSeeks = TRUE;
        }

        /*
         * FIXME: Figure out the answer to the below
         *
         * I must admit that I'm really confused about the Model 30 issue.  At least one
         * important bit (the disk change bit in the DIR) is flipped if this is a Model 30
         * controller.  However, at least one other floppy driver believes that there are only
         * two computers that are guaranteed to have a Model 30 controller:
         *  - IBM Thinkpad 750
         *  - IBM PS2e
         *
         * ...and another driver only lists a config option for "thinkpad", that flips
         * the change line.  A third driver doesn't mention the Model 30 issue at all.
         *
         * What I can't tell is whether or not the average, run-of-the-mill computer now has
         * a Model 30 controller.  For the time being, I'm going to wire this to FALSE,
         * and just not support the computers mentioned above, while I try to figure out
         * how ubiquitous these newfangled 30 thingies are.
         */
        //ControllerInfo->Model30 = TRUE;
        ControllerInfo->Model30 = FALSE;
    }
    else
    {
        INFO_(FLOPPY, "InitController: enhanced version not supported; disabling implied seeks\n");
        ControllerInfo->ImpliedSeeks = FALSE;
        ControllerInfo->Model30 = FALSE;
    }

    /* Specify */
    WARN_(FLOPPY, "FIXME: Figure out speed\n");
    HeadLoadTime = SPECIFY_HLT_500K;
    HeadUnloadTime = SPECIFY_HUT_500K;
    StepRateTime = SPECIFY_SRT_500K;

    INFO_(FLOPPY, "InitController: issuing specify command to controller\n");

    /* Don't disable DMA --> enable dma (dumb & confusing) */
    if(HwSpecify(ControllerInfo, HeadLoadTime, HeadUnloadTime, StepRateTime, FALSE) != STATUS_SUCCESS)
    {
        WARN_(FLOPPY, "InitController: unable to specify options\n");
        return STATUS_IO_DEVICE_ERROR;
    }

    /* Init the stop stuff */
    KeInitializeDpc(&ControllerInfo->MotorStopDpc, MotorStopDpcFunc, ControllerInfo);
    KeInitializeTimer(&ControllerInfo->MotorTimer);
    KeInitializeEvent(&ControllerInfo->MotorStoppedEvent, NotificationEvent, FALSE);
    ControllerInfo->StopDpcQueued = FALSE;

    /*
     * Recalibrate each drive on the controller (depends on StartMotor, which depends on the timer stuff above)
     * We don't even know if there is a disk in the drive, so this may not work, but that's OK.
     */
    for(i = 0; i < ControllerInfo->NumberOfDrives; i++)
    {
        INFO_(FLOPPY, "InitController: recalibrating drive 0x%x on controller 0x%p\n", i, ControllerInfo);
        Recalibrate(&ControllerInfo->DriveInfo[i]);
    }

    INFO_(FLOPPY, "InitController: done initializing; returning STATUS_SUCCESS\n");

    return STATUS_SUCCESS;
}
示例#28
0
NTSTATUS
LMInitialize(
	IN PLURELATION_NODE		Lurn,
	IN PBUFFLOCK_CONTROL	BuffLockCtl,
	IN BOOLEAN				InitialState
){

	RtlZeroMemory(BuffLockCtl, sizeof(PBUFFLOCK_CONTROL));

	//
	// Timer resolution data:
	//
	// Windows Vista Business x86 with Xeon SMP: 1/64 second per tick. ( 15.6250 msec )
	// Windows Vista Enterprise x86_64 with AMD Sempron 2600+: 1/64
	// Windows XP Professional x86 with VMWare 5.5: 1/64
	// Windows XP Professional x86 with Xeon SMP: 1/64
	// Windows XP Professional x86 with Dell Latitude D520 note book: 15.6001 msec per tick.
	//
	BuffLockCtl->TimerResolution = KeQueryTimeIncrement();
	KDPrintM(DBG_OTHER_ERROR, ("KeQueryTickCount()'s 100nano per tick = %u, LOCKMGMT_QUANTUM = %u\n", 
								BuffLockCtl->TimerResolution, LOCKMGMT_QUANTUM));

	BuffLockCtl->Quantum.QuadPart = LOCKMGMT_QUANTUM;
	BuffLockCtl->PriorityWaitTime.QuadPart = LOCKMGMT_PRIORITYWAITTIME;
	BuffLockCtl->AcquisitionMaxTime.QuadPart = LOCKMGMT_MAX_ACQUISITION_TIME;
	BuffLockCtl->AcquisitionExpireTime.QuadPart = 0;
	BuffLockCtl->MaxIOBytes = LOCKMGMT_MAX_ACQUISITION_BYTES;
	BuffLockCtl->IoIdleTimeOut.QuadPart = LOCKMGMT_IOIDLE_TIMEOUT;
	BuffLockCtl->IoIdle = TRUE;
	BuffLockCtl->ConnectedHosts = 1; // add myself.
	BuffLockCtl->CurrentLockCount = 0;
	BuffLockCtl->RequestCountWhenReleased = 0;
	BuffLockCtl->Priority = 0;
	KeInitializeTimer(&BuffLockCtl->IoIdleTimer);
	BuffLockCtl->AccumulatedIOBytes = 0;
	BuffLockCtl->BufferLockConrol = InitialState;

#if __NDAS_SCSI_DISABLE_LOCK_RELEASE_DELAY__
	if (LURN_IS_ROOT_NODE(Lurn)) {

		BuffLockCtl->BufferLockParent = FALSE;
	
	} else {

		BuffLockCtl->BufferLockParent = TRUE;
		// Must be off when the parent controls the buffer lock.
		BuffLockCtl->BufferLockConrol = FALSE;
	}
#else
	BuffLockCtl->BufferLockParent = FALSE;
#endif

#if DBG
	if(BuffLockCtl->BufferLockParent)
		ASSERT(BuffLockCtl->BufferLockConrol == FALSE);
	KDPrintM(DBG_LURN_ERROR, ("Buffer lock control:%x Controlled by parent:%x\n",
		BuffLockCtl->BufferLockConrol,
		BuffLockCtl->BufferLockParent));
#endif

	return STATUS_SUCCESS;
}
示例#29
0
NTSTATUS DriverEntry(
    __in PDRIVER_OBJECT  DriverObject,
    __in PUNICODE_STRING RegistryPath
    )
{
    PDEVICE_OBJECT      deviceObject;
    PDEVICE_EXTENSION   pContext;
    UNICODE_STRING      ntDeviceName;
    UNICODE_STRING      symbolicLinkName;
    NTSTATUS            status;

    UNREFERENCED_PARAMETER(RegistryPath);

    DebugPrint(("==>DriverEntry\n"));

    // 创建设备对象
    RtlInitUnicodeString(&ntDeviceName, NTDEVICE_NAME_STRING);

    status = IoCreateDevice(DriverObject,               // DriverObject
                            sizeof(DEVICE_EXTENSION),   // DeviceExtensionSize
                            &ntDeviceName,              // DeviceName
                            FILE_DEVICE_UNKNOWN,        // DeviceType
                            FILE_DEVICE_SECURE_OPEN,    // DeviceCharacteristics
                            FALSE,                      // Not Exclusive
                            &deviceObject);             // DeviceObject
        
    if (!NT_SUCCESS(status)) {
        DebugPrint(("\tIoCreateDevice returned 0x%x\n", status));
        return(status);
    }

    DriverObject->MajorFunction[IRP_MJ_CREATE]          = DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]           = DispatchCreateClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = DispatchDispatchIoControl;
    DriverObject->DriverUnload                          = DrvUnload;

    RtlInitUnicodeString(&symbolicLinkName, SYMBOLIC_NAME_STRING);
    status = IoCreateSymbolicLink(&symbolicLinkName, &ntDeviceName);

    if (!NT_SUCCESS(status)) 
	{
        IoDeleteDevice(deviceObject);
        DebugPrint(("\tIoCreateSymbolicLink returned 0x%x\n", status));
        return(status);
    }

    pContext = deviceObject->DeviceExtension;
    RtlZeroMemory(pContext, sizeof(DEVICE_EXTENSION));

    pContext->Self = deviceObject;
	pContext->bStoppingDPC = TRUE;
	pContext->ulSampleRate = 44100; // 初始采样率。我们没有提供给用户设置采样率的接口。所以它总是固定的。

    // 初始化计时器
    KeInitializeDpc (
        &pContext->TimerDpc,
        TimerDpc,
        deviceObject
        );
	
    KeInitializeEvent (
        &pContext->StopDPCEvent,
        SynchronizationEvent,
        FALSE
        );

    KeInitializeTimer (&pContext->Timer);

    // 用户缓冲区方式
    deviceObject->Flags |= DO_BUFFERED_IO;
    return status;
}
示例#30
-1
文件: main.c 项目: GYGit/reactos
NTSTATUS NTAPI
DriverEntry(
  PDRIVER_OBJECT DriverObject,
  PUNICODE_STRING RegistryPath)
/*
 * FUNCTION: Main driver entry point
 * ARGUMENTS:
 *     DriverObject = Pointer to a driver object for this driver
 *     RegistryPath = Registry node for configuration parameters
 * RETURNS:
 *     Status of driver initialization
 */
{
  NTSTATUS Status;
  UNICODE_STRING strIpDeviceName = RTL_CONSTANT_STRING(DD_IP_DEVICE_NAME);
  UNICODE_STRING strRawDeviceName = RTL_CONSTANT_STRING(DD_RAWIP_DEVICE_NAME);
  UNICODE_STRING strUdpDeviceName = RTL_CONSTANT_STRING(DD_UDP_DEVICE_NAME);
  UNICODE_STRING strTcpDeviceName = RTL_CONSTANT_STRING(DD_TCP_DEVICE_NAME);
  UNICODE_STRING strNdisDeviceName = RTL_CONSTANT_STRING(TCPIP_PROTOCOL_NAME);
  NDIS_STATUS NdisStatus;
  LARGE_INTEGER DueTime;

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Called\n"));

  /* TdiInitialize() ? */

  /* FIXME: Create symbolic links in Win32 namespace */

  /* Initialize our periodic timer and its associated DPC object. When the
     timer expires, the IPTimeout deferred procedure call (DPC) is queued */
  KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL);
  KeInitializeTimer(&IPTimer);

  /* Create IP device object */
  Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  ChewInit( IPDeviceObject );

  /* Create RawIP device object */
  Status = IoCreateDevice(DriverObject, 0, &strRawDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create UDP device object */
  Status = IoCreateDevice(DriverObject, 0, &strUdpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Create TCP device object */
  Status = IoCreateDevice(DriverObject, 0, &strTcpDeviceName,
    FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Setup network layer and transport layer entities */
  KeInitializeSpinLock(&EntityListLock);
  EntityList = ExAllocatePoolWithTag(NonPagedPool,
                                     sizeof(TDIEntityID) * MAX_TDI_ENTITIES,
                                     TDI_ENTITY_TAG );
  if (!EntityList) {
    TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  EntityCount = 0;
  EntityMax   = MAX_TDI_ENTITIES;

  /* Allocate NDIS packet descriptors */
  NdisAllocatePacketPoolEx(&NdisStatus, &GlobalPacketPool, 500, 1500, sizeof(PACKET_CONTEXT));
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Allocate NDIS buffer descriptors */
  NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 2000);
  if (NdisStatus != NDIS_STATUS_SUCCESS) {
    TiUnload(DriverObject);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  /* Initialize address file list and protecting spin lock */
  InitializeListHead(&AddressFileListHead);
  KeInitializeSpinLock(&AddressFileListLock);

  /* Initialize connection endpoint list and protecting spin lock */
  InitializeListHead(&ConnectionEndpointListHead);
  KeInitializeSpinLock(&ConnectionEndpointListLock);

  /* Initialize interface list and protecting spin lock */
  InitializeListHead(&InterfaceListHead);
  KeInitializeSpinLock(&InterfaceListLock);

  /* Initialize network level protocol subsystem */
  IPStartup(RegistryPath);

  /* Initialize transport level protocol subsystems */
  Status = RawIPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = UDPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = TCPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  Status = ICMPStartup();
  if( !NT_SUCCESS(Status) ) {
      TiUnload(DriverObject);
      return Status;
  }

  /* Use direct I/O */
  IPDeviceObject->Flags    |= DO_DIRECT_IO;
  RawIPDeviceObject->Flags |= DO_DIRECT_IO;
  UDPDeviceObject->Flags   |= DO_DIRECT_IO;
  TCPDeviceObject->Flags   |= DO_DIRECT_IO;

  /* Initialize the driver object with this driver's entry points */
  DriverObject->MajorFunction[IRP_MJ_CREATE]  = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_CLOSE]   = TiDispatchOpenClose;
  DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = TiDispatchInternal;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TiDispatch;

  DriverObject->DriverUnload = TiUnload;

  /* Open loopback adapter */
  Status = LoopRegisterAdapter(NULL, NULL);
  if (!NT_SUCCESS(Status)) {
    TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status));
    TiUnload(DriverObject);
    return Status;
  }

  /* Register protocol with NDIS */
  /* This used to be IP_DEVICE_NAME but the DDK says it has to match your entry in the SCM */
  Status = LANRegisterProtocol(&strNdisDeviceName);
  if (!NT_SUCCESS(Status)) {
	  TI_DbgPrint(MIN_TRACE,("Failed to register protocol with NDIS; status 0x%x\n", Status));
	  TiWriteErrorLog(
      DriverObject,
      EVENT_TRANSPORT_REGISTER_FAILED,
      TI_ERROR_DRIVERENTRY,
      Status,
      NULL,
      0,
      NULL);
      TiUnload(DriverObject);
      return Status;
  }

  /* Start the periodic timer with an initial and periodic
     relative expiration time of IP_TIMEOUT milliseconds */
  DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000;
  KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc);

  TI_DbgPrint(MAX_TRACE, ("[TCPIP, DriverEntry] Finished\n"));


  return STATUS_SUCCESS;
}