⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 namelookup.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 4 页
字号:

        //
        //  Set the DosName to the empty string
        //

        nlExtHeader->DosName.Length = 0;

        return;
    }

    ASSERT( nlExtHeader->StorageStackDeviceObject != NULL );

    //
    //  Get the DOS device name
    //

    status = RtlVolumeDeviceToDosName( nlExtHeader->StorageStackDeviceObject,
                                       &nlExtHeader->DosName);

    if (!NT_SUCCESS( status )) {

        //
        //  We couldn't get the DOS device name. Set the string to empty
        //

        nlExtHeader->DosName.Length = 0;

    }

    ObDereferenceObject( Context->DeviceObject );
    ExFreePoolWithTag( Context, NL_POOL_TAG );

    return;

}


/////////////////////////////////////////////////////////////////////////////
//
//  Name lookup device extension header functions.
//
/////////////////////////////////////////////////////////////////////////////

VOID
NLInitDeviceExtensionHeader (
    IN PNL_DEVICE_EXTENSION_HEADER NLExtHeader,
    IN PDEVICE_OBJECT ThisDeviceObject,
    IN PDEVICE_OBJECT StorageStackDeviceObject
    )
/*++

Routine Description:

    This routine initializes the fields of a NL_DEVICE_EXTENSION_HEADER.  All
    pointer fields are set to NULL, and unicode strings are initialized as
    empty.  Use NLCleanupDeviceExtensionHeader to clean up a
    NL_DEVICE_EXTENSION_HEADER.

    NLExtHeader must *not* be NULL.

Arguments:

    NLExtHeader - The name lookup extension header to initialize.

    ThisDeviceObject - Device Object that this device extension is attached to

Return Value:

    Pointer to the allocated and initialized name control.
    If allocation fails, this function returns NULL.

--*/
{
    ASSERT(NLExtHeader != NULL);

    NLExtHeader->AttachedToDeviceObject = NULL;
    NLExtHeader->ThisDeviceObject = ThisDeviceObject;
    NLExtHeader->StorageStackDeviceObject = StorageStackDeviceObject;

    RtlInitEmptyUnicodeString( &NLExtHeader->DeviceName, NULL, 0 );
    RtlInitEmptyUnicodeString( &NLExtHeader->DosName, NULL, 0 );
}

VOID
NLCleanupDeviceExtensionHeader (
    PNL_DEVICE_EXTENSION_HEADER NLExtHeader
    )
/*++

Routine Description:

    This routine frees any memory associated with the given name lookup
    extension header.  This may include the DosName unicode string and buffer,
    and the DeviceName.

Arguments:

    NLExtHeader - The name lookup extension header to clean up.

Return Value:

    None

--*/
{
    if (NLExtHeader->DosName.Buffer != NULL) {

        ExFreePool( NLExtHeader->DosName.Buffer );
    }

    if (NLExtHeader->DeviceName.Buffer != NULL) {

        ExFreePool( NLExtHeader->DeviceName.Buffer );
    }
}


/////////////////////////////////////////////////////////////////////////////
//
//  General support routines
//
/////////////////////////////////////////////////////////////////////////////

NTSTATUS
NLAllocateAndCopyUnicodeString (
    IN OUT PUNICODE_STRING DestName,
    IN PUNICODE_STRING SrcName,
    IN ULONG PoolTag
    )
