Example #1
0
NTSTATUS CreateDevice (
		IN PDRIVER_OBJECT	pDriverObject) 
{
	NTSTATUS status;
	PDEVICE_OBJECT pDevObj;
	PDEVICE_EXTENSION pDevExt;
	
	UNICODE_STRING devName;
	RtlInitUnicodeString(&devName,DEVICE_NAME);
	
	UNICODE_STRING symLinkName;
	RtlInitUnicodeString(&symLinkName,DOS_NAME);
	
	
	status = IoCreateDevice( pDriverObject,
						sizeof(DEVICE_EXTENSION),
						&(UNICODE_STRING)devName,
						FILE_DEVICE_UNKNOWN,
						FILE_DEVICE_SECURE_OPEN, FALSE,
						&pDevObj );
	if (!NT_SUCCESS(status))
	{
		KdPrint( ("create device is error!\n") );
		return status;
	}

	IoRegisterShutdownNotification(pDevObj);

	pDevObj->Flags |= DO_BUFFERED_IO;
	pDevObj->Flags &= (~DO_DEVICE_INITIALIZING);//wdm used

	pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
	pDevExt->pDevice = pDevObj;
	pDevExt->ustrDeviceName = devName;//
	pDevExt->ustrSymLinkName = symLinkName;//

	status = IoCreateSymbolicLink( &symLinkName,&devName );
	if (!NT_SUCCESS(status)) 
	{
		IoDeleteDevice( pDevObj );
		KdPrint( ("create symbolicLink is error!\n") );
		return status;
	}

	//fanzhenxing add
	InitBlackCache();
	InitFilterCache();

	return STATUS_SUCCESS;
}
Example #2
0
EXTERN_C static NTSTATUS LogpInitializeBufferInfo(
    _In_ const wchar_t *LogFilePath, _In_opt_ PDEVICE_OBJECT DeviceObject,
    _Inout_ LogBufferInfo *Info) {
  NT_ASSERT(LogFilePath);
  NT_ASSERT(Info);

  KeInitializeSpinLock(&Info->SpinLock);

  auto status = ExInitializeResourceLite(&Info->Resource);
  if (!NT_SUCCESS(status)) {
    return status;
  }
  Info->ResourceInitialized = true;

  if (DeviceObject) {
    // We can handle IRP_MJ_SHUTDOWN in order to flush buffered log entries.
    status = IoRegisterShutdownNotification(DeviceObject);
    if (!NT_SUCCESS(status)) {
      LogpFinalizeBufferInfo(DeviceObject, Info);
      return status;
    }
  }

  // Allocate two log buffers on NonPagedPool.
  Info->LogBuffer1 = reinterpret_cast<char *>(ExAllocatePoolWithTag(
      NonPagedPoolNx, LOGP_BUFFER_SIZE, LOGP_POOL_TAG_NAME));
  if (!Info->LogBuffer1) {
    LogpFinalizeBufferInfo(DeviceObject, Info);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  Info->LogBuffer2 = reinterpret_cast<char *>(ExAllocatePoolWithTag(
      NonPagedPoolNx, LOGP_BUFFER_SIZE, LOGP_POOL_TAG_NAME));
  if (!Info->LogBuffer2) {
    LogpFinalizeBufferInfo(DeviceObject, Info);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  // Initialize these buffers
  RtlFillMemory(Info->LogBuffer1, LOGP_BUFFER_SIZE, 0xff);  // for debug
  Info->LogBuffer1[0] = '\0';
  Info->LogBuffer1[LOGP_BUFFER_SIZE - 1] = '\0';  // at the end

  RtlFillMemory(Info->LogBuffer2, LOGP_BUFFER_SIZE, 0xff);  // for debug
  Info->LogBuffer2[0] = '\0';
  Info->LogBuffer2[LOGP_BUFFER_SIZE - 1] = '\0';  // at the end

  // Buffer should be used is LogBuffer1, and location should be written logs
  // is the head of the buffer.
  Info->LogBufferHead = Info->LogBuffer1;
  Info->LogBufferTail = Info->LogBuffer1;

  // Initialize a log file
  UNICODE_STRING logFilePathU = {};
  RtlInitUnicodeString(&logFilePathU, LogFilePath);

  OBJECT_ATTRIBUTES oa = {};
  InitializeObjectAttributes(&oa, &logFilePathU,
                             OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, nullptr,
                             nullptr);

  IO_STATUS_BLOCK ioStatus = {};
  status = ZwCreateFile(
      &Info->LogFileHandle, FILE_APPEND_DATA | SYNCHRONIZE, &oa, &ioStatus,
      nullptr, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN_IF,
      FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, nullptr, 0);
  if (!NT_SUCCESS(status)) {
    LogpFinalizeBufferInfo(DeviceObject, Info);
    return status;
  }

  // Initialize a log buffer flush thread.
  Info->BufferFlushThreadShouldBeAlive = true;
  status = PsCreateSystemThread(&Info->BufferFlushThreadHandle, GENERIC_ALL,
                                nullptr, nullptr, nullptr,
                                LogpBufferFlushThreadRoutine, Info);
  if (!NT_SUCCESS(status)) {
    LogpFinalizeBufferInfo(DeviceObject, Info);
    return status;
  }

  return status;
}
Example #3
0
File: init.c Project: GYGit/reactos
NTSTATUS
NTAPI
DriverEntry(IN PDRIVER_OBJECT DriverObject,
            IN PUNICODE_STRING RegistryPath)
{
    HEADLESS_RSP_QUERY_INFO HeadlessInformation;
    ULONG InfoSize = sizeof(HeadlessInformation);
    NTSTATUS Status;
    UNICODE_STRING DriverName;
    PDEVICE_OBJECT DeviceObject;
    PSAC_DEVICE_EXTENSION DeviceExtension;
    PAGED_CODE();
    SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering.\n");

    /* Check if EMS is enabled in the kernel */
    HeadlessDispatch(HeadlessCmdQueryInformation,
                     NULL,
                     0,
                     &HeadlessInformation,
                     &InfoSize);
    if ((HeadlessInformation.Serial.TerminalType != HeadlessUndefinedPortType) &&
        ((HeadlessInformation.Serial.TerminalType != HeadlessSerialPort) ||
         (HeadlessInformation.Serial.TerminalAttached)))
    {
        /* It is, so create the device */
        RtlInitUnicodeString(&DriverName, L"\\Device\\SAC");
        Status = IoCreateDevice(DriverObject,
                                sizeof(SAC_DEVICE_EXTENSION),
                                &DriverName,
                                FILE_DEVICE_UNKNOWN,
                                FILE_DEVICE_SECURE_OPEN,
                                FALSE,
                                &DeviceObject);
        if (NT_SUCCESS(Status))
        {
            /* Setup the device extension */
            DeviceExtension = DeviceObject->DeviceExtension;
            DeviceExtension->Initialized = FALSE;

            /* Initialize the driver object */
            RtlFillMemoryUlong(DriverObject->MajorFunction,
                               RTL_NUMBER_OF(DriverObject->MajorFunction),
                               (ULONG_PTR)Dispatch);
            DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchDeviceControl;
            DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = DispatchShutdownControl;
            DriverObject->FastIoDispatch = NULL;
            DriverObject->DriverUnload = UnloadHandler;

            /* Initialize driver data */
            if (InitializeGlobalData(RegistryPath, DriverObject))
            {
                /* Initialize device data */
                if (InitializeDeviceData(DeviceObject))
                {
                    /* We're all good, register a shutdown notification */
                    IoRegisterShutdownNotification(DeviceObject);
                    return Status;
                }
            }

            /* One of the initializations failed, bail out */
            Status = STATUS_INSUFFICIENT_RESOURCES;
        }
        else
        {
            /* Print a debug statement if enabled */
            SAC_DBG(SAC_DBG_INIT, "unable to create device object: %X\n", Status);
        }

        /* Free any data we may have allocated and exit with failure */
        FreeGlobalData();
        SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with status 0x%x\n", Status);
        return Status;
    }

    /* EMS is not enabled */
    return STATUS_PORT_DISCONNECTED;
}
Example #4
0
NTSTATUS
SoundCardInstanceInit(
    IN   PWSTR RegistryPathName,
    IN   PVOID Context
)
{
    /*
    ** Instance data
    */

    PSOUND_CARD_INSTANCE CardInstance;

    //
    // Return code from last function called
    //

    NTSTATUS        Status;

    //
    // Configuration data :
    //

    SB_CONFIG_DATA  ConfigData;

    //
    // Where we keep all general driver information
    // We avoid using static data because :
    //     1. Accesses are slower with 32-bit offsets
    //     2. We support more than one card instance
    //

    PGLOBAL_DEVICE_INFO pGDI;

    //
    // The number of devices we actually create
    //

    int         NumberOfDevicesCreated;

    //
    //  The context is the global device info pointer from the previous
    //  instance
    //

    CardInstance = Context;


   /********************************************************************
    *
    * Allocate our global info
    *
    ********************************************************************/

    pGDI =
        (PGLOBAL_DEVICE_INFO)ExAllocatePool(
                                  NonPagedPool,
                                  sizeof(GLOBAL_DEVICE_INFO));

    if (pGDI == NULL) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    dprintf4((" DriverEntry():  GlobalInfo    : %08lXH", pGDI));

    RtlZeroMemory(pGDI, sizeof(GLOBAL_DEVICE_INFO));
    pGDI->Key              = GDI_KEY;
    pGDI->Hw.Key           = HARDWARE_KEY;
    pGDI->RegistryPathName = RegistryPathName;

    pGDI->Usage            = 0xFF;                    // Free
    pGDI->DriverObject     = CardInstance->pDriverObject;

    //
    // Mutual exclusion :
    //
    //    Everything is synchronized on the DeviceMutex (except for
    //    some stuff inside the wave device) except
    //
    //    Midi external output which takes too long and so is synchronized
    //    separately but grabs the DeviceMutex every time it actually
    //    writes anything and
    //
    //    Synth output where the hardware is separate but callbacks to the
    //    mixer must grab the DeviceMutex.
    //

    KeInitializeMutex(&pGDI->DeviceMutex,
                       2                     // High level
                       );

    KeInitializeMutex(&pGDI->MidiMutex,
                       1                     // Low level
                       );

    KeInitializeMutex(&pGDI->Hw.DSPMutex,
                       3                     // Highest level
                       );

   /********************************************************************
    *
    *  Add ourselves to the ring of cards
    *
    ********************************************************************/

    if (CardInstance->PrevGDI == NULL) {
        pGDI->Next = pGDI;
    } else {
        PGLOBAL_DEVICE_INFO pNext;
        pNext = CardInstance->PrevGDI->Next;
        CardInstance->PrevGDI->Next = pGDI;
        pGDI->Next = pNext;
    }
    CardInstance->PrevGDI = pGDI;


   /********************************************************************
    *
    *  See if we can find our bus.  We run on both ISA and EISA
    *  We ASSUME that if there's an ISA bus we're on that
    *
    ********************************************************************/

    Status = SoundGetBusNumber(Isa, &pGDI->BusNumber);

    if (!NT_SUCCESS(Status)) {
        //
        // Cound not find an ISA bus so try EISA
        //
        Status = SoundGetBusNumber(Eisa, &pGDI->BusNumber);

        if (!NT_SUCCESS(Status)) {
            Status = SoundGetBusNumber(MicroChannel, &pGDI->BusNumber);

            if (!NT_SUCCESS(Status)) {
                dprintf1(("driver does not work on non-Isa/Eisa/Mca"));
                return Status;
            }
            pGDI->BusType = MicroChannel;

        } else {
            pGDI->BusType = Eisa;
        }
    } else {
        pGDI->BusType = Isa;
    }

    //
    // Set configuration to default in case we don't get all the
    // values back from the registry.
    //
    // Also set default volume for all devices
    //

    ConfigData.Port            = SOUND_DEF_PORT;
    ConfigData.InterruptNumber = SOUND_DEF_INT;
    ConfigData.DmaChannel      = SOUND_DEF_DMACHANNEL;
    ConfigData.DmaChannel16    = SOUND_DEF_DMACHANNEL16;
    ConfigData.DmaBufferSize   = DEFAULT_DMA_BUFFERSIZE;
    ConfigData.MPU401Port      = SOUND_DEF_MPU401_PORT;
    ConfigData.LoadType        = SOUND_LOADTYPE_NORMAL;
    ConfigData.MixerSettingsFound = FALSE;

    //
    // Get the system configuration information for this driver.
    //
    //
    //     Port, Interrupt, DMA channel, DMA 16-bit channel DMA buffer size
    //

    {
        RTL_QUERY_REGISTRY_TABLE    Table[2];

        RtlZeroMemory(Table, sizeof(Table));

        Table[0].QueryRoutine = SoundReadConfiguration;

        Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE,
                                         pGDI->RegistryPathName,
                                         Table,
                                         &ConfigData,
                                         NULL );

        if (!NT_SUCCESS(Status)) {
            dprintf1(("ERROR: DriverEntry(): RtlQueryRegistryValues() Failed with Status = %XH", Status));
            return Status;
        }           // End IF (!NT_SUCCESS(Status))
    }           // End Query Resistry Values

    //
    // Save additional Config data
    //
    pGDI->InterruptNumber = ConfigData.InterruptNumber;
    pGDI->DmaChannel      = ConfigData.DmaChannel;
    pGDI->DmaChannel16    = ConfigData.DmaChannel16;

    //
    // Verify the DMA Buffer Size
    //
    if ( ConfigData.DmaBufferSize < MIN_DMA_BUFFERSIZE ) {
        ConfigData.DmaBufferSize = MIN_DMA_BUFFERSIZE;
        dprintf1((" DriverEntry(): Adjusting the DMA Buffer size, size in Registry was too small"));
    }

    //
    // print out some info about the configuration
    //

    dprintf2((" DriverEntry():  Base I/O Port     = %XH", ConfigData.Port));
    dprintf2((" DriverEntry():  Interrupt         = %u",  ConfigData.InterruptNumber));
    dprintf2((" DriverEntry():  DMA Channel       = %u",  ConfigData.DmaChannel));
    dprintf2((" DriverEntry():  DMA Channel (16 bit) = %u",  ConfigData.DmaChannel16));
    dprintf2((" DriverEntry():  DMA Buffer Size   = %XH", ConfigData.DmaBufferSize));
    dprintf2((" DriverEntry():  MPU 401 port      = %XH", ConfigData.MPU401Port));

    /*
    **  Create our wave devices to ease reporting problems
    */

    Status = SBCreateDevice(pGDI, WaveInDevice);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    Status = SBCreateDevice(pGDI, WaveOutDevice);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    /*
    **  Say we want to be called at shutdown time
    */

    Status = IoRegisterShutdownNotification(pGDI->DeviceObject[WaveInDevice]);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    pGDI->ShutdownRegistered = TRUE;


    /*
    **  Check the configuration and acquire the resources
    */

    Status = SoundInitHardwareConfig(pGDI, &ConfigData);

    if (!NT_SUCCESS(Status)) {
        dprintf1(("ERROR: DriverEntry(): SoundInitHardwareConfig() Failed with Status = %XH",
                                 Status));
        return Status;
    }

    /*
    **  Initialize generic device environments - first get the
    **  hardware routines in place.
    **  We do this here after we've found out what hardware we've got
    */

    HwInitialize(pGDI);

    SoundInitMidiIn(&pGDI->MidiInfo,
                    &pGDI->Hw);


    /*
    **  Register most of our resources.  Some may be registered on
    **  the wave output device :
    **     16-bit dma channel
    **
    **  We wipe out the registration of the MPU401 port when we do this
    **  but this is OK.
    */

    {
        ULONG PortToReport;
        PortToReport = ConfigData.Port + MIX_ADDR_PORT;

        Status = SoundReportResourceUsage(
                     pGDI->DeviceObject[WaveInDevice],  // As good as any device to own
                                                   // it
                     pGDI->BusType,
                     pGDI->BusNumber,
                     &ConfigData.InterruptNumber,
                     INTERRUPT_MODE,
                     (BOOLEAN)(SB16(&pGDI->Hw) ? TRUE : FALSE),  // Sharable for SB16
                     &ConfigData.DmaChannel,
                     &PortToReport,
                     NUMBER_OF_SOUND_PORTS - MIX_ADDR_PORT);
    }

    if (!NT_SUCCESS(Status)) {
        dprintf1(("Error - failed to claim resources - code %8X", Status));
        pGDI->LoadStatus = SOUND_CONFIG_ERROR;
        return Status;
    }
    /*
    **  Now we know what device we've got we can create the appropriate
    **  devices
    */

    /*
    **  Thuderboard has no external midi and we're going to
    **  drive the SB16 in MPU401 mode if we can
    */

    if (!pGDI->Hw.ThunderBoard) {
        //
        //  Don't create the MPU401 device if it is disabled
        //
        if (!SB16(&pGDI->Hw) ||
            (ULONG)-1 != ConfigData.MPU401Port)
        {
            Status = SBCreateDevice(pGDI, MidiOutDevice);
            if (!NT_SUCCESS(Status)) {
                return Status;
            }
            Status = SBCreateDevice(pGDI, MidiInDevice);
            if (!NT_SUCCESS(Status)) {
                return Status;
            }
        }
    }

    /*
    **  Create volume control stuff for those devices which have it
    */

    if (SBPRO(&pGDI->Hw) || SB16(&pGDI->Hw)
#ifdef SB_CD
        ||
        pGDI->Hw.SBCDBase != NULL
#endif // SB_CD
        ) {
        Status = SBCreateDevice(pGDI, LineInDevice);
        if (!NT_SUCCESS(Status)) {
            return Status;
        }
        Status = SBCreateDevice(pGDI, CDInternal);
        if (!NT_SUCCESS(Status)) {
            return Status;
        }
        Status = SBCreateDevice(pGDI, MixerDevice);
        if (!NT_SUCCESS(Status)) {
            return Status;
        }
    } else {
        /*  Volume setting not supported for our wave device */
        ((PLOCAL_DEVICE_INFO)pGDI->DeviceObject[WaveOutDevice]->DeviceExtension)->CreationFlags |=
            SOUND_CREATION_NO_VOLUME;
    }

    /*
    ** Init the WaveInfo structure
    */

    SoundInitializeWaveInfo(&pGDI->WaveInfo,
                            (UCHAR)(SB1(&pGDI->Hw) ?
                                        SoundReprogramOnInterruptDMA :
                                        SoundAutoInitDMA),
                            SoundQueryFormat,
                            &pGDI->Hw);

    if (ConfigData.SynthType == SOUND_SYNTH_TYPE_NONE) {
        /*
        **  This will happen if the user selected a basic config without
        **  a synthesizer.
        */
        dprintf2(("No synth!"));
    } else {
        Status = SynthInit(CardInstance->pDriverObject,
                           pGDI->RegistryPathName,
                           &pGDI->Synth,
                           SB16(&pGDI->Hw) ||
                           SBPRO(&pGDI->Hw) && INPORT(&pGDI->Hw, 0) == 0 ?
                               ConfigData.Port : SYNTH_PORT,
                           FALSE,                         // Interrupt not enabled
                           pGDI->BusType,
                           pGDI->BusNumber,
                           NULL,
                           SOUND_MIXER_INVALID_CONTROL_ID,// Set volume later
                           TRUE,                          // Allow multiple
                           SoundMidiOutGetSynthCaps
                           );
        
        if (!NT_SUCCESS(Status)) {
        
            /*
            **  OK - we can get along without a synth
            */
        
            dprintf2(("No synth!"));
        } else {
            if (!pGDI->Synth.IsOpl3) {
                dprintf2(("Synth is Adlib"));
            } else {
        
                /*
                **  Bad aliasing in early sound blasters means we can
                **  guess wrong.
                */
        
                if (!(SB16(&pGDI->Hw) || SBPRO(&pGDI->Hw) && INPORT(&pGDI->Hw, 0) == 0)) {
                    pGDI->Synth.IsOpl3 = FALSE;
                }
                dprintf2(("Synth is Opl3"));
            }
        }
    }

    /*
    **  Set the mixer up.
    **
    **  Note that the mixer info depends on what hardware is present
    **  so this must be called after we have checked out the hardware.
    */

    if (pGDI->DeviceObject[MixerDevice]) {
        Status = SoundMixerInit(pGDI->DeviceObject[MixerDevice]->DeviceExtension,
                                &ConfigData.MixerSettings,
                                ConfigData.MixerSettingsFound);

        if (!NT_SUCCESS(Status)) {
            return Status;
        }
    }

    /*
    ** Save new settings
    */

    Status = SoundSaveConfig(pGDI->RegistryPathName,
                             ConfigData.Port,
                             ConfigData.DmaChannel,
                             ConfigData.DmaChannel16,
                             ConfigData.InterruptNumber,
                             ConfigData.MPU401Port,
                             (BOOLEAN)(pGDI->Synth.DeviceObject != NULL),
                             pGDI->Synth.IsOpl3,
                             pGDI->WaveInfo.DMABuf.BufferSize);

    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    /*
    **  Finally test the PRO interrupt
    */

    if (SBPRO(&pGDI->Hw)) {
        BOOLEAN Ok;

        SoundEnter(pGDI->DeviceObject[WaveOutDevice]->DeviceExtension,
                   TRUE);
        Ok = 0 == SoundTestWaveDevice(pGDI->DeviceObject[WaveOutDevice]);
        SoundEnter(pGDI->DeviceObject[WaveOutDevice]->DeviceExtension,
                   FALSE);
        if (!Ok) {
            pGDI->LoadStatus = SOUND_CONFIG_BADDMA;
            return STATUS_DEVICE_CONFIGURATION_ERROR;
        }
    }

    /*
    ** Exit OK Message
    */

    pGDI->LoadStatus = SOUND_CONFIG_OK;

    return STATUS_SUCCESS;

}
Example #5
0
///////////////////////////////////////////////////////////////////////////////////////////////////
//  DriverEntry 
//      Installable driver initialization entry point.
//      This entry point is called directly by the I/O system.
//
//  Arguments:
//      IN  DriverObject
//              pointer to the driver object
//
//      IN  RegistryPath
//              pointer to a unicode string representing the path,
//              to driver-specific key in the registry.
//
//  Return Value:
//      Status
//
NTSTATUS DriverEntry(
    IN  PDRIVER_OBJECT  DriverObject,
    IN  PUNICODE_STRING RegistryPath
    )
{
    NTSTATUS                            status;
    PDEVICE_OBJECT                      deviceObject;
    PTESTDRV_DEVICE_EXTENSION   deviceExtension;
    UNICODE_STRING                      ntName;
    UNICODE_STRING                      win32Name;

    testdrvDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"++");
    testdrvDebugPrint(DBG_INIT, DBG_INFO, "Compiled at %s on %s", __TIME__, __DATE__);

#ifdef DBG
//    DbgBreakPoint();
#endif

#ifdef TESTDRV_WMI_TRACE 
    WPP_INIT_TRACING(DriverObject, RegistryPath);
#endif

    RtlZeroMemory(&g_Data, sizeof(TESTDRV_DATA));

    // save registry path
    g_Data.RegistryPath.Length = RegistryPath->Length;
    g_Data.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL);
    g_Data.RegistryPath.Buffer = (PWCHAR)ExAllocatePoolWithTag(
                                            PagedPool,
                                            g_Data.RegistryPath.MaximumLength,
                                            TESTDRV_POOL_TAG
                                            );

    if (g_Data.RegistryPath.Buffer == NULL)
    {
        status = STATUS_INSUFFICIENT_RESOURCES;

        testdrvDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__": Failed to allocate memory for RegistryPath");

        return status;
    }

    RtlCopyUnicodeString(&g_Data.RegistryPath, RegistryPath);

    // setup our dispatch function table in the driver object
    DriverObject->MajorFunction[IRP_MJ_CREATE] = testdrvCreateDispatch;
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = testdrvCloseDispatch;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = testdrvDeviceIoControlDispatch;
    DriverObject->MajorFunction[IRP_MJ_READ] = testdrvReadDispatch;
    DriverObject->MajorFunction[IRP_MJ_WRITE] = testdrvWriteDispatch;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = testdrvCleanupDispatch;
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = testdrvShutdownDispatch;
    DriverObject->DriverUnload = testdrvUnload;

    // initialize device name
    RtlInitUnicodeString(&ntName, L"\\Device\\testdrvDevice");

	ExInitializeFastMutex(&qemu_output_lock);

	// Create our function device object.
    status = IoCreateDevice(
                DriverObject,
                sizeof (TESTDRV_DEVICE_EXTENSION),
                &ntName,
                FILE_DEVICE_UNKNOWN,
                0,
                FALSE,
                &deviceObject
                );

    if (!NT_SUCCESS (status)) 
    {
        ExFreePool(g_Data.RegistryPath.Buffer);
        g_Data.RegistryPath.Buffer = NULL;

        testdrvDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__"--. STATUS %x", status);

        return status;
    }

    // Initialize the device extension.
    deviceExtension = (PTESTDRV_DEVICE_EXTENSION)deviceObject->DeviceExtension;

    // Zero the memory
    RtlZeroMemory(deviceExtension, sizeof(TESTDRV_DEVICE_EXTENSION));

    // save our device object pointer
    deviceExtension->DeviceObject = deviceObject;

    // This flag sets the buffering method for reads and writes
    // to METHOD_DIRECT.  IOCTLs are handled by IO control codes
    // independent of the value of this flag.
    deviceObject->Flags |= DO_DIRECT_IO;

    RtlInitUnicodeString(&win32Name, L"\\??\\testdrvDevice");
    status = IoCreateSymbolicLink(&win32Name, &ntName);
    if (!NT_SUCCESS(status))
    {
        IoDeleteDevice(deviceObject);

        ExFreePool(g_Data.RegistryPath.Buffer);
        g_Data.RegistryPath.Buffer = NULL;

        return status;
    }

    IoRegisterShutdownNotification(deviceObject);

	InitializeListHead(&ModuleListHead);


	g_WorkItem = IoAllocateWorkItem(deviceObject);
	if(!g_WorkItem)
		return STATUS_INSUFFICIENT_RESOURCES;

	IoQueueWorkItem(g_WorkItem, GetSysModInfo, DelayedWorkQueue, g_WorkItem);
	//UpdateSysModuleList();


	PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine);
	PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, FALSE);


    testdrvDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"--. STATUS %x", status);

    return status;
}
CPGPdiskInterface::CPGPdiskInterface(CPGPdiskDriver *pDriver)
	: KDevice(L"PGPdisk", FILE_DEVICE_UNKNOWN, L"PGPdisk", 0, DO_DIRECT_IO)

