static
BOOLEAN
TestZwLoad(
    IN PDRIVER_OBJECT DriverObject,
    IN PCUNICODE_STRING DriverRegistryPath,
    IN PWCHAR NewDriverRegPath)
{
    UNICODE_STRING RegPath;
    NTSTATUS Status;

    /* Try to load ourself */
    Status = ZwLoadDriver((PUNICODE_STRING)DriverRegistryPath);
    ok (Status == STATUS_IMAGE_ALREADY_LOADED, "Expected NTSTATUS STATUS_IMAGE_ALREADY_LOADED, got 0x%lX\n", Status);

    if (Status != STATUS_IMAGE_ALREADY_LOADED)
    {
        DbgPrint("WARNING: Loading this a second time will cause BUGCHECK!\n");
    }

    /* Try to load with a Registry Path that doesnt exist */
    RtlInitUnicodeString(&RegPath, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\deadbeef");
    Status = ZwLoadDriver(&RegPath);
    ok (Status == STATUS_OBJECT_NAME_NOT_FOUND, "Expected NTSTATUS STATUS_OBJECT_NAME_NOT_FOUND, got 0x%lX\n", Status);

    /* Load the driver */
    RtlInitUnicodeString(&RegPath, NewDriverRegPath);
    Status = ZwLoadDriver(&RegPath);
    ok(Status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got 0x%lX\n", Status);

    return NT_SUCCESS(Status);
}
Exemple #2
0
NTSTATUS
NTAPI
FsRecLoadFileSystem(IN PDEVICE_OBJECT DeviceObject,
                    IN PWCHAR DriverServiceName)
{
    UNICODE_STRING DriverName;
    PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
    NTSTATUS Status = STATUS_IMAGE_ALREADY_LOADED;
    PAGED_CODE();

    /* Make sure we haven't already been called */
    if (DeviceExtension->State != Loaded)
    {
        /* Acquire the load lock */
        KeWaitForSingleObject(FsRecLoadSync,
                              Executive,
                              KernelMode,
                              FALSE,
                              NULL);
        KeEnterCriticalRegion();

        /* Make sure we're active */
        if (DeviceExtension->State == Pending)
        {
            /* Load the FS driver */
            RtlInitUnicodeString(&DriverName, DriverServiceName);
            Status = ZwLoadDriver(&DriverName);

            /* Loop all the linked recognizer objects */
            while (DeviceExtension->State != Unloading)
            {
                /* Set them to the unload state */
                DeviceExtension->State = Unloading;

                /* Go to the next one */
                DeviceObject = DeviceExtension->Alternate;
                DeviceExtension = DeviceObject->DeviceExtension;
            }
        }

        /* Make sure that we haven't already loaded the FS */
        if (DeviceExtension->State != Loaded)
        {
            /* Unregiser us, and set us as loaded */
            IoUnregisterFileSystem(DeviceObject);
            DeviceExtension->State = Loaded;
        }

        /* Release the lock */
        KeSetEvent(FsRecLoadSync, 0, FALSE);
        KeLeaveCriticalRegion();
    }

    /* Return */
    return Status;
}
Exemple #3
0
int main()
{
	GetDrvCopyBits ();

	if (!DrvCopyBits)
		return 0;

	if(!EnableLoadDriverPrivilege())
		return printf("Could not enable SeLoadDriverPrivilege\n");


	char DriverPath [MAX_PATH];

	GetSystemDirectory (DriverPath, MAX_PATH-1);
	lstrcat (DriverPath, "\\drivers\\ngvid.sys");

	if(!CopyFile ("ngvid.sys", DriverPath, FALSE))
		return printf("Cannot copy driver file\n");

	SC_HANDLE hManager = OpenSCManager (0, 0, SC_MANAGER_CONNECT|SC_MANAGER_CREATE_SERVICE);
	if (!hManager)
		return printf("Cannot open SC manager\n");

	SC_HANDLE hService = CreateService (hManager, "ngvid2", "ngvid2", SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER,
		SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, DriverPath, 0, 0, 0, 0, 0);

	CloseServiceHandle (hService);
	CloseServiceHandle (hManager);

	HKEY hk;
	if(RegCreateKeyEx (HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\ngvid2\\Parameters", 0, 0, 
		0, KEY_SET_VALUE, 0, &hk, 0))
		return 0;

	if (RegSetValueEx (hk, "DrvCopyBits", 0, REG_DWORD, (PBYTE)&DrvCopyBits, 4))
		return 0;

	if (RegSetValueEx (hk, "pTblDrvCopyBits", 0, REG_DWORD, (PBYTE)&pTblDrvCopyBits, 4))
		return 0;

	RegCloseKey (hk);
	

	UNICODE_STRING Path;
	NTSTATUS st;

	RtlInitUnicodeString (&Path, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\ngvid2");

	st = ZwLoadDriver (&Path);

	if (!NT_SUCCESS(st) && st != STATUS_IMAGE_ALREADY_LOADED)
		return printf("ZwLoadDriver failed with status %X\n", st);


	return 0;
}
Exemple #4
0
NTSTATUS
FsRtlRegisterUncProvider(
    __inout PHANDLE MupHandle,
    __in PUNICODE_STRING RedirDevName,
    __in BOOLEAN MailslotsSupported
    )
/*++

Routine Description:

    This routine registers a redir as a UNC provider.

Arguments:

    Handle - Pointer to a handle.  The handle is returned by the routine
        to be used when calling FsRtlDeregisterUncProvider.
        It is valid only if the routines returns STATUS_SUCCESS.

    RedirDevName - The device name of the redir.

    MailslotsSupported - If TRUE, this redir supports mailslots.

Return Value:

    NTSTATUS - The status of the operation.

--*/
{
    NTSTATUS status;
    HANDLE mupHandle = (HANDLE)-1;
    UNICODE_STRING mupDriverName;
    BOOLEAN dfsEnabled;

    PAGED_CODE();

    KeWaitForSingleObject(&FsRtlpUncSemaphore, Executive, KernelMode, FALSE, NULL );

    if (FsRtlpRedirs == 0) {

        dfsEnabled = FsRtlpIsDfsEnabled();

        if (dfsEnabled) {
            FsRtlpRedirs = 1;
            RtlZeroMemory((PVOID) &FsRtlpDRD, sizeof(FsRtlpDRD));
        }

    }

    switch( FsRtlpRedirs ) {
    case 0:
        //
        // Ok, the MUP isn't there and we don't need to use the
        //   MUP for the first redir.
        //
        // We need to return a handle, but we're not really using the MUP yet.
        //   And we may never use it (if there's only 1 redir).  Return
        //   a handle to the NULL device object, since we're committed to returning
        //   a handle to our caller.  Our caller isn't supposed to do anything with
        //   the handle except to call FsRtlDeregisterUncProvider() with it.
        //
        status = FsRtlpOpenDev( &mupHandle, DevNull );

        if( !NT_SUCCESS( status ) )
            break;

        //
        // Save up enough state to allow us to call the MUP later with
        // this registration info if necessary.
        //
        FsRtlpDRD.RedirDevName.Buffer = ExAllocatePoolWithTag( NonPagedPool, 
                                                               RedirDevName->MaximumLength, 
                                                               MODULE_POOL_TAG );

        if( FsRtlpDRD.RedirDevName.Buffer == NULL ) {
            status =  STATUS_INSUFFICIENT_RESOURCES;
            break;
        }

        FsRtlpDRD.RedirDevName.Length = RedirDevName->Length;
        FsRtlpDRD.RedirDevName.MaximumLength = RedirDevName->MaximumLength;

        RtlCopyMemory(
                (PCHAR)FsRtlpDRD.RedirDevName.Buffer,
                RedirDevName->Buffer,
                RedirDevName->MaximumLength
        );

        FsRtlpDRD.MailslotsSupported = MailslotsSupported;
        FsRtlpDRD.ReturnedHandle = mupHandle;
        FsRtlpDRD.MupHandle = (HANDLE)-1;

        //
        // Set the UNC symbolic link to point to the redir we just loaded
        //
        FsRtlpSetSymbolicLink( RedirDevName );

        break;

    default:
        //
        // This is the second or later redir load -- MUST use the MUP
        //
        status = FsRtlpOpenDev( &mupHandle, DevMup );

        if( !NT_SUCCESS( status ) ) {

            RtlInitUnicodeString( &mupDriverName, MupRegKey );

            (VOID)ZwLoadDriver( &mupDriverName );

            status = FsRtlpOpenDev( &mupHandle, DevMup );
            if( !NT_SUCCESS( status ) )
                break;
        }

        //
        // See if we need to tell the MUP about the first redir that registered
        //
        if( FsRtlpDRD.RedirDevName.Buffer ) {

            status = FsRtlpRegisterProviderWithMUP( mupHandle,
                    &FsRtlpDRD.RedirDevName,
                    FsRtlpDRD.MailslotsSupported );

            if( !NT_SUCCESS( status ) )
                break;

            FsRtlpDRD.MupHandle = mupHandle;

            ExFreePool( FsRtlpDRD.RedirDevName.Buffer );
            FsRtlpDRD.RedirDevName.Buffer = NULL;

            //
            // Set the UNC symbolic link to point to the MUP
            //
            RtlInitUnicodeString(  &mupDriverName, DevMup );
            FsRtlpSetSymbolicLink( &mupDriverName );

            status = FsRtlpOpenDev( &mupHandle, DevMup );

            if( !NT_SUCCESS( status ) )
                break;
        }

        //
        //  Pass the request to the MUP for this redir
        //
        status = FsRtlpRegisterProviderWithMUP( mupHandle,
                        RedirDevName,
                        MailslotsSupported );
        break;

    }

    if( NT_SUCCESS( status ) ) {
        FsRtlpRedirs++;
        *MupHandle = mupHandle;

    } else {
        if( mupHandle != (HANDLE)-1 && mupHandle != NULL ) {
            ZwClose( mupHandle );
        }

        *MupHandle = (HANDLE)-1;
    }

    KeReleaseSemaphore(&FsRtlpUncSemaphore, 0, 1, FALSE );
    return status;
}
Exemple #5
0
VOID
NtfsLoadAddOns (
    IN PDRIVER_OBJECT DriverObject,
    IN PVOID Context,
    IN ULONG Count
    )

/*++

Routine Description:

    This routine attempts to load any NTFS add-ons and notify them about
    any previously mounted volumes.

Arguments:

    DriverObject - Driver object for NTFS

    Context - Unused, required by I/O system.

    Count - Unused, required by I/O system.

Return Value:

    None.

--*/

{
    NTSTATUS Status;
    UNICODE_STRING UnicodeString;
    ULONG i;
    WCHAR Buffer[80];

    TOP_LEVEL_CONTEXT TopLevelContext;
    PTOP_LEVEL_CONTEXT ThreadTopLevelContext;

    IRP_CONTEXT LocalIrpContext;
    IRP LocalIrp;

    PIRP_CONTEXT IrpContext;

    PLIST_ENTRY Links;
    PVCB Vcb;

    PVCB VcbForTearDown = NULL;
    BOOLEAN AcquiredGlobal = FALSE;

    PAGED_CODE();

    UNREFERENCED_PARAMETER(Context);
    UNREFERENCED_PARAMETER(Count);
    UNREFERENCED_PARAMETER(DriverObject);

    //
    // For each add-on try to load it.
    //

    for (i = 0; NtfsAddonNames[i] != NULL; i++) {

        wcscpy(Buffer, NTFS_SERVICE_KEY);
        wcscat(Buffer, NtfsAddonNames[i]);

        RtlInitUnicodeString( &UnicodeString, Buffer);

        Status = ZwLoadDriver( &UnicodeString );

#if DBG
        DbgPrint("NtfsLoadAddOns: Loaded module %ws. Status = 0x%lx\n", Buffer, Status);
#endif

    }

    RtlZeroMemory( &LocalIrpContext, sizeof(LocalIrpContext) );
    RtlZeroMemory( &LocalIrp, sizeof(LocalIrp) );

    IrpContext = &LocalIrpContext;
    IrpContext->NodeTypeCode = NTFS_NTC_IRP_CONTEXT;
    IrpContext->NodeByteSize = sizeof(IRP_CONTEXT);
    IrpContext->OriginatingIrp = &LocalIrp;
    SetFlag(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT);
    InitializeListHead( &IrpContext->ExclusiveFcbList );

    //
    //  Make sure we don't get any pop-ups
    //

    ThreadTopLevelContext = NtfsSetTopLevelIrp( &TopLevelContext, TRUE, FALSE );
    ASSERT( ThreadTopLevelContext == &TopLevelContext );

    (VOID) ExAcquireResourceShared( &NtfsData.Resource, TRUE );
    AcquiredGlobal = TRUE;

    __try {

        NtfsUpdateIrpContextWithTopLevel( IrpContext, ThreadTopLevelContext );

        __try {

            for (Links = NtfsData.VcbQueue.Flink;
                 Links != &NtfsData.VcbQueue;
                 Links = Links->Flink) {

                Vcb = CONTAINING_RECORD(Links, VCB, VcbLinks);

                IrpContext->Vcb = Vcb;

                if (FlagOn( Vcb->VcbState, VCB_STATE_VOLUME_MOUNTED )) {

                    Status = CiMountVolume( Vcb, IrpContext);

                    // Bugbug: What should we do if this fails?
                    // BugBug: add call out for views.

                    NtfsCommitCurrentTransaction( IrpContext );

                }
            }

        } __except(NtfsExceptionFilter( IrpContext, GetExceptionInformation() )) {

            NOTHING;
        }

    } __finally {

        if (AcquiredGlobal) {
            ExReleaseResource( &NtfsData.Resource );
        }

        NtfsRestoreTopLevelIrp( ThreadTopLevelContext );
    }

    //
    //  And return to our caller
    //

    return;

}
Exemple #6
0
/*++
 * @name FsRtlRegisterUncProvider
 * @implemented
 *
 * FILLME
 *
 * @param Handle
 *        FILLME
 *
 * @param RedirectorDeviceName
 *        FILLME
 *
 * @param MailslotsSupported
 *        FILLME
 *
 * @return None
 *
 * @remarks None
 *
 *--*/
NTSTATUS
NTAPI
FsRtlRegisterUncProvider(OUT PHANDLE Handle,
                         IN PCUNICODE_STRING RedirectorDeviceName,
                         IN BOOLEAN MailslotsSupported)
{
    NTSTATUS Status;
    HANDLE DeviceHandle;
    UNICODE_STRING MupString;

    PAGED_CODE();

    DPRINT1("FsRtlRegisterUncProvider(%p, %wZ, %u)\n", Handle, RedirectorDeviceName, MailslotsSupported);

    KeWaitForSingleObject(&FsRtlpUncSemaphore, Executive, KernelMode, FALSE, NULL);

    /* In case no provider was registered yet, check for DFS present.
     * If DFS is present, we need to go with MUP, whatever the case
     */
    if (FsRtlpRedirs == 0)
    {
        if (FsRtlpIsDfsEnabled())
        {
            DPRINT1("DFS is not disabled. Going through MUP\n");

            /* We've to go with MUP, make sure our internal structure doesn't
             * contain any leftover data and raise redirs to one, to make sure
             * we use MUP.
             */
            RtlZeroMemory(&FsRtlpDRD, sizeof(FsRtlpDRD));
            FsRtlpRedirs = 1;
        }
    }

    /* In case no UNC provider was already registered,
     * We'll proceed without MUP and directly redirect
     * UNC to the provider.
     */
    if (FsRtlpRedirs == 0)
    {
        /* As we don't provide MUP, just give a handle to NULL device */
        Status = FsRtlpOpenDev(&DeviceHandle, L"\\Device\\Null");
        if (!NT_SUCCESS(Status))
        {
            goto Cleanup;
        }

        /* Allocate a buffer big enough to keep a local copy of UNC provider device */
        FsRtlpDRD.RedirectorDeviceName.Buffer = ExAllocatePoolWithTag(NonPagedPool, RedirectorDeviceName->MaximumLength, TAG_UNC);
        if (FsRtlpDRD.RedirectorDeviceName.Buffer == NULL)
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            goto Cleanup;
        }

        FsRtlpDRD.RedirectorDeviceName.Length = RedirectorDeviceName->Length;
        FsRtlpDRD.RedirectorDeviceName.MaximumLength = RedirectorDeviceName->MaximumLength;
        RtlCopyMemory(FsRtlpDRD.RedirectorDeviceName.Buffer, RedirectorDeviceName->Buffer, RedirectorDeviceName->MaximumLength);

        /* We don't have MUP, and copy provider information */
        FsRtlpDRD.MupHandle = INVALID_HANDLE_VALUE;
        FsRtlpDRD.MailslotsSupported = MailslotsSupported;
        FsRtlpDRD.NullHandle = DeviceHandle;

        /* Set DOS device UNC to use provider device */
        FsRtlpSetSymbolicLink(RedirectorDeviceName);
    }
    else
    {
        /* We (will) have several providers, MUP is required */
        Status = FsRtlpOpenDev(&DeviceHandle, L"\\Device\\Mup");
        if (!NT_SUCCESS(Status))
        {
            /* Opening MUP may have failed because the driver was not loaded, so load it and retry */
            RtlInitUnicodeString(&MupString, L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Mup");
            ZwLoadDriver(&MupString);
            Status = FsRtlpOpenDev(&DeviceHandle, L"\\Device\\Mup");
            if (!NT_SUCCESS(Status))
            {
                goto Cleanup;
            }
        }

        /* In case we had a single provider till now, we have to forward the old provider to MUP
         * And then, register the new one to MUP as well
         */
        if (FsRtlpDRD.RedirectorDeviceName.Buffer != NULL)
        {
            /* We will only continue if we can register previous provider in MUP */
            Status = FsRtlpRegisterProviderWithMUP(DeviceHandle, &FsRtlpDRD.RedirectorDeviceName, FsRtlpDRD.MailslotsSupported);
            if (!NT_SUCCESS(Status))
            {
                goto Cleanup;
            }

            /* Save our Mup handle for later usage */
            FsRtlpDRD.MupHandle = DeviceHandle;

            /* Release information about previous provider */
            ExFreePoolWithTag(FsRtlpDRD.RedirectorDeviceName.Buffer, TAG_UNC);
            FsRtlpDRD.RedirectorDeviceName.Buffer = NULL;

            /* Re-open MUP to have a handle to give back to the user */
            Status = FsRtlpOpenDev(&DeviceHandle, L"\\Device\\Mup");
            if (!NT_SUCCESS(Status))
            {
                goto Cleanup;
            }
        }

        /* Redirect UNC DOS device to MUP */
        RtlInitUnicodeString(&MupString, L"\\Device\\Mup");
        FsRtlpSetSymbolicLink(&MupString);

        /* Register new provider */
        Status = FsRtlpRegisterProviderWithMUP(DeviceHandle, RedirectorDeviceName, MailslotsSupported);
    }

Cleanup:

    /* In case of success, increment number of providers and return handle
     * to the device pointed by UNC DOS device
     */
    if (NT_SUCCESS(Status))
    {
        ++FsRtlpRedirs;
        *Handle = DeviceHandle;
    }
    else
    {
        /* Cleanup in case of failure */
        if (DeviceHandle != INVALID_HANDLE_VALUE && DeviceHandle != 0)
        {
            ZwClose(DeviceHandle);
        }

        *Handle = INVALID_HANDLE_VALUE;
    }

    KeReleaseSemaphore(&FsRtlpUncSemaphore, IO_NO_INCREMENT, 1, FALSE);
    return Status;
}
Exemple #7
0
NTSTATUS
AFSLoadLibrary( IN ULONG Flags,
                IN UNICODE_STRING *ServicePath)
{
    UNREFERENCED_PARAMETER(Flags);

    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSDeviceExt       *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    UNICODE_STRING uniLibraryName;
    AFSDeviceExt *pLibDevExt = NULL;
    PFILE_OBJECT pLibraryFileObject = NULL;
    PDEVICE_OBJECT pLibraryDeviceObject = NULL;

    __Enter
    {

        //
        // Wait on the load library event so we don't race with any
        // other requests coming through
        //

        AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Start load library\n",
                      __FUNCTION__));

        ntStatus = KeWaitForSingleObject( &pDevExt->Specific.Control.LoadLibraryEvent,
                                          Executive,
                                          KernelMode,
                                          FALSE,
                                          NULL);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSLoadLibrary Wait for LoadLibraryEvent failure %08lX\n",
                          ntStatus));

            try_return( ntStatus);
        }

        //
        // Check our current state to ensure we currently do not have a library loaded
        //

        if( BooleanFlagOn( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s Library already loaded\n",
                          __FUNCTION__));

            try_return( ntStatus = STATUS_DEVICE_NOT_READY);
        }

        pDevExt->Specific.Control.LibraryServicePath.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
                                                                                                 ServicePath->Length,
                                                                                                 AFS_GENERIC_MEMORY_25_TAG);

        if( pDevExt->Specific.Control.LibraryServicePath.Buffer == NULL)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSLoadLibrary AFS_GENERIC_MEMORY_25_TAG allocation error\n"));

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        RtlZeroMemory( pDevExt->Specific.Control.LibraryServicePath.Buffer,
                       ServicePath->Length);

        pDevExt->Specific.Control.LibraryServicePath.Length = ServicePath->Length;
        pDevExt->Specific.Control.LibraryServicePath.MaximumLength = pDevExt->Specific.Control.LibraryServicePath.Length;

        RtlCopyMemory( pDevExt->Specific.Control.LibraryServicePath.Buffer,
                       ServicePath->Buffer,
                       pDevExt->Specific.Control.LibraryServicePath.Length);

        //
        // Load the library
        //

        ntStatus = ZwLoadDriver( ServicePath);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to load library Status %08lX\n",
                          __FUNCTION__,
                          ntStatus));

            try_return( ntStatus);
        }

        //
        // Open up the control device and grab teh entry points for the library
        //

        RtlInitUnicodeString( &uniLibraryName,
                              AFS_LIBRARY_CONTROL_DEVICE_NAME);

        ntStatus = IoGetDeviceObjectPointer( &uniLibraryName,
                                             FILE_ALL_ACCESS,
                                             &pLibraryFileObject,
                                             &pLibraryDeviceObject);

        if( !NT_SUCCESS( ntStatus))
        {
            AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "AFSLoadLibrary IoGetDeviceObjectPointer failure %08lX\n",
                          ntStatus));

            try_return( ntStatus);
        }

        //
        // We have our reference to the library device object. Grab the
        // device extension and setup our callbacks
        //

        pLibDevExt = (AFSDeviceExt *)pLibraryDeviceObject->DeviceExtension;

        //
        // Save off our references
        //

        pDevExt->Specific.Control.LibraryFileObject = pLibraryFileObject;

        pDevExt->Specific.Control.LibraryDeviceObject = pLibraryDeviceObject;

        //
        // Reset the state for our library
        //

        AFSAcquireExcl( &pDevExt->Specific.Control.LibraryStateLock,
                        TRUE);

        SetFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED);

        ClearFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_QUEUE_CANCELLED);

        AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Completed load library, processing queued requests\n",
                      __FUNCTION__));

        AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock);

        //
        // Process the queued requests
        //

        AFSProcessQueuedResults( FALSE);

try_exit:

        AFSDbgTrace(( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Library load complete Status %08lX\n",
                      __FUNCTION__,
                      ntStatus));

        if( !NT_SUCCESS( ntStatus))
        {

            if( pDevExt->Specific.Control.LibraryServicePath.Buffer != NULL)
            {

                ZwUnloadDriver( &pDevExt->Specific.Control.LibraryServicePath);

                ExFreePool( pDevExt->Specific.Control.LibraryServicePath.Buffer);

                pDevExt->Specific.Control.LibraryServicePath.Buffer = NULL;
                pDevExt->Specific.Control.LibraryServicePath.Length = 0;
                pDevExt->Specific.Control.LibraryServicePath.MaximumLength = 0;
            }
        }

        KeSetEvent( &pDevExt->Specific.Control.LoadLibraryEvent,
                    0,
                    FALSE);
    }

    return ntStatus;
}