Beispiel #1
0
NTSTATUS
NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,
            IN PUNICODE_STRING RegistryPath)
{
    PDEVICE_OBJECT DeviceObject;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\Null");
    NTSTATUS Status;
    PFAST_IO_DISPATCH FastIoDispatch;
    PAGED_CODE();

    /* Page the driver */
    MmPageEntireDriver(DriverEntry);

    /* Create null device */
    Status = IoCreateDevice(DriverObject,
                            0,
                            &DeviceName,
                            FILE_DEVICE_NULL,
                            0,
                            FALSE,
                            &DeviceObject);
    if (!NT_SUCCESS(Status)) return Status;

    /* Register driver routines */
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = NullDispatch;
    DriverObject->MajorFunction[IRP_MJ_CREATE] = NullDispatch;
    DriverObject->MajorFunction[IRP_MJ_WRITE] = NullDispatch;
    DriverObject->MajorFunction[IRP_MJ_READ] = NullDispatch;
    DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = NullDispatch;
    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = NullDispatch;

    /* Allocate the fast I/O dispatch table */
    FastIoDispatch = ExAllocatePool(NonPagedPool, sizeof(FAST_IO_DISPATCH));
    if (!FastIoDispatch)
    {
        /* Failed, cleanup */
        IoDeleteDevice(DeviceObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Initialize it */
    RtlZeroMemory(FastIoDispatch, sizeof(FAST_IO_DISPATCH));
    FastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);

    /* Setup our pointers */
    FastIoDispatch->FastIoRead = NullRead;
    FastIoDispatch->FastIoWrite = NullWrite;
    DriverObject->FastIoDispatch = FastIoDispatch;

    /* Return success */
    return STATUS_SUCCESS;
}
Beispiel #2
0
//
// This is where it all starts...
//
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject,
	    IN PUNICODE_STRING RegistryPath)
{
  NTSTATUS status;
  PDEVICE_OBJECT device_object;
  UNICODE_STRING ctl_device_name;
  UNICODE_STRING sym_link;

  AWEAllocDriverObject = DriverObject;

  MmPageEntireDriver((PVOID)(ULONG_PTR)DriverEntry);

  // Create the control device.
  RtlInitUnicodeString(&ctl_device_name, AWEALLOC_DEVICE_NAME);

  status = IoCreateDevice(DriverObject,
			  0,
			  &ctl_device_name,
			  FILE_DEVICE_NULL,
			  0,
			  FALSE,
			  &device_object);

  if (!NT_SUCCESS(status))
    return status;

  device_object->Flags |= DO_DIRECT_IO;

  RtlInitUnicodeString(&sym_link, AWEALLOC_SYMLINK_NAME);
  status = IoCreateUnprotectedSymbolicLink(&sym_link, &ctl_device_name);
  if (!NT_SUCCESS(status))
    {
      IoDeleteDevice(device_object);
      return status;
    }

  DriverObject->MajorFunction[IRP_MJ_CREATE] = AWEAllocCreate;
  DriverObject->MajorFunction[IRP_MJ_CLOSE] = AWEAllocClose;
  DriverObject->MajorFunction[IRP_MJ_READ] = AWEAllocReadWrite;
  DriverObject->MajorFunction[IRP_MJ_WRITE] = AWEAllocReadWrite;
  DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = AWEAllocFlushBuffers;
  DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
    AWEAllocQueryInformation;
  DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = AWEAllocSetInformation;

  DriverObject->DriverUnload = AWEAllocUnload;

  KdPrint(("AWEAlloc: Initialization done. Leaving DriverEntry().\n"));

  return STATUS_SUCCESS;
}
Beispiel #3
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;
}
Beispiel #4
0
VOID
MsDereferenceVcb (
    IN PVCB Vcb
    )

/*++

Routine Description:

    This routine dereferences a VCB block.  If the reference count
    reaches zero, the block is freed.

Arguments:

    Vcb - Supplies the VCB to dereference

Return Value:

    None

--*/