{
	NTSTATUS status;

	pgpAssertAddrValid(pDriver, CPGPdiskDriver);

	mSecondsInactive = 0;

	mPGPdiskDriver = pDriver;

	mTimerStarted	= FALSE;
	mUnmountAllMode	= FALSE;

	mAutoUnmount	= kDefaultAutoUnmount;
	mUnmountTimeout	= kDefaultUnmountTimeout;

	mKeyboardFilter = NULL;
	mMouseFilter = NULL;

	mCreatedKeyboardFilter	= FALSE;
	mCreatedMouseFilter		= FALSE;

	if (!NT_SUCCESS(m_ConstructorStatus))
	{
		mInitErr = DualErr(kPGDMinorError_DeviceConstructFailed, 
			m_ConstructorStatus);
	}

	if (mInitErr.IsntError())
	{
		mInitErr = mUserMemManager.mInitErr;
	}

	// Setup our system hooks.
	if (mInitErr.IsntError())
	{
		mInitErr = SetupSystemHooks();
	}

	// Start our one-second timer.
	if (mInitErr.IsntError())
	{
		status = IoInitializeTimer(m_pDeviceObject, EverySecondCallback, 
			NULL);

		if (!NT_SUCCESS(status))
		{
			mInitErr = DualErr(kPGDMinorError_IoInitializeTimerFailed, 
				status);
		}
	}

	if (mInitErr.IsntError())
	{
		IoRegisterShutdownNotification(m_pDeviceObject);

		IoStartTimer(m_pDeviceObject);
		mTimerStarted = TRUE;
	}
}
Example #7
0
//
//  Typically called by a driver's AddDevice function, which is set when
//  calling PcInitializeAdapterDriver. This performs some common driver
//  operations, such as creating a device extension.
//
//  The StartDevice parameter is a driver-supplied function which gets
//  called in response to IRP_MJ_PNP / IRP_MN_START_DEVICE.
//
NTSTATUS
NTAPI
PcAddAdapterDevice(
    IN  PDRIVER_OBJECT DriverObject,
    IN  PDEVICE_OBJECT PhysicalDeviceObject,
    IN  PCPFNSTARTDEVICE StartDevice,
    IN  ULONG MaxObjects,
    IN  ULONG DeviceExtensionSize)
{
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    PDEVICE_OBJECT fdo;
    PDEVICE_OBJECT PrevDeviceObject;
    PPCLASS_DEVICE_EXTENSION portcls_ext = NULL;

    DPRINT("PcAddAdapterDevice called\n");
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!DriverObject || !PhysicalDeviceObject || !StartDevice)
    {
        return STATUS_INVALID_PARAMETER;
    }

    // check if the DeviceExtensionSize is provided
    if ( DeviceExtensionSize < PORT_CLASS_DEVICE_EXTENSION_SIZE )
    {
        // driver does not need a device extension 
        if ( DeviceExtensionSize != 0 )
        {
            // DeviceExtensionSize must be zero
            return STATUS_INVALID_PARAMETER;
        }
        // set size to our extension size
        DeviceExtensionSize = PORT_CLASS_DEVICE_EXTENSION_SIZE;
    }

    // create the device
    status = IoCreateDevice(DriverObject,
                            DeviceExtensionSize,
                            NULL,
                            FILE_DEVICE_KS,
                            FILE_AUTOGENERATED_DEVICE_NAME | FILE_DEVICE_SECURE_OPEN,
                            FALSE,
                            &fdo);

    if (!NT_SUCCESS(status))
    {
        DPRINT("IoCreateDevice() failed with status 0x%08lx\n", status);
        return status;
    }

    // Obtain the new device extension
    portcls_ext = (PPCLASS_DEVICE_EXTENSION) fdo->DeviceExtension;
    // initialize the device extension
    RtlZeroMemory(portcls_ext, DeviceExtensionSize);
    // allocate create item
    portcls_ext->CreateItems = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, MaxObjects * sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS);

    if (!portcls_ext->CreateItems)
    {
        // not enough resources
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    // store max subdevice count
    portcls_ext->MaxSubDevices = MaxObjects;
    // store the physical device object
    portcls_ext->PhysicalDeviceObject = PhysicalDeviceObject;
    // set up the start device function
    portcls_ext->StartDevice = StartDevice;
    // initialize timer lock
    KeInitializeSpinLock(&portcls_ext->TimerListLock);
    // initialize timer list
    InitializeListHead(&portcls_ext->TimerList);
    // initialize io timer
    IoInitializeTimer(fdo, PcIoTimerRoutine, NULL);
    // start the io timer
    IoStartTimer(fdo);

    // set io flags
    fdo->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
    // clear initializing flag
    fdo->Flags &= ~ DO_DEVICE_INITIALIZING;

    // allocate the device header
    status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems);
    // did we succeed
    if (!NT_SUCCESS(status))
    {
        goto cleanup;
    }

    // attach device to device stack
    PrevDeviceObject = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
    // did we succeed
    if (PrevDeviceObject)
    {
        // store the device object in the device header
        //KsSetDevicePnpBaseObject(portcls_ext->KsDeviceHeader, fdo, PrevDeviceObject);
        portcls_ext->PrevDeviceObject = PrevDeviceObject;
    }
    else
    {
        // return error code
        status = STATUS_UNSUCCESSFUL;
        goto cleanup;
    }

    // register shutdown notification
    IoRegisterShutdownNotification(PhysicalDeviceObject);

    return status;

