Esempio n. 1
0
NTSTATUS DriverEntry (IN PDRIVER_OBJECT DriverObject,
                      IN PUNICODE_STRING RegistryPath)
{
  UNICODE_STRING DeviceName, DeviceLink;
  NTSTATUS NtStatus;
  PDEVICE_OBJECT DeviceObject = NULL;
  PDEVICE_EXTENSION extension;

  WinDbgPrint("WinPMEM - " PMEM_VERSION " - Physical memory acquisition\n");

#if PMEM_WRITE_ENABLED == 1
  WinDbgPrint("WinPMEM write support available!");
#endif

  WinDbgPrint("Copyright (c) 2014, Michael Cohen <*****@*****.**>\n");

  // Initialize import tables:
  if(PmemGetProcAddresses() != STATUS_SUCCESS) {
    WinDbgPrint("Failed to initialize import table. Aborting.\n");
    goto error;
  };

  RtlInitUnicodeString (&DeviceName, L"\\Device\\" PMEM_DEVICE_NAME);

  // We create our secure device.
  // http://msdn.microsoft.com/en-us/library/aa490540.aspx
  NtStatus = IoCreateDeviceSecure(DriverObject,
                                  sizeof(DEVICE_EXTENSION),
                                  &DeviceName,
                                  FILE_DEVICE_UNKNOWN,
                                  FILE_DEVICE_SECURE_OPEN,
                                  FALSE,
                                  &SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
                                  &GUID_DEVCLASS_PMEM_DUMPER,
                                  &DeviceObject);

  if (!NT_SUCCESS(NtStatus)) {
    WinDbgPrint ("IoCreateDevice failed. => %08X\n", NtStatus);
    return NtStatus;
  }

  DriverObject->MajorFunction[IRP_MJ_CREATE] = wddCreate;
  DriverObject->MajorFunction[IRP_MJ_CLOSE] = wddClose;
  DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = wddDispatchDeviceControl;
  DriverObject->MajorFunction[IRP_MJ_READ] = PmemRead;

#if PMEM_WRITE_ENABLED == 1
  {
    // Make sure that the drivers with write support are clearly marked as such.
    static char TAG[] = "Write Supported";
  }

  // Support writing.
  DriverObject->MajorFunction[IRP_MJ_WRITE] = PmemWrite;
#endif
  DriverObject->DriverUnload = IoUnload;

  // Use buffered IO - a bit slower but simpler to implement, and more
  // efficient for small reads.
  SetFlag(DeviceObject->Flags, DO_BUFFERED_IO );
  ClearFlag(DeviceObject->Flags, DO_DIRECT_IO );
  ClearFlag(DeviceObject->Flags, DO_DEVICE_INITIALIZING);

  RtlInitUnicodeString (&DeviceLink, L"\\DosDevices\\" PMEM_DEVICE_NAME);

  NtStatus = IoCreateSymbolicLink (&DeviceLink, &DeviceName);

  if (!NT_SUCCESS(NtStatus)) {
    WinDbgPrint ("IoCreateSymbolicLink failed. => %08X\n", NtStatus);
    IoDeleteDevice (DeviceObject);
  }

  // Populate globals in kernel context.
  CR3.QuadPart = __readcr3();

  // Initialize the device extension with safe defaults.
  extension = DeviceObject->DeviceExtension;
  extension->mode = ACQUISITION_MODE_PHYSICAL_MEMORY;
  extension->MemoryHandle = 0;

#if _WIN64
  // Disable pte mapping for 32 bit systems.
  extension->pte_mmapper = pte_mmap_windows_new();
  extension->pte_mmapper->loglevel = PTE_ERR;
#else
  extension->pte_mmapper = NULL;
#endif

  WinDbgPrint("Driver intialization completed.");
  return NtStatus;

 error:
  return STATUS_UNSUCCESSFUL;
}
Esempio n. 2
0
NTSTATUS
DriverEntry (
    _In_ PDRIVER_OBJECT  DriverObject,
    _In_ PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    This routine is called by the operating system to initialize the driver. 
    It allocates a device object, initializes the supported Io callbacks, and
    creates a symlink to make the device accessible to Win32.

    It gets the registry callback version and stores it in the global
    variables g_MajorVersion and g_MinorVersion. It also calls
    CreateKTMResourceManager to create a resource manager that is used in 
    the transaction samples.

Arguments:
    
    DriverObject - Supplies the system control object for this test driver.

    RegistryPath - The string location of the driver's corresponding services 
                   key in the registry.

Return value:

    Success or appropriate failure code.

--*/
{
    NTSTATUS Status;
    UNICODE_STRING NtDeviceName;
    UNICODE_STRING DosDevicesLinkName;
    UNICODE_STRING DeviceSDDLString;

    UNREFERENCED_PARAMETER(RegistryPath);

    DbgPrintEx(DPFLTR_IHVDRIVER_ID, 
               DPFLTR_ERROR_LEVEL,
               "RegFltr: DriverEntry()\n");

    DbgPrintEx(DPFLTR_IHVDRIVER_ID, 
               DPFLTR_ERROR_LEVEL,
               "RegFltr: Use ed nt!Kd_IHVDRIVER_Mask 8 to enable more detailed printouts\n");

    //
    // Create our device object.
    //

    RtlInitUnicodeString(&NtDeviceName, NT_DEVICE_NAME);
    RtlInitUnicodeString(&DeviceSDDLString, DEVICE_SDDL);

    // TODO(H): 看下这个函数
    Status = IoCreateDeviceSecure(
                            DriverObject,                 // pointer to driver object
                            0,                            // device extension size
                            &NtDeviceName,                // device name
                            FILE_DEVICE_UNKNOWN,          // device type
                            0,                            // device characteristics
                            TRUE,                         // not exclusive
                            &DeviceSDDLString,            // SDDL string specifying access
                            NULL,                         // device class guid
                            &g_DeviceObj);                // returned device object pointer

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

    //
    // Set dispatch routines.
    //

    DriverObject->MajorFunction[IRP_MJ_CREATE]         = DeviceCreate;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DeviceClose;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP]        = DeviceCleanup;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceControl;
    DriverObject->DriverUnload                         = DeviceUnload;

    //
    // Create a link in the Win32 namespace.
    //
    
    RtlInitUnicodeString(&DosDevicesLinkName, DOS_DEVICES_LINK_NAME);

    Status = IoCreateSymbolicLink(&DosDevicesLinkName, &NtDeviceName);

    if (!NT_SUCCESS(Status)) {
        IoDeleteDevice(DriverObject->DeviceObject);
        return Status;
    }

    //
    // Get callback version.
    //

    // TODO(H): 
    CmGetCallbackVersion(&g_MajorVersion, &g_MinorVersion);
    InfoPrint("Callback version %u.%u", g_MajorVersion, g_MinorVersion);

    //
    // Some variations depend on knowing if the OS is win8 or above
    //
    
    DetectOSVersion();

    //
    // Set up KTM resource manager and pass in RMCallback as our
    // callback routine.
    //

    Status = CreateKTMResourceManager(RMCallback, NULL);

    if (NT_SUCCESS(Status)) {
        g_RMCreated = TRUE;
    }

    //
    // Initialize the callback context list
    //

    InitializeListHead(&g_CallbackCtxListHead);
    ExInitializeFastMutex(&g_CallbackCtxListLock);
    g_NumCallbackCtxListEntries = 0;

    return STATUS_SUCCESS;
    
}
Esempio n. 3
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath )
{
    PDEVICE_OBJECT DeviceObject = NULL;
    NTSTATUS       Status = STATUS_SUCCESS;
    UNICODE_STRING DeviceName;
    UNICODE_STRING DosDeviceName;  

    //
    // Initialize a unicode string for the drivers object name.
    //
    RtlInitUnicodeString( &DeviceName, DEVICE_NAME_U );

    //
    // Attempt to create a named device object
    // 

//
// SDDL_DEVOBJ_SYS_ALL_ADM_ALL allows the kernel, system, and admin complete
// control over the device. No other users may access the device
//
/*
DECLARE_CONST_UNICODE_STRING(
    SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
    L"D:P(A;;GA;;;SY)(A;;GA;;;BA)"
    );
*/

// -- Security descriptor
//RtlInitUnicodeString(&sd,
//  _T("D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;BU)(A;;GA;;;WD)"));

    Status = IoCreateDeviceSecure(
      DriverObject, 
      0, // sizeof(DEVICE_EXTENSION),
      &DeviceName,
      FILE_DEVICE_UNKNOWN, // FILE_DEVICE_NOTHING
      FILE_DEVICE_SECURE_OPEN,
      FALSE,
      &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, // &sd
      NULL,
      &DeviceObject
    );

    if( !NT_SUCCESS(Status) )
      {
        DbgPrint( "[chipsec] ERROR: DriverEntry: IoCreateDeviceSecure failed (status = %d)\n", Status );
        return Status;
      }

    //
    // Create the symbolic link that the Win32 app can access the device
    //
    RtlInitUnicodeString (&DosDeviceName, DEVICE_NAME_DOS );
    Status = IoCreateSymbolicLink(&DosDeviceName, &DeviceName);
    if( !NT_SUCCESS(Status) ) 
      {
        DbgPrint( "[chipsec] ERROR: DriverEntry: IoCreateSymbolicLink failed\n" );
        if(DeviceObject)
          {           
            IoDeleteDevice(DeviceObject);
          }
        return Status;
      }

    //
    // Initialize the dispatch table of the driver object.
    // NT sends requests to these routines.
    //
    DriverObject->MajorFunction[IRP_MJ_CREATE]         = DriverOpen;
    DriverObject->MajorFunction[IRP_MJ_CLOSE]          = DriverClose;
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDeviceControl;
    DriverObject->DriverUnload                         = DriverUnload;

    return Status;

}
Esempio n. 4
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT theDriverObject,
    IN PUNICODE_STRING theRegistryPath)
{
    NTSTATUS status;
    UNICODE_STRING devname, linkname;
    BOOLEAN ip_fw_started = FALSE, pfhook_started = FALSE;
    int i;

    g_driver_object = theDriverObject;

    log_init();

    /* before starting ip_fw init ip_fw_nt wrappers */
    ip_fw_nt_init();
    rn_init();
    init_tables();
    iflist_init();
    init_packet();
    
    /* send load event to ip_fw */
    
    status = module_ipfw->modevent(theDriverObject, MOD_LOAD, NULL);
    if (status != STATUS_SUCCESS) {
        KdPrint(("[wipfw] DriverEntry: ip_fw MOD_LOAD: 0x%x!\n", status));
        goto done;
    }

    ip_fw_started = TRUE;

    /* setup pfhook */

    status = pfhook_init();
    if (status != STATUS_SUCCESS) {
        KdPrint(("[wipfw] DriverEntry: pfhook_init: 0x%x!\n", status));
        goto done;
    }

    pfhook_started = TRUE;

    /* create control device and symbolic link */

    RtlInitUnicodeString(&devname, L"\\Device\\ip_fw");

    status = IoCreateDeviceSecure(theDriverObject, 0, &devname, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, (BOOLEAN) FALSE, \
    	&SDDL_DEVOBJ_SYS_ALL_ADM_ALL, NULL, &g_devcontrol);
    if (status != STATUS_SUCCESS) {
        KdPrint(("[wipfw] DriverEntry: IoCreateDevice: 0x%x!\n", status));
        goto done;
    }
    
    g_devcontrol->Flags |= DO_POWER_PAGABLE;

    RtlInitUnicodeString(&linkname, L"\\??\\ip_fw");

    status = IoCreateSymbolicLink(&linkname, &devname);
    if (status != STATUS_SUCCESS) {
        KdPrint(("[wipfw] DriverEntry: IoCreateSymbolicLink: 0x%x!\n", status));
        goto done;
    }

    for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
        theDriverObject->MajorFunction[i] = DeviceDispatch;
        
    theDriverObject->MajorFunction[IRP_MJ_PNP] = DeviceDispatch;

#ifdef KLD_MODULE
    theDriverObject->DriverUnload = OnUnload;
#endif

    status = STATUS_SUCCESS;

done:
    if (status != STATUS_SUCCESS) {
        if (g_devcontrol != NULL)
            IoDeleteDevice(g_devcontrol);
        if (pfhook_started)
            pfhook_free();
        if (ip_fw_started)
            module_ipfw->modevent(theDriverObject, MOD_UNLOAD, NULL);
        
        iflist_free();
        log_free();
    }

    return status;
}
Esempio n. 5
0
NTSTATUS
DriverEntry(
    __in PDRIVER_OBJECT  DriverObject,
    __in PUNICODE_STRING RegistryPath
    )