{
    PAGED_CODE();
    DebugTrace(+1, DEBUG_TRACE_REFCOUNT, "MsDereferenceVcb, Vcb = %08lx\n", (ULONG)Vcb);

    //
    // Acquire the lock that protects the reference count.
    //

    MsAcquireGlobalLock();

    if ( --(Vcb->Header.ReferenceCount) == 0 ) {

        //
        // This was the last reference to the VCB.  Delete it now
        //

        DebugTrace(0,
                   DEBUG_TRACE_REFCOUNT,
                   "Reference count = %lx\n",
                   Vcb->Header.ReferenceCount );

        MsReleaseGlobalLock();
        MsDeleteVcb( Vcb );

    } else {

        DebugTrace(0,
                   DEBUG_TRACE_REFCOUNT,
                   "Reference count = %lx\n",
                   Vcb->Header.ReferenceCount );

        if (Vcb->Header.ReferenceCount == 1) {
            //
            // Set driver to be paged completely out
            //
            MmPageEntireDriver(MsDereferenceVcb);
        }

        MsReleaseGlobalLock();

    }

    DebugTrace(-1, DEBUG_TRACE_REFCOUNT, "MsDereferenceVcb -> VOID\n", 0);
    return;
}
Beispiel #5
0
NTSTATUS
DriverEntry( DRIVER_OBJECT *DriverObject, UNICODE_STRING *RegistryPath )
{
    VOID *processEventHandle = 0;
    VOID *threadEventHandle = 0;
    VOID *imageEventHandle = 0;
    NTSTATUS status;
    UNICODE_STRING DeviceNameU;
    UNICODE_STRING DeviceLinkU;
    UNICODE_STRING processEventName;
    UNICODE_STRING threadEventName;
    UNICODE_STRING imageEventName;

    DbgPrint("[PUSH] => (DriverEntry)\n");

    MmPageEntireDriver((PVOID)(ULONG_PTR) DriverEntry);

    MaxDevices = IMDISK_DEFAULT_MAX_DEVICES;

    lstMapInfo.Next=NULL;

    PushDriverObject = DriverObject;

    RtlInitUnicodeString(&DeviceNameU,  PUSH_DEVICE_BASE_NAME);
    RtlInitUnicodeString(&DeviceLinkU,  PUSH_SYMLINK_NAME);
    RtlInitUnicodeString(&processEventName, L"\\BaseNamedObjects\\" PUSH_PROCESS_EVENT_NAME);
    RtlInitUnicodeString(&threadEventName,  L"\\BaseNamedObjects\\" PUSH_THREAD_EVENT_NAME);
    RtlInitUnicodeString(&imageEventName,   L"\\BaseNamedObjects\\" PUSH_IMAGE_EVENT_NAME);

    //Create a device object
    status = IoCreateDevice(DriverObject,               //IN: Driver Object
                              sizeof(DEVICE_EXTENSION), //IN: Device Extension Size
                              &DeviceNameU,             //IN: Device Name
                              FILE_DEVICE_PUSH,         //IN: Device Type
                              0,                        //IN: Device Characteristics
                              FALSE,                    //IN: Exclusive
                              &g_DeviceObject);     //OUT:Created Device Object

    // The control device gets a device_number of -1 to make it easily
    // distinguishable from the actual created devices.
    //((PDEVICE_EXTENSION) g_DeviceObject->DeviceExtension)->device_number =
    //(ULONG) -1;

    //Dispatch functions
    DriverObject->MajorFunction[IRP_MJ_CREATE]          = DispatchCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]           = DispatchClose;
    DriverObject->MajorFunction[IRP_MJ_READ]            = ImDiskReadWrite;
    DriverObject->MajorFunction[IRP_MJ_WRITE]           = ImDiskReadWrite;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = DispatchIoCtl;
    DriverObject->MajorFunction[IRP_MJ_PNP]             = ImDiskDispatchPnP;

    DriverObject->DriverUnload = PushUnload;

    //Create a symbolic link
    IoCreateSymbolicLink(&DeviceLinkU, &DeviceNameU);

    ProcessEvent = IoCreateNotificationEvent(&processEventName, &processEventHandle);
    ThreadEvent = IoCreateNotificationEvent(&threadEventName, &threadEventHandle);
    ImageEvent = IoCreateNotificationEvent(&imageEventName, &imageEventHandle);

    KeClearEvent(ProcessEvent);
    KeClearEvent(ThreadEvent);
    KeClearEvent(ImageEvent);

    DbgPrint("[PUSH] <= (DriverEntry)\n");

    return status;
}
Beispiel #6
0
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING Registry)
{
	int				Index = 0;
	PDEVICE_OBJECT	DeviceObject;

	MmPageEntireDriver(DriverEntry);

	DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsRecFsControl;
	DriverObject->MajorFunction[IRP_MJ_CREATE] = FsRecCreate;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = 
	DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FsRecCleanupClose;
	
	DriverObject->DriverUnload = FsRecUnload;

	FsRecLoadSync = (PKEVENT)ExAllocatePoolWithTag(sizeof(KEVENT),NonPagedPool,POOL_TAG);
	if(FsRecLoadSync == NULL)
	{
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	KeInitializeEvent(FsRecLoadSync,SynchronizationEvent,TRUE);
	
	if(NT_SUCCESS(FsRecCreateAndRegisterDO(DriverObject,NULL,NULL,
		L"\\Cdfs",
		L"\\FileSystem\\CdfsRecognizer",
		CDFS_TYPE,
		FILE_DEVICE_CD_ROM_FILE_SYSTEM,
		TRUE)))
	{
		Index ++;
	}

	if (NT_SUCCESS( FsRecCreateAndRegisterDO(
		DriverObject,
		NULL,
		&DeviceObject,
		L"\\UdfsCdRom",
		L"\\FileSystem\\UdfsCdRomRecognizer",
		UDFS_TYPE,
		FILE_DEVICE_CD_ROM_FILE_SYSTEM,
		FALSE) ))
	{
		Index++;
	}

	if (NT_SUCCESS( FsRecCreateAndRegisterDO(
		DriverObject,
		NULL,
		&DeviceObject,
		L"\\Fat",
		L"\\FileSystem\\FatDiskRecognizer",
		FATCD_TYPE,
		FILE_DEVICE_DISK_FILE_SYSTEM,
		FALSE) ))
	{
		Index++;
	}
	
    if (NT_SUCCESS( FsRecCreateAndRegisterDO(
		DriverObject,
		DeviceObject,
		NULL,
		L"\\FatCdrom",
		L"\\FileSystem\\FatCdRomRecognizer",
		FATCD_TYPE,
		FILE_DEVICE_CD_ROM_FILE_SYSTEM,
		FALSE) ))
	{
		Index++;
	}
	
    if (NT_SUCCESS( FsRecCreateAndRegisterDO(DriverObject, NULL, NULL,
			L"\\Ntfs",
			L"\\FileSystem\\NtfsRecognizer", 
			NTFS_TYPE, 
			FILE_DEVICE_DISK_FILE_SYSTEM, 
			FALSE) ))
	{
		++Index;
	}

    if (NT_SUCCESS( FsRecCreateAndRegisterDO(DriverObject, 
		NULL, 
		NULL,
		L"\\ExFat", 
		L"\\FileSystem\\ExFatRecognizer",
		EXFAT_TYPE, 
		FILE_DEVICE_DISK_FILE_SYSTEM, 
		FALSE) ))
	{
		++Index;
	}

	return Index != 0 ? STATUS_SUCCESS : STATUS_IMAGE_ALREADY_LOADED;

}
Beispiel #7
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This is the initialization routine for the mailslot file system
    device driver.  This routine creates the device object for the mailslot
    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 = STATUS_SUCCESS;
    UNICODE_STRING nameString;
    PDEVICE_OBJECT deviceObject;
    PMSFS_DEVICE_OBJECT msfsDeviceObject;

    BOOLEAN vcbInitialized;

    PAGED_CODE();

    //
    // Initialize MSFS global data.
    //

    MsInitializeData();

    //
    // Set driver to be completely paged out.
    //
    MmPageEntireDriver(DriverEntry);

    //
    // Create the MSFS device object.
    //

    RtlInitUnicodeString( &nameString, L"\\Device\\Mailslot" );
    status = IoCreateDevice( DriverObject,
                             sizeof(MSFS_DEVICE_OBJECT)-sizeof(DEVICE_OBJECT),
                             &nameString,
                             FILE_DEVICE_MAILSLOT,
                             0,
                             FALSE,
                             &deviceObject );

    if (!NT_SUCCESS( status )) {
        return status;

    }

    //
    //  Now because we use the irp stack for storing a data entry we need
    //  to bump up the stack size in the device object we just created.
    //

    deviceObject->StackSize += 1;

    //
    // Note that because of the way data copying is done, we set neither
    // the Direct I/O or Buffered I/O bit in DeviceObject->Flags.  If
    // data 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)MsFsdCreate;
    DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] =
        (PDRIVER_DISPATCH)MsFsdCreateMailslot;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] =
        (PDRIVER_DISPATCH)MsFsdClose;
    DriverObject->MajorFunction[IRP_MJ_READ] =
        (PDRIVER_DISPATCH)MsFsdRead;
    DriverObject->MajorFunction[IRP_MJ_WRITE] =
        (PDRIVER_DISPATCH)MsFsdWrite;
    DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
        (PDRIVER_DISPATCH)MsFsdQueryInformation;
    DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
        (PDRIVER_DISPATCH)MsFsdSetInformation;
    DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
        (PDRIVER_DISPATCH)MsFsdQueryVolumeInformation;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] =
        (PDRIVER_DISPATCH)MsFsdCleanup;
    DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
        (PDRIVER_DISPATCH)MsFsdDirectoryControl;
    DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
        (PDRIVER_DISPATCH)MsFsdFsControl;
    DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] =
        (PDRIVER_DISPATCH)MsFsdQuerySecurityInfo;
    DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] =
        (PDRIVER_DISPATCH)MsFsdSetSecurityInfo;