cleanup:

    if (portcls_ext->KsDeviceHeader)
    {
        // free the device header
        KsFreeDeviceHeader(portcls_ext->KsDeviceHeader);
    }

    if (portcls_ext->CreateItems)
    {
        // free previously allocated create items
        FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
    }

    // delete created fdo
    IoDeleteDevice(fdo);


    return status;
}
Example #8
0
NTSTATUS
DriverEntry( PDRIVER_OBJECT DriverObject,
             PUNICODE_STRING RegistryPath)
{

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSDeviceExt    *pDeviceExt;
    ULONG ulTimeIncrement = 0;
    UNICODE_STRING uniSymLinkName;
    UNICODE_STRING uniDeviceName;
    ULONG ulIndex = 0;
    ULONG ulValue = 0;
    UNICODE_STRING uniValueName;
    BOOLEAN bExit = FALSE;
    UNICODE_STRING uniRoutine;
    RTL_OSVERSIONINFOW sysVersion;
    UNICODE_STRING uniPsSetCreateProcessNotifyRoutineEx;
    PsSetCreateProcessNotifyRoutineEx_t pPsSetCreateProcessNotifyRoutineEx = NULL;

    __try
    {

        DbgPrint("AFSRedirFs DriverEntry Initialization build %s:%s\n", __DATE__, __TIME__);

        //
        // Initialize some local variables for easier processing
        //

        uniSymLinkName.Buffer = NULL;

        AFSDumpFileLocation.Length = 0;
        AFSDumpFileLocation.MaximumLength = 0;
        AFSDumpFileLocation.Buffer = NULL;

        AFSDumpFileName.Length = 0;
        AFSDumpFileName.Buffer = NULL;
        AFSDumpFileName.MaximumLength = 0;

        ExInitializeResourceLite( &AFSDbgLogLock);

        //
        // Initialize the server name
        //

        AFSReadServerName();

        RtlZeroMemory( &sysVersion,
                       sizeof( RTL_OSVERSIONINFOW));

        sysVersion.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW);

        RtlGetVersion( &sysVersion);

        RtlInitUnicodeString( &uniRoutine,
                              L"ZwSetInformationToken");

        AFSSetInformationToken = (PAFSSetInformationToken)MmGetSystemRoutineAddress( &uniRoutine);

        if( AFSSetInformationToken == NULL)
        {
#ifndef AMD64
            AFSSrvcTableEntry *pServiceTable = NULL;

            pServiceTable = (AFSSrvcTableEntry *)KeServiceDescriptorTable;

            //
            // Only perform this lookup for Windows XP.
            //

            if( pServiceTable != NULL &&
                sysVersion.dwMajorVersion == 5 &&
                sysVersion.dwMinorVersion == 1)
            {
                AFSSetInformationToken = (PAFSSetInformationToken)pServiceTable->ServiceTable[ 0xE6];
            }
#endif
        }

        //
        // And the global root share name
        //

        RtlInitUnicodeString( &AFSGlobalRootName,
                              AFS_GLOBAL_ROOT_SHARE_NAME);

        RtlZeroMemory( &AFSNoPAGAuthGroup,
                       sizeof( GUID));

        //
        // Our backdoor to not let the driver load
        //

        if( bExit)
        {
            try_return( ntStatus);
        }

        //
        // Perform some initialization
        //

        AFSDriverObject = DriverObject;

        ntStatus = AFSReadRegistry( RegistryPath);

        if( !NT_SUCCESS( ntStatus))
        {

            DbgPrint("AFS DriverEntry: Failed to read registry Status %08lX\n", ntStatus);

            ntStatus = STATUS_SUCCESS;
        }

        //
        // Initialize the debug log and dump file interface
        //

        AFSInitializeDbgLog();

        AFSInitializeDumpFile();

#if DBG

        if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_BREAK_ON_ENTRY))
        {

            DbgPrint("AFSRedirFs DriverEntry - Break on entry\n");

            AFSBreakPoint();

            if ( bExit)
            {
                //
                // Just as above
                //
                try_return( ntStatus = STATUS_UNSUCCESSFUL);
            }
        }