/*++

Routine Description:

    Installable driver initialization entry point.
    This entry point is called directly by the I/O system.

Arguments:

    DriverObject - pointer to the driver object

    registryPath - pointer to a unicode string representing the path,
                   to driver-specific key in the registry.

Return Value:

    STATUS_SUCCESS if successful,
    STATUS_UNSUCCESSFUL otherwise

--*/
{
    NTSTATUS            status = STATUS_SUCCESS;
    UNICODE_STRING      unicodeDeviceName;
    UNICODE_STRING      unicodeDosDeviceName;
    PDEVICE_OBJECT      deviceObject;
    PDEVICE_EXTENSION   devExtension;
    HANDLE              threadHandle;
    UNICODE_STRING      sddlString;

    UNREFERENCED_PARAMETER (RegistryPath);

    CSAMP_KDPRINT(("DriverEntry Enter \n"));


    (void) RtlInitUnicodeString(&unicodeDeviceName, CSAMP_DEVICE_NAME_U);

    (void) RtlInitUnicodeString( &sddlString, L"D:P(A;;GA;;;SY)(A;;GA;;;BA)");

    //
    // We will create a secure deviceobject so that only processes running
    // in admin and local system account can access the device. Refer
    // "Security Descriptor String Format" section in the platform
    // SDK documentation to understand the format of the sddl string.
    // We need to do because this is a legacy driver and there is no INF
    // involved in installing the driver. For PNP drivers, security descriptor
    // is typically specified for the FDO in the INF file.
    //

    status = IoCreateDeviceSecure(
                DriverObject,
                sizeof(DEVICE_EXTENSION),
                &unicodeDeviceName,
                FILE_DEVICE_UNKNOWN,
                FILE_DEVICE_SECURE_OPEN,
                (BOOLEAN) FALSE,
                &sddlString,
                (LPCGUID)&GUID_DEVCLASS_CANCEL_SAMPLE,
                &deviceObject
                );
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    DbgPrint("DeviceObject %p\n", deviceObject);

    //
    // Allocate and initialize a Unicode String containing the Win32 name
    // for our device.
    //

    (void)RtlInitUnicodeString( &unicodeDosDeviceName, CSAMP_DOS_DEVICE_NAME_U );


    status = IoCreateSymbolicLink(
                (PUNICODE_STRING) &unicodeDosDeviceName,
                (PUNICODE_STRING) &unicodeDeviceName
                );

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

    devExtension = deviceObject->DeviceExtension;

    DriverObject->MajorFunction[IRP_MJ_CREATE]=
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = CsampCreateClose;
    DriverObject->MajorFunction[IRP_MJ_READ] = CsampRead;
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = CsampCleanup;

    DriverObject->DriverUnload = CsampUnload;

    //
    // Set the flag signifying that we will do buffered I/O. This causes NT
    // to allocate a buffer on a ReadFile operation which will then be copied
    // back to the calling application by the I/O subsystem
    //

    deviceObject->Flags |= DO_BUFFERED_IO;

    //
    // This is used to serailize access to the queue.
    //

    KeInitializeSpinLock(&devExtension->QueueLock);

    KeInitializeSemaphore(&devExtension->IrpQueueSemaphore, 0, MAXLONG );

    //
    // Initialize the pending Irp devicequeue
    //

    InitializeListHead( &devExtension->PendingIrpQueue );

    //
    // Initialize the cancel safe queue
    //
    IoCsqInitialize( &devExtension->CancelSafeQueue,
                     CsampInsertIrp,
                     CsampRemoveIrp,
                     CsampPeekNextIrp,
                     CsampAcquireLock,
                     CsampReleaseLock,
                     CsampCompleteCanceledIrp );
    //
    // 10 is multiplied because system time is specified in 100ns units
    //

    devExtension->PollingInterval.QuadPart = Int32x32To64(
                                CSAMP_RETRY_INTERVAL, -10);
    //
    // Note down system time
    //

    KeQuerySystemTime (&devExtension->LastPollTime);

    //
    // Start the polling thread.
    //

    devExtension->ThreadShouldStop = FALSE;

    status = PsCreateSystemThread(&threadHandle,
                                (ACCESS_MASK)0,
                                NULL,
                                (HANDLE) 0,
                                NULL,
                                CsampPollingThread,
                                deviceObject );

    if ( !NT_SUCCESS( status ))
    {
        IoDeleteSymbolicLink( &unicodeDosDeviceName );
        IoDeleteDevice( deviceObject );
        return status;
    }

    //
    // Convert the Thread object handle into a pointer to the Thread object
    // itself. Then close the handle.
    //

    ObReferenceObjectByHandle(threadHandle,
                            THREAD_ALL_ACCESS,
                            NULL,
                            KernelMode,
                            &devExtension->ThreadObject,
                            NULL );

    ZwClose(threadHandle);

    CSAMP_KDPRINT(("DriverEntry Exit = %x\n", status));

    ASSERT(NT_SUCCESS(status));

    return status;
}
Esempio n. 6
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT   pDriverObject,
    IN PUNICODE_STRING  pRegistryPath
    )
/*++

Routine Description:

    Called on loading. We create a device object to handle user-mode requests
    on, and register ourselves as a protocol with NDIS.

Arguments:

    pDriverObject - Pointer to driver object created by system.

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

Return Value:

    NT Status code
    
--*/
{
    NDIS_PROTOCOL_CHARACTERISTICS   protocolChar;
    NTSTATUS                        status = STATUS_SUCCESS;
    NDIS_STRING                     protoName = NDIS_STRING_CONST("NdisProt");     
    UNICODE_STRING                  ntDeviceName;
    UNICODE_STRING                  win32DeviceName;
    BOOLEAN                         fSymbolicLink = FALSE;
    PDEVICE_OBJECT                  deviceObject = NULL;

    UNREFERENCED_PARAMETER(pRegistryPath);

    DEBUGP(DL_LOUD, ("DriverEntry\n"));

    Globals.pDriverObject = pDriverObject;
    NPROT_INIT_EVENT(&Globals.BindsComplete);

    do
    {

        //
        // Create our device object using which an application can
        // access NDIS devices.
        //
        RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
#ifndef WIN9X
        status = IoCreateDeviceSecure(pDriverObject,
                                 0,
                                 &ntDeviceName,
                                 FILE_DEVICE_NETWORK,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
                                 NULL,
                                 &deviceObject);

#else     
        status = IoCreateDevice(pDriverObject,
                                 0,
                                 &ntDeviceName,
                                 FILE_DEVICE_NETWORK,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &deviceObject);
#endif
        if (!NT_SUCCESS (status))
        {
            //
            // Either not enough memory to create a deviceobject or another
            // deviceobject with the same name exits. This could happen
            // if you install another instance of this device.
            //
            break;
        }

        RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);

        status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);

        if (!NT_SUCCESS(status))
        {
            break;
        }

        fSymbolicLink = TRUE;
    
        deviceObject->Flags |= DO_DIRECT_IO;
        Globals.ControlDeviceObject = deviceObject;

        NPROT_INIT_LIST_HEAD(&Globals.OpenList);
        NPROT_INIT_LOCK(&Globals.GlobalLock);

        //
        // Initialize the protocol characterstic structure
        //
    
        NdisZeroMemory(&protocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

        protocolChar.MajorNdisVersion            = 5;
        protocolChar.MinorNdisVersion            = 0;
        protocolChar.Name                        = protoName;
        protocolChar.OpenAdapterCompleteHandler  = NdisProtOpenAdapterComplete;
        protocolChar.CloseAdapterCompleteHandler = NdisProtCloseAdapterComplete;
        protocolChar.SendCompleteHandler         = NdisProtSendComplete;
        protocolChar.TransferDataCompleteHandler = NdisProtTransferDataComplete;
        protocolChar.ResetCompleteHandler        = NdisProtResetComplete;
        protocolChar.RequestCompleteHandler      = NdisProtRequestComplete;
        protocolChar.ReceiveHandler              = NdisProtReceive;
        protocolChar.ReceiveCompleteHandler      = NdisProtReceiveComplete;
        protocolChar.StatusHandler               = NdisProtStatus;
        protocolChar.StatusCompleteHandler       = NdisProtStatusComplete;
        protocolChar.BindAdapterHandler          = NdisProtBindAdapter;
        protocolChar.UnbindAdapterHandler        = NdisProtUnbindAdapter;
        protocolChar.UnloadHandler               = NULL;
        protocolChar.ReceivePacketHandler        = NdisProtReceivePacket;
        protocolChar.PnPEventHandler             = NdisProtPnPEventHandler;

        //
        // Register as a protocol driver
        //
    
        NdisRegisterProtocol(
            (PNDIS_STATUS)&status,
            &Globals.NdisProtocolHandle,
            &protocolChar,
            sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

        if (status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(DL_WARN, ("Failed to register protocol with NDIS\n"));
            status = STATUS_UNSUCCESSFUL;
            break;
        }

#ifdef NDIS51
        Globals.PartialCancelId = NdisGeneratePartialCancelId();
        Globals.PartialCancelId <<= ((sizeof(PVOID) - 1) * 8);
        DEBUGP(DL_LOUD, ("DriverEntry: CancelId %lx\n", Globals.PartialCancelId));
#endif

        //
        // Now set only the dispatch points we would like to handle.
        //
        pDriverObject->MajorFunction[IRP_MJ_CREATE] = NdisProtOpen;
        pDriverObject->MajorFunction[IRP_MJ_CLOSE]  = NdisProtClose;
        pDriverObject->MajorFunction[IRP_MJ_READ]   = NdisProtRead; 
        pDriverObject->MajorFunction[IRP_MJ_WRITE]  = NdisProtWrite;
        pDriverObject->MajorFunction[IRP_MJ_CLEANUP]  = NdisProtCleanup;
        pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = NdisProtIoControl;
        pDriverObject->DriverUnload = NdisProtUnload;

        status = STATUS_SUCCESS;
        
    }
    while (FALSE);
       

    if (!NT_SUCCESS(status))
    {
        if (deviceObject)
        {
            #pragma prefast(disable:28107, "within critical section, device object is held")
            KeEnterCriticalRegion();
            IoDeleteDevice(deviceObject);
            Globals.ControlDeviceObject = NULL;
            KeLeaveCriticalRegion();
        }

        if (fSymbolicLink)
        {
            IoDeleteSymbolicLink(&win32DeviceName);
        }
        
    }
    
    return status;

}
Esempio n. 7
0
NTSTATUS
DokanCreateDiskDevice(
	__in PDRIVER_OBJECT DriverObject,
	__in ULONG			MountId,
	__in PWCHAR			BaseGuid,
	__in PDOKAN_GLOBAL	DokanGlobal,
	__in DEVICE_TYPE	DeviceType,
	__in ULONG			DeviceCharacteristics,
	__out PDokanDCB*	Dcb
	)
{
	WCHAR				diskDeviceNameBuf[MAXIMUM_FILENAME_LENGTH];
	WCHAR				fsDeviceNameBuf[MAXIMUM_FILENAME_LENGTH];
	WCHAR				symbolicLinkNameBuf[MAXIMUM_FILENAME_LENGTH];
	PDEVICE_OBJECT		diskDeviceObject;
	PDEVICE_OBJECT		fsDeviceObject;
	PDokanDCB			dcb;
	PDokanVCB			vcb;
	UNICODE_STRING		diskDeviceName;
	NTSTATUS			status;
	BOOLEAN				isNetworkFileSystem = (DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM);

	// make DeviceName and SymboliLink
	if (isNetworkFileSystem) {
#ifdef DOKAN_NET_PROVIDER
		RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME);
		RtlStringCchCopyW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME);
		RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_SYMBOLIC_LINK_NAME);