#ifdef _PNP_POWER_
    //
    // Mailslots should probably have a SetPower handler to ensure
    // that the driver is not powered down while a guarateed
    // mailslot delivery is in progress.   For now, we'll just
    // ignore this and let the machine set power.
    //

    deviceObject->DeviceObjectExtension->PowerControlNeeded = FALSE;
#endif

    vcbInitialized = FALSE;

    try {

        //
        // Initialize stuff
        //

        msfsDeviceObject = (PMSFS_DEVICE_OBJECT)deviceObject;

        //
        // Now initialize the Vcb, and create the root dcb
        //

        MsInitializeVcb( &msfsDeviceObject->Vcb );
        (VOID)MsCreateRootDcb( &msfsDeviceObject->Vcb );
        vcbInitialized = TRUE;

    } finally {

        if (AbnormalTermination() ) {

            //
            // We encountered some unrecoverable error while initializing.
            // Cleanup as necessary.
            //

            if (vcbInitialized) {
                MsDeleteVcb( &msfsDeviceObject->Vcb );
            }
        }
    }

    //
    // Return to the caller.
    //

    return( status );
}
Beispiel #8
0
/*
 * This definition doesn't work
 */
INIT_FUNCTION
NTSTATUS
APIENTRY
DriverEntry(
    IN    PDRIVER_OBJECT    DriverObject,
    IN    PUNICODE_STRING    RegistryPath)
{
    NTSTATUS Status;
    BOOLEAN Result;
    WIN32_CALLOUTS_FPNS CalloutData = {0};
    PVOID GlobalUserHeapBase = NULL;

    /*
     * Register user mode call interface
     * (system service table index = 1)
     */
    Result = KeAddSystemServiceTable(Win32kSSDT,
                                     NULL,
                                     Win32kNumberOfSysCalls,
                                     Win32kSSPT,
                                     1);
    if (Result == FALSE)
    {
        DPRINT1("Adding system services failed!\n");
        return STATUS_UNSUCCESSFUL;
    }

    hModuleWin = MmPageEntireDriver(DriverEntry);
    DPRINT("Win32k hInstance 0x%p!\n",hModuleWin);

    /* Register Object Manager Callbacks */
    CalloutData.ProcessCallout = Win32kProcessCallback;
    CalloutData.ThreadCallout = Win32kThreadCallback;
    CalloutData.WindowStationParseProcedure = IntWinStaObjectParse;
    CalloutData.WindowStationDeleteProcedure = IntWinStaObjectDelete;
    CalloutData.WindowStationOkToCloseProcedure = IntWinstaOkToClose;
    CalloutData.DesktopOkToCloseProcedure = IntDesktopOkToClose;
    CalloutData.DesktopDeleteProcedure = IntDesktopObjectDelete;
    CalloutData.DesktopCloseProcedure = IntDesktopObjectClose;
    CalloutData.DesktopOpenProcedure = IntDesktopObjectOpen;
    CalloutData.BatchFlushRoutine = NtGdiFlushUserBatch;

    /* Register our per-process and per-thread structures. */
    PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData);

    /* Register service hook callbacks */