/*++

Routine Description:

    This routine will allocate a buffer big enough to hold the unicode string
    in SrcName, copy the name, and properly setup DestName

Arguments:

    DestName - the unicode string we are copying too

    SrcName - the unicode string we are copying from

Return Value:

    STATUS_SUCCESS - if it worked
    STATUS_INSUFFICIENT_RESOURCE - if we could not allocate pool

--*/
{
    USHORT bufSize;
    PVOID buf;

    ASSERT(DestName->Buffer == NULL);

    bufSize = SrcName->Length;

    if (bufSize > 0) {

        buf = ExAllocatePoolWithTag( NonPagedPool,
                                     bufSize,
                                     PoolTag );

        if (buf == NULL) {

            RtlInitEmptyUnicodeString( DestName, NULL, bufSize );
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        RtlInitEmptyUnicodeString( DestName, buf, bufSize );
        RtlCopyUnicodeString( DestName, SrcName );

    } else {

        RtlInitEmptyUnicodeString( DestName, NULL, bufSize );
    }

    return STATUS_SUCCESS;
}



/////////////////////////////////////////////////////////////////////////////
//
//  Routines to support generic name control structures that allow us
//  to get names of arbitrary size.
//
/////////////////////////////////////////////////////////////////////////////

NTSTATUS
NLAllocateNameControl (
    OUT PNAME_CONTROL *NameControl,
    IN PPAGED_LOOKASIDE_LIST LookasideList
    )
/*++

Routine Description:

    This routine allocates a name control from LookasideList, initializes it,
    and returns a pointer to it.  If allocation fails, NULL is returned.
    Use NLFreeNameControl to free a name control received from this routine.

Arguments:

    LookasideList - The lookaside list to allocate the name control from.

Return Value:

    Pointer to the allocated and initialized name control.
    If allocation fails, this function returns NULL.

--*/
{
    PNAME_CONTROL nameCtrl = NULL;

    nameCtrl = ExAllocateFromPagedLookasideList( LookasideList );

    if (nameCtrl == NULL) {

        *NameControl = NULL;
        return STATUS_INSUFFICIENT_RESOURCES;

    }

    NLInitNameControl( nameCtrl );

    *NameControl = nameCtrl;

    return STATUS_SUCCESS;
}

VOID
NLFreeNameControl (
    IN PNAME_CONTROL NameControl,
    IN PPAGED_LOOKASIDE_LIST LookasideList
    )
/*++

Routine Description:

    This routine frees a name control received from NLAllocateNameControl.  It
    cleans up the name control, including any larger buffer allocations, and
    then frees the name control back to LookasideList.  If NameControl is NULL,
    this function does nothing.

Arguments:

    NameControl - The name control release.
    LookasideList - The lookaside list that this name control was initially
        allocated from.

Return Value:

    None.

--*/
{
    if (NameControl != NULL) {

        NLCleanupNameControl( NameControl );
        ExFreeToPagedLookasideList( LookasideList, NameControl );
    }
}

NTSTATUS
NLCheckAndGrowNameControl (
    IN OUT PNAME_CONTROL NameCtrl,
    IN USHORT NewSize
    )
/*++

Routine Description:

    This routine will check the name control's current buffer capacity.  If
    it is less than NewSize, a new larger name buffer will be allocated and put
    into the name control structure.  If there is already an allocated buffer it
    will be freed.  It will also copy any name information from the old buffer
    into the new buffer.

Arguments:

    NameCtrl - The name control we need a bigger buffer for
    NewSize - Size of the new buffer

Return Value:

    Returns STATUS_INSUFFICIENT_RESOURCES if a larger buffer cannot be
    allocated.

--*/
{
    if (NewSize > (NameCtrl->BufferSize - sizeof(WCHAR))) {

        return NLReallocNameControl( NameCtrl,
                                     (NewSize + sizeof(WCHAR)),
                                     NULL );

    }

    return STATUS_SUCCESS;
}

VOID
NLInitNameControl (
    IN PNAME_CONTROL NameCtrl
    )
/*++

Routine Description:

    This will initialize the name control structure.  Use NLCleanupNameControl
    when you are done with it.

    Use NLAllocateNameControl and NLFreeNameControl if you need to
    allocate & initialize / cleanup & deallocate a name control in one step.

Arguments:

    NameCtrl - The name control to initialize.

Return Value:

    None

--*/
{
    PAGED_CODE();

    NameCtrl->AllocatedBuffer = NULL;
    NameCtrl->BufferSize = sizeof( NameCtrl->SmallBuffer );
    RtlInitEmptyUnicodeString( &NameCtrl->Name,
                               (PWCHAR)NameCtrl->SmallBuffer,
                               (USHORT)NameCtrl->BufferSize );
}

VOID
NLCleanupNameControl (
    IN PNAME_CONTROL NameCtrl
    )
/*++

Routine Description:

    This will cleanup the name control structure, freeing any buffers
    that were allocated for the NameCtrl.

    Use NLAllocateNameControl and NLFreeNameControl if you need to
    allocate & initialize / cleanup & deallocate a name control in one step.

Arguments:

    NameCtrl - The NAME_CONTROL structure to cleanup.

Return Value:

    None

--*/
{
    PAGED_CODE();

    if (NULL != NameCtrl->AllocatedBuffer) {

        ExFreePoolWithTag( NameCtrl->AllocatedBuffer, NL_POOL_TAG );
        NameCtrl->AllocatedBuffer = NULL;
    }
}

NTSTATUS
NLReallocNameControl (
    IN PNAME_CONTROL NameCtrl,
    IN ULONG NewSize,
    OUT PWCHAR *RetOriginalBuffer OPTIONAL
    )
/*++

Routine Description:

    This routine will allocate a new larger name buffer and put it into the
    NameControl structure.  If there is already an allocated buffer it will
    be freed.  It will also copy any name information from the old buffer
    into the new buffer.

Arguments:

    NameCtrl - the name control we need a bigger buffer for
    NewSize - size of the new buffer
    RetOrignalBuffer - if defined, receives the buffer that we were
        going to free.  if NULL was returned no buffer needed to be freed.
      WARNING:  if this parameter is defined and a non-null value is returned
        then the caller MUST free this memory else the memory will be lost.

Return Value:

    Returns STATUS_INSUFFICIENT_RESOURCES if a larger buffer cannot be
    allocated.

--*/
{
    PUCHAR newBuffer;

    PAGED_CODE();

    ASSERT( NewSize > NameCtrl->BufferSize);

    //
    //  Flag no buffer to return yet
    //

    if (RetOriginalBuffer) {

        *RetOriginalBuffer = NULL;
    }

    //
    //  Allocate the new buffer
    //

    newBuffer = ExAllocatePoolWithTag( PagedPool, NewSize, NL_POOL_TAG );

    if (NULL == newBuffer) {

        return STATUS_INSUFFICIENT_RESOURCES;
    }

    //
    //  Copy data from old buffer if there is any, including any stream
    //  name component.
    //

    if (NameCtrl->Name.Length > 0) {

        ASSERT( NewSize > (USHORT)NameCtrl->Name.Length);
        RtlCopyMemory( newBuffer,
                       NameCtrl->Name.Buffer,
                       NameCtrl->Name.Length );
    }

    //
    //  If we had an old buffer free it if the caller doesn't want
    //  it passed back to him.  This is done because there are
    //  cases where the caller has a pointer into the old buffer so
    //  it can't be freed yet.  The caller must free this memory.
    //

    if (NULL != NameCtrl->AllocatedBuffer) {

        if (RetOriginalBuffer) {

            *RetOriginalBuffer = (PWCHAR)NameCtrl->AllocatedBuffer;

        } else {

            ExFreePoolWithTag( NameCtrl->AllocatedBuffer, NL_POOL_TAG );
        }
    }

    //
    //  Set the new buffer into the name control
    //

    NameCtrl->AllocatedBuffer = newBuffer;
    NameCtrl->BufferSize = NewSize;

    NameCtrl->Name.Buffer = (PWCHAR)newBuffer;
    NameCtrl->Name.MaximumLength = (USHORT)min( 0xfff0, NewSize );

    return STATUS_SUCCESS;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -