示例#1
0
文件: unc.c 项目: GYGit/reactos
/*++
 * @name FsRtlDeregisterUncProvider
 * @implemented
 *
 * FILLME
 *
 * @param Handle
 *        FILLME
 *
 * @return None
 *
 * @remarks None
 *
 *--*/
VOID
NTAPI
FsRtlDeregisterUncProvider(IN HANDLE Handle)
{
    PAGED_CODE();

    /* We won't work on invalid input */
    if (Handle == INVALID_HANDLE_VALUE || Handle == 0)
    {
        return;
    }

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

    /* Sanity check: we need to have providers */
    ASSERT(FsRtlpRedirs > 0);

    /* At that point, we had only one provider at a time */
    if (Handle == (HANDLE)FsRtlpDRD.NullHandle)
    {
        /* Free its name if possible (it might have been overtaken in case of
         * registration of other UNC provider */
        if (FsRtlpDRD.RedirectorDeviceName.Buffer != NULL)
        {
            ExFreePoolWithTag(FsRtlpDRD.RedirectorDeviceName.Buffer, TAG_UNC);
            FsRtlpDRD.RedirectorDeviceName.Buffer = NULL;
        }

        /* Close the handle to MUP */
        if (FsRtlpDRD.MupHandle != INVALID_HANDLE_VALUE)
        {
            ZwClose(FsRtlpDRD.MupHandle);
            FsRtlpDRD.MupHandle = INVALID_HANDLE_VALUE;
        }

        /* Last handle isn't required anymore */
        FsRtlpDRD.NullHandle = INVALID_HANDLE_VALUE;
    }

    /* One less provider */
    --FsRtlpRedirs;

    /* In case we reach no provider anylonger, reset the symbolic link */
    if (FsRtlpRedirs == 0)
    {
        FsRtlpSetSymbolicLink(NULL);
    }

    KeReleaseSemaphore(&FsRtlpUncSemaphore, IO_NO_INCREMENT, 1, FALSE);

    /* Final note:
     * NULL device handle and 'normal' MUP device handle are not closed by
     * FsRtl. It's up to the user to close them afterwards.
     * If the handle is leaked, MUP will never be notified about the
     * unregistration.
     */
}
示例#2
0
文件: unc.c 项目: BaoYu0721/WRK-1.2
VOID
FsRtlDeregisterUncProvider(
    __in HANDLE Handle
    )

/*++

Routine Description:

    This routine deregisters a redir as a UNC provider.

Arguments:

    Handle - A handle to the Multiple UNC router, returned by the
        registration call.

Return Value:

    None.

--*/

{
    NTSTATUS status;

    PAGED_CODE();

    if( Handle == (HANDLE)-1 || Handle == NULL )
        return;

    status = ZwClose( Handle );

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

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

    ASSERT( FsRtlpRedirs > 0 );

    if( Handle == FsRtlpDRD.ReturnedHandle ) {

        //
        // The first redir in the system is closing.  Release the state we saved
        //  for it, and pass the close on to the MUP if necessary
        //

        if( FsRtlpDRD.RedirDevName.Buffer != NULL ) {
            ExFreePool( FsRtlpDRD.RedirDevName.Buffer );
            FsRtlpDRD.RedirDevName.Buffer = NULL;
        }

        if( FsRtlpDRD.MupHandle != (HANDLE)-1 ) {
            ZwClose( FsRtlpDRD.MupHandle );
            FsRtlpDRD.MupHandle = (HANDLE)-1;
        }

        FsRtlpDRD.ReturnedHandle = (HANDLE)-1;

    }

    if( --FsRtlpRedirs == 0 ) {
        FsRtlpSetSymbolicLink( (PUNICODE_STRING)NULL );
    }

    KeReleaseSemaphore(&FsRtlpUncSemaphore, 0, 1, FALSE );
}
示例#3
0
文件: unc.c 项目: BaoYu0721/WRK-1.2
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;
}
示例#4
0
文件: unc.c 项目: GYGit/reactos
/*++
 * @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;
}