#else
		RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME);
		RtlStringCchCatW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
		RtlStringCchCopyW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_DEVICE_NAME);
		RtlStringCchCatW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
		RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_NET_SYMBOLIC_LINK_NAME);
		RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
#endif

	} else {
		RtlStringCchCopyW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_DISK_DEVICE_NAME);
		RtlStringCchCatW(diskDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
		RtlStringCchCopyW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_FS_DEVICE_NAME);
		RtlStringCchCatW(fsDeviceNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
		RtlStringCchCopyW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, DOKAN_SYMBOLIC_LINK_NAME);
		RtlStringCchCatW(symbolicLinkNameBuf, MAXIMUM_FILENAME_LENGTH, BaseGuid);
	}
	
	RtlInitUnicodeString(&diskDeviceName, diskDeviceNameBuf);

	//
	// make a DeviceObject for Disk Device
	//
	if (!isNetworkFileSystem) {
		status = IoCreateDeviceSecure(
					DriverObject,		// DriverObject
					sizeof(DokanDCB),	// DeviceExtensionSize
					&diskDeviceName,	// DeviceName
					FILE_DEVICE_DISK,	// DeviceType
					DeviceCharacteristics,	// DeviceCharacteristics
					FALSE,				// Not Exclusive
					&sddl, // Default SDDL String
					NULL,				// Device Class GUID
					&diskDeviceObject); // DeviceObject
	} else {
		status = IoCreateDevice(
					DriverObject,			// DriverObject
					sizeof(DokanDCB),		// DeviceExtensionSize
					NULL,					// DeviceName
					FILE_DEVICE_UNKNOWN,	// DeviceType
					DeviceCharacteristics,	// DeviceCharacteristics
					FALSE,					// Not Exclusive
					&diskDeviceObject);		// DeviceObject
	}


	if (!NT_SUCCESS(status)) {
		DDbgPrint("  IoCreateDevice (DISK_DEVICE) failed: 0x%x\n", status);
		return status;
	}
	DDbgPrint("DokanDiskDevice: %wZ created\n", &diskDeviceName);

	//
	// Initialize the device extension.
	//
	dcb = diskDeviceObject->DeviceExtension;
	*Dcb = dcb;
	dcb->DeviceObject = diskDeviceObject;
	dcb->Global = DokanGlobal;

	dcb->Identifier.Type = DCB;
	dcb->Identifier.Size = sizeof(DokanDCB);

	dcb->MountId = MountId;
	dcb->DeviceType = FILE_DEVICE_DISK;
	dcb->DeviceCharacteristics = DeviceCharacteristics;
	KeInitializeEvent(&dcb->KillEvent, NotificationEvent, FALSE);

	//
	// Establish user-buffer access method.
	//
	diskDeviceObject->Flags |= DO_DIRECT_IO;

	// initialize Event and Event queue
	DokanInitIrpList(&dcb->PendingIrp);
	DokanInitIrpList(&dcb->PendingEvent);
	DokanInitIrpList(&dcb->NotifyEvent);

	KeInitializeEvent(&dcb->ReleaseEvent, NotificationEvent, FALSE);

	// "0" means not mounted
	dcb->Mounted = 0;

	ExInitializeResourceLite(&dcb->Resource);

	dcb->CacheManagerNoOpCallbacks.AcquireForLazyWrite  = &DokanNoOpAcquire;
	dcb->CacheManagerNoOpCallbacks.ReleaseFromLazyWrite = &DokanNoOpRelease;
	dcb->CacheManagerNoOpCallbacks.AcquireForReadAhead  = &DokanNoOpAcquire;
	dcb->CacheManagerNoOpCallbacks.ReleaseFromReadAhead = &DokanNoOpRelease;

	dcb->SymbolicLinkName = AllocateUnicodeString(symbolicLinkNameBuf);
	dcb->DiskDeviceName =  AllocateUnicodeString(diskDeviceNameBuf);
	dcb->FileSystemDeviceName = AllocateUnicodeString(fsDeviceNameBuf);

	status = IoCreateDeviceSecure(
				DriverObject,		// DriverObject
				sizeof(DokanVCB),	// DeviceExtensionSize
				dcb->FileSystemDeviceName, // DeviceName
				DeviceType,			// DeviceType
				DeviceCharacteristics,	// DeviceCharacteristics
				FALSE,				// Not Exclusive
				&sddl, // Default SDDL String
				NULL,				// Device Class GUID
				&fsDeviceObject);	// DeviceObject

	if (!NT_SUCCESS(status)) {
		DDbgPrint("  IoCreateDevice (FILE_SYSTEM_DEVICE) failed: 0x%x\n", status);
		IoDeleteDevice(diskDeviceObject);
		return status;
	}
	DDbgPrint("DokanFileSystemDevice: %wZ created\n", dcb->FileSystemDeviceName);

	vcb = fsDeviceObject->DeviceExtension;

	vcb->Identifier.Type = VCB;
	vcb->Identifier.Size = sizeof(DokanVCB);

	vcb->DeviceObject = fsDeviceObject;
	vcb->Dcb = dcb;

	dcb->Vcb = vcb;
	
	InitializeListHead(&vcb->NextFCB);

	InitializeListHead(&vcb->DirNotifyList);
	FsRtlNotifyInitializeSync(&vcb->NotifySync);

	ExInitializeFastMutex(&vcb->AdvancedFCBHeaderMutex);