#endif

        if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN) &&
            !BooleanFlagOn( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN))
        {

            AFSPrint("AFS DriverEntry: Failed to shutdown clean, exiting\n");

            try_return( ntStatus = STATUS_UNSUCCESSFUL);
        }

        //
        // Setup the registry string
        //

        AFSRegistryPath.MaximumLength = RegistryPath->MaximumLength;
        AFSRegistryPath.Length        = RegistryPath->Length;

        AFSRegistryPath.Buffer = (PWSTR)ExAllocatePoolWithTag( PagedPool,
                                                               AFSRegistryPath.Length,
                                                               AFS_GENERIC_MEMORY_18_TAG);

        if( AFSRegistryPath.Buffer == NULL)
        {

            DbgPrint("AFSRedirFs DriverEntry Failed to allocate registry path buffer\n");

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        RtlCopyMemory( AFSRegistryPath.Buffer,
                       RegistryPath->Buffer,
                       RegistryPath->Length);

        if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN))
        {

            //
            // Update the shutdown flag
            //

            ulValue = (ULONG)-1;

            RtlInitUnicodeString( &uniValueName,
                                  AFS_REG_SHUTDOWN_STATUS);

            AFSUpdateRegistryParameter( &uniValueName,
                                        REG_DWORD,
                                        &ulValue,
                                        sizeof( ULONG));
        }

        RtlInitUnicodeString( &uniDeviceName,
                              AFS_CONTROL_DEVICE_NAME);

        ntStatus = IoCreateDeviceSecure( DriverObject,
                                         sizeof( AFSDeviceExt),
                                         &uniDeviceName,
                                         FILE_DEVICE_NETWORK_FILE_SYSTEM,
                                         0,
                                         FALSE,
                                         &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX,
                                         (LPCGUID)&GUID_SD_AFS_REDIRECTOR_CONTROL_OBJECT,
                                         &AFSDeviceObject);

        if( !NT_SUCCESS( ntStatus))
        {

            DbgPrint("AFS DriverEntry - Failed to allocate device control object Status %08lX\n", ntStatus);

            try_return( ntStatus);
        }

        //
        // Setup the device extension
        //

        pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;

        InitializeListHead( &pDeviceExt->Specific.Control.DirNotifyList);
        FsRtlNotifyInitializeSync( &pDeviceExt->Specific.Control.NotifySync);

        //
        // Now initialize the control device
        //

        ntStatus = AFSInitializeControlDevice();

        if( !NT_SUCCESS( ntStatus))
        {

            try_return( ntStatus);
        }

        //
        // Allocate our symbolic link for service communication
        //

        RtlInitUnicodeString( &uniSymLinkName,
                              AFS_SYMLINK_NAME);

        ntStatus = IoCreateSymbolicLink( &uniSymLinkName,
                                         &uniDeviceName);

        if( !NT_SUCCESS( ntStatus))
        {

            DbgPrint("AFS DriverEntry - Failed to create symbolic link Status %08lX\n", ntStatus);

            //
            // OK, no one can communicate with us so fail
            //

            try_return( ntStatus);
        }

        //
        // Fill in the dispatch table
        //

        for( ulIndex = 0; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++)
        {

            DriverObject->MajorFunction[ ulIndex] = AFSDefaultDispatch;
        }

        DriverObject->MajorFunction[IRP_MJ_CREATE] =                    AFSCreate;
        DriverObject->MajorFunction[IRP_MJ_CLOSE] =                     AFSClose;
        DriverObject->MajorFunction[IRP_MJ_READ] =                      AFSRead;
        DriverObject->MajorFunction[IRP_MJ_WRITE] =                     AFSWrite;
        DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =         AFSQueryFileInfo;
        DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =           AFSSetFileInfo;
        DriverObject->MajorFunction[IRP_MJ_QUERY_EA] =                  AFSQueryEA;
        DriverObject->MajorFunction[IRP_MJ_SET_EA] =                    AFSSetEA;
        DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] =             AFSFlushBuffers;
        DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =  AFSQueryVolumeInfo;
        DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =    AFSSetVolumeInfo;
        DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =         AFSDirControl;
        DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =       AFSFSControl;
        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =            AFSDevControl;
        DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =   AFSInternalDevControl;
        DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =                  AFSShutdown;
        DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] =              AFSLockControl;
        DriverObject->MajorFunction[IRP_MJ_CLEANUP] =                   AFSCleanup;
        DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] =            AFSQuerySecurity;
        DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] =              AFSSetSecurity;
        DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =            AFSSystemControl;
        //DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] =               AFSQueryQuota;
        //DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] =                 AFSSetQuota;

        //
        // Since we are not a true FSD then we are not controlling a device and hence these will not be needed
        //

#ifdef FSD_NOT_USED

        DriverObject->MajorFunction[IRP_MJ_POWER] =                     AFSPower;
        DriverObject->MajorFunction[IRP_MJ_PNP] =                       AFSPnP;

#endif

        //
        // Fast IO Dispatch table
        //

        DriverObject->FastIoDispatch = &AFSFastIoDispatch;

        RtlZeroMemory( &AFSFastIoDispatch,
                       sizeof( AFSFastIoDispatch));

        //
        // Again, since we are not a registered FSD many of these are not going to be called. They are here
        // for completeness.
        //

        AFSFastIoDispatch.SizeOfFastIoDispatch         = sizeof(FAST_IO_DISPATCH);
        AFSFastIoDispatch.FastIoCheckIfPossible        = AFSFastIoCheckIfPossible;  //  CheckForFastIo
        AFSFastIoDispatch.FastIoRead                   = AFSFastIoRead;             //  Read
        AFSFastIoDispatch.FastIoWrite                  = AFSFastIoWrite;            //  Write
        AFSFastIoDispatch.FastIoQueryBasicInfo         = AFSFastIoQueryBasicInfo;     //  QueryBasicInfo
        AFSFastIoDispatch.FastIoQueryStandardInfo      = AFSFastIoQueryStandardInfo;       //  QueryStandardInfo
        AFSFastIoDispatch.FastIoLock                   = AFSFastIoLock;               //  Lock
        AFSFastIoDispatch.FastIoUnlockSingle           = AFSFastIoUnlockSingle;       //  UnlockSingle
        AFSFastIoDispatch.FastIoUnlockAll              = AFSFastIoUnlockAll;          //  UnlockAll
        AFSFastIoDispatch.FastIoUnlockAllByKey         = AFSFastIoUnlockAllByKey;     //  UnlockAllByKey
        AFSFastIoDispatch.FastIoQueryNetworkOpenInfo   = AFSFastIoQueryNetworkOpenInfo;
        AFSFastIoDispatch.AcquireForCcFlush            = AFSFastIoAcquireForCCFlush;
        AFSFastIoDispatch.ReleaseForCcFlush            = AFSFastIoReleaseForCCFlush;
        AFSFastIoDispatch.FastIoDeviceControl          = AFSFastIoDevCtrl;
        AFSFastIoDispatch.AcquireFileForNtCreateSection = AFSFastIoAcquireFile;
        AFSFastIoDispatch.ReleaseFileForNtCreateSection = AFSFastIoReleaseFile;
        AFSFastIoDispatch.FastIoDetachDevice           = AFSFastIoDetachDevice;
        //AFSFastIoDispatch.AcquireForModWrite           = AFSFastIoAcquireForModWrite;
        //AFSFastIoDispatch.ReleaseForModWrite           = AFSFastIoReleaseForModWrite;
        AFSFastIoDispatch.MdlRead                      = AFSFastIoMdlRead;
        AFSFastIoDispatch.MdlReadComplete              = AFSFastIoMdlReadComplete;
        AFSFastIoDispatch.PrepareMdlWrite              = AFSFastIoPrepareMdlWrite;
        AFSFastIoDispatch.MdlWriteComplete             = AFSFastIoMdlWriteComplete;
        AFSFastIoDispatch.FastIoReadCompressed         = AFSFastIoReadCompressed;
        AFSFastIoDispatch.FastIoWriteCompressed        = AFSFastIoWriteCompressed;
        AFSFastIoDispatch.MdlReadCompleteCompressed    = AFSFastIoMdlReadCompleteCompressed;
        AFSFastIoDispatch.MdlWriteCompleteCompressed   = AFSFastIoMdlWriteCompleteCompressed;
        AFSFastIoDispatch.FastIoQueryOpen              = AFSFastIoQueryOpen;

        //
        //  Cache manager callback routines.
        //

        AFSCacheManagerCallbacks.AcquireForLazyWrite  = &AFSAcquireFcbForLazyWrite;
        AFSCacheManagerCallbacks.ReleaseFromLazyWrite = &AFSReleaseFcbFromLazyWrite;
        AFSCacheManagerCallbacks.AcquireForReadAhead  = &AFSAcquireFcbForReadAhead;
        AFSCacheManagerCallbacks.ReleaseFromReadAhead = &AFSReleaseFcbFromReadAhead;

        //
        //  System process.
        //

        AFSSysProcess = PsGetCurrentProcessId();

        //
        // Register for shutdown notification
        //

        IoRegisterShutdownNotification( AFSDeviceObject);

        //
        // Initialize the system process cb
        //

        AFSInitializeProcessCB( 0,
                                (ULONGLONG)AFSSysProcess);

        //
        // Initialize the redirector device
        //

        ntStatus = AFSInitRDRDevice();

        if( !NT_SUCCESS( ntStatus))
        {

            DbgPrint("AFS DriverEntry Failed to initialize redirector device Status %08lX\n");

            try_return( ntStatus);
        }

        //
        // Initialize some server name based strings
        //

        AFSInitServerStrings();

        //
        // Register the call back for process creation and tear down.
        // On Vista SP1 and above, PsSetCreateProcessNotifyRoutineEx
        // will be used.  This function returns STATUS_ACCESS_DENIED
        // if there is a signing error.  In that case, the AFSProcessNotifyEx
        // routine has not been registered and we can fallback to the
        // Windows 2000 interface and AFSProcessNotify.
        //

        RtlInitUnicodeString( &uniPsSetCreateProcessNotifyRoutineEx,
                              L"PsSetCreateProcessNotifyRoutineEx");

        pPsSetCreateProcessNotifyRoutineEx = (PsSetCreateProcessNotifyRoutineEx_t)MmGetSystemRoutineAddress(&uniPsSetCreateProcessNotifyRoutineEx);

        ntStatus = STATUS_ACCESS_DENIED;

        if ( pPsSetCreateProcessNotifyRoutineEx)
        {

            ntStatus = pPsSetCreateProcessNotifyRoutineEx( AFSProcessNotifyEx,
                                                           FALSE);
        }

        if ( ntStatus == STATUS_ACCESS_DENIED)
        {

            ntStatus = PsSetCreateProcessNotifyRoutine( AFSProcessNotify,
                                                        FALSE);
        }

        ntStatus = STATUS_SUCCESS;

try_exit:

        if( !NT_SUCCESS( ntStatus))
        {

            DbgPrint("AFSRedirFs DriverEntry failed to initialize %08lX\n", ntStatus);

            if( AFSRegistryPath.Buffer != NULL)
            {

                ExFreePool( AFSRegistryPath.Buffer);
            }

            if( uniSymLinkName.Buffer != NULL)
            {

                IoDeleteSymbolicLink( &uniSymLinkName);
            }

            if( AFSDeviceObject != NULL)
            {

                AFSRemoveControlDevice();

                FsRtlNotifyUninitializeSync( &pDeviceExt->Specific.Control.NotifySync);

                IoUnregisterShutdownNotification( AFSDeviceObject);

                IoDeleteDevice( AFSDeviceObject);
            }

            AFSTearDownDbgLog();

            ExDeleteResourceLite( &AFSDbgLogLock);
        }
    }
    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
    {

        AFSDbgLogMsg( 0,
                      0,
                      "EXCEPTION - AFSRedirFs DriverEntry\n");

        AFSDumpTraceFilesFnc();
    }

    return ntStatus;
}