#if DBG
    KdSystemDebugControl('CsoR', DbgPreServiceHook, ID_Win32PreServiceHook, 0, 0, 0, 0);
    KdSystemDebugControl('CsoR', DbgPostServiceHook, ID_Win32PostServiceHook, 0, 0, 0, 0);
#endif

    /* Create the global USER heap */
    GlobalUserHeap = UserCreateHeap(&GlobalUserHeapSection,
                                    &GlobalUserHeapBase,
                                    1 * 1024 * 1024); /* FIXME: 1 MB for now... */
    if (GlobalUserHeap == NULL)
    {
        DPRINT1("Failed to initialize the global heap!\n");
        return STATUS_UNSUCCESSFUL;
    }

    /* Allocate global server info structure */
    gpsi = UserHeapAlloc(sizeof(SERVERINFO));
    if (!gpsi)
    {
        DPRINT1("Failed allocate server info structure!\n");
        return STATUS_UNSUCCESSFUL;
    }

    RtlZeroMemory(gpsi, sizeof(SERVERINFO));
    DPRINT("Global Server Data -> %p\n", gpsi);

    NT_ROF(InitGdiHandleTable());
    NT_ROF(InitPaletteImpl());

    /* Create stock objects, ie. precreated objects commonly
       used by win32 applications */
    CreateStockObjects();
    CreateSysColorObjects();

    NT_ROF(InitBrushImpl());
    NT_ROF(InitPDEVImpl());
    NT_ROF(InitLDEVImpl());
    NT_ROF(InitDeviceImpl());
    NT_ROF(InitDcImpl());
    NT_ROF(InitUserImpl());
    NT_ROF(InitWindowStationImpl());
    NT_ROF(InitDesktopImpl());
    NT_ROF(InitInputImpl());
    NT_ROF(InitKeyboardImpl());
    NT_ROF(MsqInitializeImpl());
    NT_ROF(InitTimerImpl());
    NT_ROF(InitDCEImpl());

    /* Initialize FreeType library */
    if (!InitFontSupport())
    {
        DPRINT1("Unable to initialize font support\n");
        return Status;
    }

    gusLanguageID = UserGetLanguageID();

    return STATUS_SUCCESS;
}
Beispiel #9
0
NTSTATUS
DriverEntry (
    IN PDRIVER_OBJECT DriverObject,
    IN PUNICODE_STRING RegistryPath
    )

/*++

Routine Description:

    This is the initialization routine for the AFD device driver.

Arguments:

    DriverObject - Pointer to driver object created by the system.

Return Value:

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

--*/

{
    NTSTATUS status;
    UNICODE_STRING deviceName;
    CLONG i;
    BOOLEAN success;

    PAGED_CODE( );

    //
    // Create the device object.  (IoCreateDevice zeroes the memory
    // occupied by the object.)
    //
    // !!! Apply an ACL to the device object.
    //

    RtlInitUnicodeString( &deviceName, AFD_DEVICE_NAME );

    status = IoCreateDevice(
                 DriverObject,                   // DriverObject
                 0,                              // DeviceExtension
                 &deviceName,                    // DeviceName
                 FILE_DEVICE_NAMED_PIPE,         // DeviceType
                 0,                              // DeviceCharacteristics
                 FALSE,                          // Exclusive
                 &AfdDeviceObject                // DeviceObject
                 );


    if ( !NT_SUCCESS(status) ) {
        KdPrint(( "AFD DriverEntry: unable to create device object: %X\n", status ));
        return status;
    }

    //
    // Create the security descriptor used for raw socket access checks.
    //
    status = AfdCreateRawSecurityDescriptor();

    if (!NT_SUCCESS(status)) {
        IoDeleteDevice(AfdDeviceObject);
        return status;
    }

    AfdDeviceObject->Flags |= DO_DIRECT_IO;

    //
    // Initialize the driver object for this file system driver.
    //

    for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
        DriverObject->MajorFunction[i] = AfdDispatch;
    }

    DriverObject->FastIoDispatch = &AfdFastIoDispatch;
    DriverObject->DriverUnload = NULL;

    //
    // Initialize global data.
    //

    success = AfdInitializeData( );
    if ( !success ) {
        IoDeleteDevice(AfdDeviceObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Initialize group ID manager.
    //

    success = AfdInitializeGroup();
    if ( !success ) {
        IoDeleteDevice(AfdDeviceObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Read registry information.
    //

    AfdReadRegistry( );

#if DBG
    if( AfdEnableUnload ) {
        KdPrint(( "AFD: DriverUnload enabled\n" ));
        DriverObject->DriverUnload = AfdUnload;
    }
#endif

    //
    // Initialize the lookaside lists.
    //

    AfdLookasideLists = AFD_ALLOCATE_POOL(
                            NonPagedPool,
                            sizeof(*AfdLookasideLists),
                            AFD_LOOKASIDE_LISTS_POOL_TAG
                            );

    if( AfdLookasideLists == NULL ) {
        IoDeleteDevice(AfdDeviceObject);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    // Initialize the work queue item lookaside list.
    //

    ExInitializeNPagedLookasideList(
        &AfdLookasideLists->WorkQueueList,
#if DBG
        AfdAllocateWorkItemPool,
        AfdFreeWorkItemPool,
#else
        NULL,
        NULL,
#endif
        NonPagedPoolMustSucceed,
        sizeof( AFD_WORK_ITEM ),
        AFD_WORK_ITEM_POOL_TAG,
        12
        );

    //
    // Initialize the AFD buffer lookaside lists.  These must be
    // initialized *after* the registry data has been read.
    //

    ExInitializeNPagedLookasideList(
        &AfdLookasideLists->LargeBufferList,
        AfdAllocateBuffer,
#if DBG
        AfdFreeBufferPool,
#else
        NULL,
#endif
        0,
        AfdLargeBufferSize,
        AFD_DATA_BUFFER_POOL_TAG,
        (USHORT)AfdLargeBufferListDepth
        );

    ExInitializeNPagedLookasideList(
        &AfdLookasideLists->MediumBufferList,
        AfdAllocateBuffer,
#if DBG
        AfdFreeBufferPool,
#else
        NULL,
#endif
        0,
        AfdMediumBufferSize,
        AFD_DATA_BUFFER_POOL_TAG,
        (USHORT)AfdMediumBufferListDepth
        );

    ExInitializeNPagedLookasideList(
        &AfdLookasideLists->SmallBufferList,
        AfdAllocateBuffer,
#if DBG
        AfdFreeBufferPool,
#else
        NULL,
#endif
        0,
        AfdSmallBufferSize,
        AFD_DATA_BUFFER_POOL_TAG,
        (USHORT)AfdSmallBufferListDepth
        );

    //
    // Initialize our device object.
    //

    AfdDeviceObject->StackSize = AfdIrpStackSize;

    //
    // Remember a pointer to the system process.  We'll use this pointer
    // for KeAttachProcess() calls so that we can open handles in the
    // context of the system process.
    //

    AfdSystemProcess = (PKPROCESS)IoGetCurrentProcess();

    //
    // Tell MM that it can page all of AFD it is desires.  We will reset
    // to normal paging of AFD code as soon as an AFD endpoint is
    // opened.
    //

    AfdLoaded = FALSE;

    MmPageEntireDriver( DriverEntry );

    return (status);

} // DriverEntry