#if _WIN32_WINNT >= 0x0501
	FsRtlSetupAdvancedHeader(&vcb->VolumeFileHeader, &vcb->AdvancedFCBHeaderMutex);
#else
	if (DokanFsRtlTeardownPerStreamContexts) {
		FsRtlSetupAdvancedHeader(&vcb->VolumeFileHeader, &vcb->AdvancedFCBHeaderMutex);
	}
#endif


	//
	// Establish user-buffer access method.
	//
	fsDeviceObject->Flags |= DO_DIRECT_IO;

	if (diskDeviceObject->Vpb) {
		// NOTE: This can be done by IoRegisterFileSystem + IRP_MN_MOUNT_VOLUME,
		// however that causes BSOD inside filter manager on Vista x86 after mount
		// (mouse hover on file).
		// Probably FS_FILTER_CALLBACKS.PreAcquireForSectionSynchronization is
		// not correctly called in that case.
		diskDeviceObject->Vpb->DeviceObject = fsDeviceObject;
		diskDeviceObject->Vpb->RealDevice = fsDeviceObject;
		diskDeviceObject->Vpb->Flags |= VPB_MOUNTED;
		diskDeviceObject->Vpb->VolumeLabelLength = (USHORT)wcslen(VOLUME_LABEL) * sizeof(WCHAR);
		RtlStringCchCopyW(diskDeviceObject->Vpb->VolumeLabel,
						sizeof(diskDeviceObject->Vpb->VolumeLabel) / sizeof(WCHAR),
						VOLUME_LABEL);
		diskDeviceObject->Vpb->SerialNumber = 0x19831116;
	}

	ObReferenceObject(fsDeviceObject);
	ObReferenceObject(diskDeviceObject);

	//
	// Create a symbolic link for userapp to interact with the driver.
	//
	status = IoCreateSymbolicLink(dcb->SymbolicLinkName, dcb->DiskDeviceName);

	if (!NT_SUCCESS(status)) {
		if (diskDeviceObject->Vpb) {
			diskDeviceObject->Vpb->DeviceObject = NULL;
			diskDeviceObject->Vpb->RealDevice = NULL;
			diskDeviceObject->Vpb->Flags = 0;
		}
		IoDeleteDevice(diskDeviceObject);
		IoDeleteDevice(fsDeviceObject);
		DDbgPrint("  IoCreateSymbolicLink returned 0x%x\n", status);
		return status;
	}
	DDbgPrint("SymbolicLink: %wZ -> %wZ created\n", dcb->SymbolicLinkName, dcb->DiskDeviceName);

	// Mark devices as initialized
	diskDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	fsDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

	//IoRegisterFileSystem(fsDeviceObject);

	if (isNetworkFileSystem) {
		// Run FsRtlRegisterUncProvider in System thread.
		HANDLE handle;
		PKTHREAD thread;
		OBJECT_ATTRIBUTES objectAttribs;

		InitializeObjectAttributes(
			&objectAttribs, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
		status = PsCreateSystemThread(&handle, THREAD_ALL_ACCESS,
			&objectAttribs, NULL, NULL, (PKSTART_ROUTINE)DokanRegisterUncProvider, dcb);
		if (!NT_SUCCESS(status)) {
			DDbgPrint("PsCreateSystemThread failed: 0x%X\n", status);
		} else {
			ObReferenceObjectByHandle(handle, THREAD_ALL_ACCESS, NULL,
					KernelMode, &thread, NULL);
			ZwClose(handle);
			KeWaitForSingleObject(thread, Executive, KernelMode, FALSE, NULL);
			ObDereferenceObject(thread);
		}
	}

	//DokanRegisterMountedDeviceInterface(diskDeviceObject, dcb);
	
	dcb->Mounted = 1;

	//DokanSendVolumeArrivalNotification(&deviceName);
	//DokanRegisterDeviceInterface(DriverObject, diskDeviceObject, dcb);

	return STATUS_SUCCESS;
}
Esempio n. 8
0
NTSTATUS
DriverEntry(
	__in PDRIVER_OBJECT DriverObject,
	__in PUNICODE_STRING RegistryPath)
{
    NTSTATUS status;
    PDEVICE_OBJECT deviceObject;
    PCONTROL_DEVICE_EXTENSION deviceExtension;
	ULONG i;

	WCHAR controlDeviceUnicodeStringBuffer[64];
	UNICODE_STRING controlDeviceUnicodeString = {
		0, 
		sizeof(controlDeviceUnicodeStringBuffer), 
		controlDeviceUnicodeStringBuffer};


    KdPrint(("NdasPortExt DriverEntry build on %s %s at %s MSVC %d\n", 
        __DATE__, __TIME__, __BUILDMACHINE_STRING__, _MSC_VER));

	i = 0;

	do
	{
		status = RtlUnicodeStringPrintf(
			&controlDeviceUnicodeString,
			L"\\Device\\NdasPortExt%d", i++);

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

		status = IoCreateDeviceSecure(
			DriverObject,
			sizeof(CONTROL_DEVICE_EXTENSION),
			&controlDeviceUnicodeString,
			FILE_DEVICE_UNKNOWN,
			FILE_DEVICE_SECURE_OPEN,
			FALSE,
			&SDDL_DEVOBJ_KERNEL_ONLY,
			&GUID_DEVCLASS_UNKNOWN,
			&deviceObject);

	} while (STATUS_OBJECT_NAME_COLLISION == status);

    if (!NT_SUCCESS(status))
    {
        KdPrint(("IoCreateDevice failed, status=%x\n", status));
        return status;
    }

    KdPrint(("Control device=%p, name=%wZ\n", deviceObject, &controlDeviceUnicodeString));

	deviceExtension = (PCONTROL_DEVICE_EXTENSION) deviceObject->DeviceExtension;

	RtlZeroMemory(
		deviceExtension,
		sizeof(CONTROL_DEVICE_EXTENSION));

	for (i = 0; i < HOST_DEVICE_TYPE_COUNT; ++i)
	{
		deviceExtension->SymbolicLinkNames[i].Buffer = deviceExtension->SymbolicLinkNameBuffers[i];
		deviceExtension->SymbolicLinkNames[i].MaximumLength = sizeof(deviceExtension->SymbolicLinkNameBuffers[i]);

		status = NdasPortExtRegisterExternalTypes(
			&controlDeviceUnicodeString,
			HostingDeviceTypes[i],
			&deviceExtension->SymbolicLinkNames[i]);

		if (!NT_SUCCESS(status))
		{
			ULONG j = i;
			for (j = 0; j + 1 < i; ++j)
			{
				IoDeleteSymbolicLink(&deviceExtension->SymbolicLinkNames[i]);
			}
			return status;
		}
	}

    DriverObject->DriverUnload = NdasPortExtDriverUnload;
    DriverObject->MajorFunction[IRP_MJ_CREATE] = 
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = NdasPortExtCreateClose;
    DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = NdasPortExtInternalDeviceControl;

    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    KdPrint(("NdasPortExt loaded successfully.\n"));
    
    return STATUS_SUCCESS;
}
Esempio n. 9
0
File: pnp.c Progetto: Shmuma/usbip
NTSTATUS bus_plugin_dev(ioctl_usbvbus_plugin * plugin, PFDO_DEVICE_DATA  fdodata,
		PFILE_OBJECT fo)
{
    PDEVICE_OBJECT      pdo;
    PPDO_DEVICE_DATA    pdodata, old_pdodata;
    NTSTATUS            status;
    ULONG               len;
    PLIST_ENTRY         entry;
    unsigned long i;

    PAGED_CODE ();

    Bus_KdPrint (fdodata, BUS_DBG_PNP_INFO,
                  ("Exposing PDO\n"
                   "======addr:  %d\n"
                   "======vendor:product: %04x:%04x\n",
                   plugin->addr,
		   plugin->vendor, plugin->product));

    if(plugin->addr <= 0)
        return STATUS_INVALID_PARAMETER;

    ExAcquireFastMutex (&fdodata->Mutex);

    for (entry = fdodata->ListOfPDOs.Flink;
         entry != &fdodata->ListOfPDOs;
         entry = entry->Flink) {

        pdodata = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link);
        if (plugin->addr == pdodata->SerialNo &&
            pdodata->DevicePnPState != SurpriseRemovePending)
        {
	    ExReleaseFastMutex (&fdodata->Mutex);
	    return STATUS_INVALID_PARAMETER;
        }
    }

    ExReleaseFastMutex (&fdodata->Mutex);

    // Create the PDO
    //


    Bus_KdPrint(fdodata, BUS_DBG_PNP_NOISE,
                 ("fdodata->NextLowerDriver = 0x%p\n", fdodata->NextLowerDriver));

    //
    // PDO must have a name. You should let the system auto generate a
    // name by specifying FILE_AUTOGENERATED_DEVICE_NAME in the
    // DeviceCharacteristics parameter. Let us create a secure deviceobject,
    // in case the child gets installed as a raw device (RawDeviceOK), to prevent
    // an unpriviledged user accessing our device. This function is avaliable
    // in a static WDMSEC.LIB and can be used in Win2k, XP, and Server 2003
    // Just make sure that  the GUID specified here is not a setup class GUID.
    // If you specify a setup class guid, you must make sure that class is
    // installed before enumerating the PDO.
    //

    status = IoCreateDeviceSecure(fdodata->Self->DriverObject,
                sizeof (PDO_DEVICE_DATA),
                NULL,
                FILE_DEVICE_BUS_EXTENDER,
                FILE_AUTOGENERATED_DEVICE_NAME |FILE_DEVICE_SECURE_OPEN,
                FALSE,
                &SDDL_DEVOBJ_SYS_ALL_ADM_ALL, // read wdmsec.h for more info
                (LPCGUID)&GUID_SD_BUSENUM_PDO,
                &pdo);
    if (!NT_SUCCESS (status)) {
        return status;
    }

    pdodata = (PPDO_DEVICE_DATA) pdo->DeviceExtension;

#define HARDWARE_IDS_TPL L"USB\\Vid_%04x&Pid_%04x&Rev_%04xZUSB\\Vid_%04x&Pid_%04xZ"

    len = sizeof(HARDWARE_IDS_TPL);
    pdodata->HardwareIDs =
            ExAllocatePoolWithTag (NonPagedPool, len, BUSENUM_POOL_TAG);
    if (NULL == pdodata->HardwareIDs) {
        IoDeleteDevice(pdo);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlStringCchPrintfW(pdodata->HardwareIDs, len/sizeof(wchar_t),
		HARDWARE_IDS_TPL,
	        plugin->vendor, plugin->product, plugin->version,
	        plugin->vendor, plugin->product);
    for(i=0;i<sizeof(HARDWARE_IDS_TPL);i++){
	    if('Z'==pdodata->HardwareIDs[i])
		    pdodata->HardwareIDs[i]=0;
    }
#define COMPATIBLE_IDS_TPL L"USB\\Class_%02x&SubClass_%02x&Prot_%02xZUSB\\Class_%02x&SubClass_%02xZUSB\\Class_%02xZ"
#define COMPATIBLE_COMPOSITE_IDS_TPL L"USB\\Class_%02x&SubClass_%02x&Prot_%02xZUSB\\Class_%02x&SubClass_%02xZUSB\\Class_%02xZUSB\\COMPOSITEZ"
    if(plugin->inum>1)
	   len = sizeof(COMPATIBLE_COMPOSITE_IDS_TPL);
    else
	   len = sizeof(COMPATIBLE_IDS_TPL);
    pdodata->compatible_ids =
            ExAllocatePoolWithTag (NonPagedPool, len, BUSENUM_POOL_TAG);
    
	if (NULL == pdodata->compatible_ids) {
		ExFreePool(pdodata->HardwareIDs);
        IoDeleteDevice(pdo);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlZeroMemory(pdodata->compatible_ids, len);

    pdodata->compatible_ids_len = len;
    RtlStringCchPrintfW(pdodata->compatible_ids, len/sizeof(wchar_t),
		(plugin->inum>1)?COMPATIBLE_COMPOSITE_IDS_TPL:COMPATIBLE_IDS_TPL,
	        plugin->int0_class, plugin->int0_subclass, plugin->int0_protocol,
		plugin->int0_class, plugin->int0_subclass,
		plugin->int0_class);
    for(i=0;i<len;i++){
	    if('Z'==pdodata->compatible_ids[i])
		    pdodata->compatible_ids[i]=0;
    }
    old_pdodata = (PPDO_DEVICE_DATA) InterlockedCompareExchangePointer(&(fo->FsContext), pdodata, 0);
    if(old_pdodata){
	    KdPrint(("you can't plugin again"));
	    ExFreePool(pdodata->HardwareIDs);
	    ExFreePool(pdodata->compatible_ids);
	   IoDeleteDevice(pdo);
           return STATUS_INVALID_PARAMETER;
    }
    pdodata->SerialNo = plugin->addr;
    pdodata->fo = fo;
    pdodata->devid = plugin->devid;
    pdodata->speed = plugin->speed;
    bus_init_pdo (pdo, fdodata);

    //
    // Device Relation changes if a new pdo is created. So let
    // the PNP system now about that. This forces it to send bunch of pnp
    // queries and cause the function driver to be loaded.
    //

    IoInvalidateDeviceRelations (fdodata->UnderlyingPDO, BusRelations);

    return status;
}
Esempio n. 10
0
NTSTATUS USBPcapCreateRootHubControlDevice(IN PDEVICE_EXTENSION hubExt,
                                           OUT PDEVICE_OBJECT *control,
                                           OUT USHORT *busId)
{
    UNICODE_STRING     ntDeviceName;
    UNICODE_STRING     symbolicLinkName;
    PDEVICE_OBJECT     controlDevice = NULL;
    PDEVICE_EXTENSION  controlExt = NULL;
    NTSTATUS           status;
    USHORT             id;
    PWCHAR             ntNameBuffer[MAX_NTNAME_LEN];
    PWCHAR             symbolicNameBuffer[MAX_SYMBOLIC_LEN];

    ASSERT(hubExt->deviceMagic == USBPCAP_MAGIC_ROOTHUB);

    /* Acquire the control device ID */
    id = (USHORT) InterlockedIncrement(&g_controlId);

    ntDeviceName.Length = 0;
    ntDeviceName.MaximumLength = MAX_NTNAME_LEN;
    ntDeviceName.Buffer = (PWSTR)ntNameBuffer;

    symbolicLinkName.Length = 0;
    symbolicLinkName.MaximumLength = MAX_SYMBOLIC_LEN;
    symbolicLinkName.Buffer = (PWSTR)symbolicNameBuffer;

    status = RtlUnicodeStringPrintf(&ntDeviceName,
                                    NTNAME_PREFIX L"%hu", id);
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    status = RtlUnicodeStringPrintf(&symbolicLinkName,
                                    SYMBOLIC_PREFIX L"%hu", id);
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    KdPrint(("Creating device %wZ (%wZ)\n",
            &ntDeviceName, &symbolicLinkName));

    status = IoCreateDeviceSecure(hubExt->pDrvObj,
                                  sizeof(DEVICE_EXTENSION),
                                  &ntDeviceName,
                                  FILE_DEVICE_UNKNOWN,
                                  FILE_DEVICE_SECURE_OPEN,
                                  TRUE, /* Exclusive device */
                                  &SDDL_DEVOBJ_SYS_ALL_ADM_ALL_EVERYONE_ANY,
                                  NULL,
                                  &controlDevice);

    if (NT_SUCCESS(status))
    {
        controlDevice->Flags |= DO_DIRECT_IO;

        status = IoCreateSymbolicLink(&symbolicLinkName, &ntDeviceName);

        if (!NT_SUCCESS(status))
        {
            IoDeleteDevice(controlDevice);
            KdPrint(("IoCreateSymbolicLink failed %x\n", status));
            return status;
        }

        controlExt = (PDEVICE_EXTENSION)controlDevice->DeviceExtension;
        controlExt->deviceMagic      = USBPCAP_MAGIC_CONTROL;
        controlExt->pThisDevObj      = controlDevice;
        controlExt->pNextDevObj      = NULL;
        controlExt->pDrvObj          = hubExt->pDrvObj;

        IoInitializeRemoveLock(&controlExt->removeLock, 0, 0, 0);
        controlExt->parentRemoveLock = &hubExt->removeLock;

        /* Initialize USBPcap control context */
        controlExt->context.control.id             = id;
        controlExt->context.control.pRootHubObject = hubExt->pThisDevObj;


        KeInitializeSpinLock(&controlExt->context.control.csqSpinLock);
        InitializeListHead(&controlExt->context.control.lePendIrp);
        status = IoCsqInitialize(&controlExt->context.control.ioCsq,
                                 DkCsqInsertIrp, DkCsqRemoveIrp,
                                 DkCsqPeekNextIrp, DkCsqAcquireLock,
                                 DkCsqReleaseLock, DkCsqCompleteCanceledIrp);
        if (!NT_SUCCESS(status))
        {
            DkDbgVal("Error initialize Cancel-safe queue!", status);
            goto End;
        }

        controlDevice->Flags &= ~DO_DEVICE_INITIALIZING;
    }
    else
    {
        KdPrint(("IoCreateDevice failed %x\n", status));
    }

End:
    if ((!NT_SUCCESS(status)) || (controlExt == NULL))
    {
        if (controlDevice != NULL)
        {
            IoDeleteSymbolicLink(&symbolicLinkName);
            IoDeleteDevice(controlDevice);
        }
    }
    else
    {
        IoAcquireRemoveLock(controlExt->parentRemoveLock, NULL);
        *control = controlDevice;
        *busId = id;
    }

    return status;
}
Esempio n. 11
0
static NTSTATUS
V4vAddDevice(PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo)
{
    NTSTATUS          status = STATUS_SUCCESS;
    UNICODE_STRING    deviceName;
    PDEVICE_OBJECT    fdo = NULL;
    PXENV4V_EXTENSION pde = NULL;
    LONG              val;
    BOOLEAN           symlink = FALSE;
    LARGE_INTEGER     seed;
    WCHAR            *szSddl = NULL;
    UNICODE_STRING    sddlString;
    CHAR             *szFpath = NULL;

    TraceVerbose(("====> '%s'.\n", __FUNCTION__));

    // We only allow one instance of this device type. If more than on pdo is created we need
    val = InterlockedCompareExchange(&g_deviceCreated, 1, 0);
    if (val != 0) {
        TraceWarning(("cannot instantiate more that one v4v device node.\n"));
        return STATUS_UNSUCCESSFUL;
    }

    do {
        // Create our device
        RtlInitUnicodeString(&deviceName, V4V_DEVICE_NAME);
        szSddl = g_win5Sddl;
        RtlInitUnicodeString(&sddlString, szSddl);

        status = 
            IoCreateDeviceSecure(driverObject,
                                 sizeof(XENV4V_EXTENSION),
                                 &deviceName,
                                 FILE_DEVICE_UNKNOWN,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &sddlString,
                                 (LPCGUID)&GUID_SD_XENV4V_CONTROL_OBJECT,
                                 &fdo);
        if (!NT_SUCCESS(status)) {
            TraceError(("failed to create device object - error: 0x%x\n", status));
            fdo = NULL;
            break;
        }

        pde = (PXENV4V_EXTENSION)fdo->DeviceExtension;
        RtlZeroMemory(pde, sizeof(XENV4V_EXTENSION));
        RtlStringCchCopyW(pde->symbolicLinkText, XENV4V_SYM_NAME_LEN, V4V_SYMBOLIC_NAME);
        RtlInitUnicodeString(&pde->symbolicLink, pde->symbolicLinkText);

        // Create our symbolic link
        status = IoCreateSymbolicLink(&pde->symbolicLink, &deviceName);
        if (!NT_SUCCESS(status)) {
            TraceError(("failed to create symbolic - error: 0x%x\n", status));
            break;
        }
        symlink = TRUE;       

        // Get our xenstore path
        szFpath = xenbus_find_frontend(pdo);
        if (szFpath == NULL) {
            status = STATUS_NO_SUCH_DEVICE;
            TraceError(("failed to locate XenStore front end path\n"));
            break;
        }

        // Setup the extension
        pde->magic = XENV4V_MAGIC;
        pde->pdo = pdo;
        pde->fdo = fdo;
        IoInitializeRemoveLock(&pde->removeLock, 'v4vx', 0, 0);
        pde->frontendPath = szFpath;
        szFpath = NULL;
        pde->state = XENV4V_DEV_STOPPED; // wait for start
        pde->lastPoState = PowerSystemWorking;
        pde->virqPort = null_EVTCHN_PORT();
        KeInitializeDpc(&pde->virqDpc, V4vVirqNotifyDpc, fdo);
        KeInitializeSpinLock(&pde->virqLock);
        KeInitializeSpinLock(&pde->dpcLock);
        KeInitializeTimerEx(&pde->timer, NotificationTimer);
        KeInitializeDpc(&pde->timerDpc,
                        V4vConnectTimerDpc,
                        fdo);
        KeInitializeSpinLock(&pde->timerLock);
        pde->timerCounter = 0;
        InitializeListHead(&pde->contextList);
        KeInitializeSpinLock(&pde->contextLock);
        pde->contextCount = 0;
        InitializeListHead(&pde->ringList);
        KeInitializeSpinLock(&pde->ringLock);
        InitializeListHead(&pde->pendingIrpQueue);
        pde->pendingIrpCount = 0;
        KeInitializeSpinLock(&pde->queueLock);
        IoCsqInitializeEx(&pde->csqObject,
                          V4vCsqInsertIrpEx,
                          V4vCsqRemoveIrp,
                          V4vCsqPeekNextIrp,
                          V4vCsqAcquireLock,
                          V4vCsqReleaseLock,
                          V4vCsqCompleteCanceledIrp);
        InitializeListHead(&pde->destList);
        pde->destCount = 0;
        ExInitializeNPagedLookasideList(&pde->destLookasideList,
                                        NULL,
                                        NULL,
                                        0,
                                        sizeof(XENV4V_DESTINATION),
                                        XENV4V_TAG,
                                        0);
        KeQueryTickCount(&seed);
        pde->seed = seed.u.LowPart;

        // Now attach us to the stack
        pde->ldo = IoAttachDeviceToDeviceStack(fdo, pdo);
        if (pde->ldo == NULL) {
            TraceError(("failed to attach device to stack - error: 0x%x\n", status));
            status = STATUS_NO_SUCH_DEVICE;
            break;
        }

        // Use direct IO and let the IO manager directly map user buffers; clear the init flag
        fdo->Flags |= DO_DIRECT_IO;
        fdo->Flags &= ~DO_DEVICE_INITIALIZING;        

        // Made it here, go to connected state to be consistent
        xenbus_change_state(XBT_NIL, pde->frontendPath, "state", XENBUS_STATE_CONNECTED);
    } while (FALSE);

    if (!NT_SUCCESS(status)) {
        if (fdo != NULL) {         
            if ((pde != NULL)&&(pde->ldo != NULL)) {
                IoDetachDevice(pde->ldo);
            }
            if (szFpath != NULL) {
                XmFreeMemory(szFpath);
            }
            if (symlink) {
                IoDeleteSymbolicLink(&pde->symbolicLink);
            }
            IoDeleteDevice(fdo);
        }
    }

    TraceVerbose(("<==== '%s'.\n", __FUNCTION__));

    return status;
}
Esempio n. 12
0
NTSTATUS DriverEntry(
	IN  PDRIVER_OBJECT  driverObject,
	IN  PUNICODE_STRING registryPath)
{
	NTSTATUS status = STATUS_SUCCESS;
	NTSTATUS symbolicLinkCreationStatus = STATUS_SUCCESS;
	UNICODE_STRING deviceName;
	UNICODE_STRING dosDeviceName;
	HANDLE threadHandle;
	NET_BUFFER_LIST_POOL_PARAMETERS nblPoolParams = {0};
	UNICODE_STRING defaultSDDLString;

#ifdef DEBUG
	DbgBreakPoint();
#endif

	status = drvCtlInit(driverObject);

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

	gDriverUnloading = FALSE;

	RtlInitUnicodeString(&defaultSDDLString, L"D:P(A;;GA;;;BU)");
	RtlInitUnicodeString(&deviceName, DEVICE_NAME);

	status = IoCreateDeviceSecure(
		driverObject, 
		0,
		&deviceName, 
		FILE_DEVICE_NETWORK, 
		0, 
		FALSE, 
		&defaultSDDLString,
		NULL,
		&gDeviceObject);

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

	RtlInitUnicodeString(&dosDeviceName, SYMBOLIC_LINK_NAME);

	status = IoCreateSymbolicLink(&dosDeviceName, &deviceName);
	symbolicLinkCreationStatus = status;

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

	status = FwpsInjectionHandleCreate0(
		AF_UNSPEC,
		FWPS_INJECTION_TYPE_STREAM,
		&gInjectionHandle);

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

	gNdisGenericObj = NdisAllocateGenericObject(
			driverObject, 
			TAG_NDIS_OBJ,
			0);

	if (gNdisGenericObj == NULL)
	{
		status = STATUS_NO_MEMORY;
		goto Exit;
	}

	nblPoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
	nblPoolParams.Header.Revision = 
		NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
	nblPoolParams.Header.Size = 
		NDIS_SIZEOF_NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;

	nblPoolParams.fAllocateNetBuffer = TRUE;
	nblPoolParams.DataSize = 0;

	nblPoolParams.PoolTag = TAG_NBL_POOL;

	gNetBufferListPool = NdisAllocateNetBufferListPool(
                        gNdisGenericObj,
                        &nblPoolParams);

	if(gNetBufferListPool == NULL)
	{
		status = STATUS_NO_MEMORY;
		goto Exit;
	}

	InitializeListHead(&gPacketQueue);
	KeInitializeSpinLock(&gPacketQueueLock);  

	InitializeListHead(&flowContextList);
	KeInitializeSpinLock(&flowContextListLock);

	KeInitializeEvent(
		&gWorkerEvent,
		NotificationEvent,
		FALSE
	);
	
	status = RegisterCallouts(gDeviceObject);

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

	status = PsCreateSystemThread(
			&threadHandle,
			THREAD_ALL_ACCESS,
			NULL,
			NULL,
			NULL,
			thAnalyzer,
			NULL);

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

	status = ObReferenceObjectByHandle(
		threadHandle,
		0,
		NULL,
		KernelMode,
		(PVOID*) &gThreadObj,
		NULL);

	ASSERT(NT_SUCCESS(status));
	
	KeSetBasePriorityThread(
		(PKTHREAD) gThreadObj,
		-2);

	ZwClose(threadHandle);

	driverObject->DriverUnload = DriverUnload;

Exit:
   
	if (!NT_SUCCESS(status))
	{
		if (gFwpmEngineHandle != NULL)
		{
			UnregisterCallouts();
		}

		if (gInjectionHandle != NULL)
		{
			FwpsInjectionHandleDestroy0(gInjectionHandle);
		}

		if (gDeviceObject)
		{
			IoDeleteDevice(gDeviceObject);
		}

		if(NT_SUCCESS(symbolicLinkCreationStatus))
		{
			IoDeleteSymbolicLink(&dosDeviceName);
		}

		if (gNetBufferListPool != NULL)
		{
			NdisFreeNetBufferListPool(gNetBufferListPool);
		}
			
		if (gNdisGenericObj != NULL)
		{
			NdisFreeGenericObject(gNdisGenericObj);
		}
	}

return status;
}
Esempio n. 13
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;
}