smbmrxnp.c

来自「winddk src目录下的文件系统驱动源码压缩!」· C语言 代码 · 共 1,729 行 · 第 1/4 页

C
1,729
字号
    lpUserName - the user name

    dwFlags - flags for the connection

Return Value:

    WN_SUCCESS if successful, otherwise the appropriate error

Notes:

    The current sample does not handle explicitly passesd in credentials. Normally
    the credential information is passed in as EA parameters to the associated
    mini redirector for further manipulation

--*/
{
    DWORD   Status = 0;

    UNICODE_STRING      ConnectionName;

    PWCHAR  pLocalName,pRemoteName;
    USHORT  LocalNameLength,RemoteNameLength;
    HANDLE  hConnection;
    ULONG   TransferBytes;
    WCHAR   NullStr[] = L"\0\0";
    PWCHAR  pUserName;
    PWCHAR  pPassword;
    PWKSTA_USER_INFO_0  WkStaUserInfo;
    PSMBMRX_CONNECTINFO ConnectInfo;
    

    DbgP((TEXT("NPAddConnection3: Incoming UserName - %s, Password - %s\n"),
                lpUserName, lpPassword ));

    // if no user specified, get the current logged on user
    if ( lpUserName == NULL )
    {
        Status = NetWkstaUserGetInfo( NULL, 0, (PBYTE *)&WkStaUserInfo );
        if ( Status == ERROR_SUCCESS )
        {
            pUserName = WkStaUserInfo->wkui0_username;
        }
        else
        {
            pUserName = NullStr;
        }
    }
    else
    {
        pUserName = lpUserName;
    }

    if ( lpPassword == NULL )
    {
        pPassword = NullStr;    // use default password
        pPassword[1] = '\0';    // reset empty flag
    }
    else if ( *lpPassword == L'\0' )
    {
        pPassword = NullStr;
        pPassword[1] = '1';     // flag the password as "Empty"
    }
    else
    {
        pPassword = lpPassword;
    }
    Status = ERROR_SUCCESS;

    DbgP((TEXT("NPAddConnection3: Outgoing UserName - %s, Password - %s\n"),
                lpUserName, lpPassword ));

    // The SMB mini supports only DISK type resources. The other resources
    // are not supported.

    if ((lpNetResource->lpRemoteName == NULL) ||
        (lpNetResource->lpRemoteName[0] != L'\\') ||
        (lpNetResource->lpRemoteName[1] != L'\\') ||
        (lpNetResource->dwType != RESOURCETYPE_DISK))
    {
        return WN_BAD_NETNAME;
    }

    //
    // The remote name is in the UNC format \\Server\Share.  This name
    // needs to be translated to an appropriate NT name in order to
    // issue the request to the underlying mini redirector to create the
    // connection.
    //
    // The NT style name is of the form
    //
    //  \device\smbminiredirector\;<DriveLetter>:\Server\Share
    //
    // The additional ; is required by the new RDR for extensibility.
    //

    pLocalName  = lpNetResource->lpLocalName;
    pRemoteName = lpNetResource->lpRemoteName;

    // skip past the first back slash since the name to be appended for the
    // NT name does not require this.
    pRemoteName++;

    if (pLocalName != NULL) {
        LocalNameLength = wcslen(pLocalName) * sizeof(WCHAR);
    } else {
        LocalNameLength = 0;
    }

    RemoteNameLength = (wcslen(pRemoteName) - 1) * sizeof(WCHAR);

    ConnectionName.MaximumLength = (USHORT)(SmbMRxDeviceName.Length +
                                   (USHORT)RemoteNameLength +
                                   ((pLocalName != NULL)
                                   ? (LocalNameLength + sizeof(WCHAR)) : 0) + // space for ;
                                   sizeof(WCHAR));

    ConnectionName.Length = ConnectionName.MaximumLength;

    ConnectionName.Buffer = LocalAlloc( LMEM_ZEROINIT,
                                        ConnectionName.Length + sizeof(WCHAR));

    if (ConnectionName.Buffer == NULL)
    {
        return GetLastError();
    }

    // Copy the name into the buffer

    CopyMemory( ConnectionName.Buffer,
                SmbMRxDeviceName.Buffer,
                SmbMRxDeviceName.Length);

    wcscat(ConnectionName.Buffer, L"\\");
    wcscat(ConnectionName.Buffer, L";");
    if (pLocalName != NULL)
    {
        wcscat(ConnectionName.Buffer, pLocalName);
    }

    wcscat(ConnectionName.Buffer, pRemoteName);

    ConnectInfo = (PSMBMRX_CONNECTINFO) LocalAlloc( LMEM_ZEROINIT, MAX_CONNECT_INFO_SIZE );
    if ( ConnectInfo )
    {
        ConnectInfo->ConnectionNameOffset = 0;
        ConnectInfo->ConnectionNameLength = ConnectionName.Length;
        CopyMemory( ConnectInfo->InfoArea, ConnectionName.Buffer, ConnectionName.Length );

        ConnectInfo->EaDataOffset = ConnectInfo->ConnectionNameOffset +
                                    ConnectInfo->ConnectionNameLength;
        // check for the "no password" flag
        if ( pPassword[0] == L'\0' && pPassword[1] == L'1' )
        {
            pPassword = NULL;
        }
        ConnectInfo->EaDataLength = FillInEaBuffer( pUserName,
                                                    pPassword,
                                                    (PBYTE) ConnectInfo->InfoArea +
                                                    ConnectInfo->EaDataOffset );
        TransferBytes = 0;

        Status = SendToMiniRdr( IOCTL_SMBMRX_ADDCONN,
                                ConnectInfo,
                                MAX_CONNECT_INFO_SIZE,
                                NULL,
                                &TransferBytes );
        LocalFree( ConnectInfo );
    }
    else
    {
        Status = WN_OUT_OF_MEMORY;
    }

    if ((Status == WN_SUCCESS) && (pLocalName != NULL))
    {
        WCHAR TempBuf[64];

        if (!QueryDosDeviceW(
                pLocalName,
                TempBuf,
                64))
        {
            if (GetLastError() != ERROR_FILE_NOT_FOUND)
            {
                //
                // Most likely failure occurred because our output
                // buffer is too small.  It still means someone already
                // has an existing symbolic link for this device.
                //

                Status = ERROR_ALREADY_ASSIGNED;
            }
            else
            {
                //
                // ERROR_FILE_NOT_FOUND (translated from OBJECT_NAME_NOT_FOUND)
                // means it does not exist and we can redirect this device.
                //
                // Create a symbolic link object to the device we are redirecting
                //
                if (!DefineDosDeviceW(
                        DDD_RAW_TARGET_PATH |
                        DDD_NO_BROADCAST_SYSTEM,
                        pLocalName,
                        ConnectionName.Buffer))
                {
                    Status = GetLastError();
                }
                else
                {
                    Status = WN_SUCCESS;
                }
            }
        }
        else
        {
            //
            // QueryDosDevice successfully an existing symbolic link--
            // somebody is already using this device.
            //
            Status = ERROR_ALREADY_ASSIGNED;
        }
    }
    else
    {
        DbgP((TEXT("SendToMiniRdr returned %lx\n"),Status));
    }

    if (Status == WN_SUCCESS)
    {
        INT     Index;
        HANDLE  hMutex, hMemory;
        BOOLEAN FreeEntryFound = FALSE;

        PSMBMRXNP_SHARED_MEMORY  pSharedMemory;

        // The connection was established and the local device mapping
        // added. Include this in the list of mapped devices.

        Status = OpenSharedMemory(
                    &hMutex,
                    &hMemory,
                    (PVOID)&pSharedMemory);

        if (Status == WN_SUCCESS)
        {
            DbgP((TEXT("NPAddConnection3: Highest Index %d Number Of resources %d\n"),
                        pSharedMemory->HighestIndexInUse,pSharedMemory->NumberOfResourcesInUse));

            Index = 0;

            while (Index < pSharedMemory->HighestIndexInUse)
            {
                if (!pSharedMemory->NetResources[Index].InUse)
                {
                    FreeEntryFound = TRUE;
                    break;
                }

                Index++;
            }

            if (!FreeEntryFound &&
                (pSharedMemory->HighestIndexInUse < SMBMRXNP_MAX_DEVICES))
            {
                pSharedMemory->HighestIndexInUse += 1;
                Index = pSharedMemory->HighestIndexInUse;
                FreeEntryFound = TRUE;
            }

            if (FreeEntryFound)
            {
                PSMBMRXNP_NETRESOURCE pSmbMrxNetResource;

                pSharedMemory->NumberOfResourcesInUse += 1;

                pSmbMrxNetResource = &pSharedMemory->NetResources[Index];

                pSmbMrxNetResource->InUse                = TRUE;
                pSmbMrxNetResource->dwScope              = lpNetResource->dwScope;
                pSmbMrxNetResource->dwType               = lpNetResource->dwType;
                pSmbMrxNetResource->dwDisplayType        = lpNetResource->dwDisplayType;
                pSmbMrxNetResource->dwUsage              = RESOURCEUSAGE_CONNECTABLE;
                pSmbMrxNetResource->LocalNameLength      = LocalNameLength;
                pSmbMrxNetResource->RemoteNameLength     = wcslen(lpNetResource->lpRemoteName) * sizeof(WCHAR);
                pSmbMrxNetResource->ConnectionNameLength = ConnectionName.Length;

                // Copy the local name
                CopyMemory( pSmbMrxNetResource->LocalName,
                            lpNetResource->lpLocalName,
                            pSmbMrxNetResource->LocalNameLength);

                // Copy the remote name
                CopyMemory( pSmbMrxNetResource->RemoteName,
                            lpNetResource->lpRemoteName,
                            pSmbMrxNetResource->RemoteNameLength);

                // Copy the connection name
                CopyMemory( pSmbMrxNetResource->ConnectionName,
                            ConnectionName.Buffer,
                            pSmbMrxNetResource->ConnectionNameLength);


                //
                // Copy the Auth info
                //
                // WARNING : security hole using shared memory..Developers must use alternate methods to maintain use table.
                //

                lstrcpyn( pSmbMrxNetResource->UserName, pUserName, MAX_PATH);
                if ( *pPassword )
                {
                    lstrcpyn( pSmbMrxNetResource->Password, pPassword, MAX_PATH);
                }
                else
                {
                    CopyMemory( pSmbMrxNetResource->Password, pPassword, 3 * sizeof(WCHAR) );
                }
            }
            else
            {
                Status = WN_NO_MORE_DEVICES;
            }

            CloseSharedMemory( &hMutex,
                               &hMemory,
                               (PVOID)&pSharedMemory);
        }
        else
        {
            DbgP((TEXT("NpAddConnection3: OpenSharedMemory returned %lx\n"),Status));
        }
    }

    return Status;
}


DWORD APIENTRY
NPCancelConnection(
    LPWSTR  lpName,
    BOOL    fForce )
/*++

Routine Description:

    This routine cancels ( deletes ) a connection from the list of connections
    associated with this network provider

Arguments:

    lpName - name of the connection

    fForce - forcefully delete the connection

Return Value:

    WN_SUCCESS if successful, otherwise the appropriate error

Notes:

--*/

{
    BOOL    bLocalName = TRUE;
    DWORD   Status = 0;

    UNICODE_STRING Name;

    HANDLE  hMutex, hMemory;
    PSMBMRXNP_SHARED_MEMORY  pSharedMemory;

    if (*lpName == L'\\' && *(lpName + 1) == L'\\')
    {
        bLocalName = FALSE;
    }

    DbgP((TEXT("NPCancelConnection\n")));
    DbgP((TEXT("NPCancelConnection: ConnectionName: %S\n"), lpName));

    Name.MaximumLength = Name.Length = wcslen(lpName) * sizeof(WCHAR);
    Name.Buffer = lpName;

    Status = OpenSharedMemory( &hMutex,
                               &hMemory,
                               (PVOID)&pSharedMemory);

    if (Status == WN_SUCCESS)
    {
        INT  Index;
        BOOL EntryFound = FALSE;
        PSMBMRXNP_NETRESOURCE pNetResource;

        DbgP((TEXT("NPCancelConnection: Highest Index %d Number Of resources %d\n"),
                    pSharedMemory->HighestIndexInUse,pSharedMemory->NumberOfResourcesInUse));

        for (Index = 0; Index <= pSharedMemory->HighestIndexInUse; Index++)
        {
            pNetResource = &pSharedMemory->NetResources[Index];

            if (pNetResource->InUse)
            {
                UNICODE_STRING EntryName;

                if (bLocalName)
                {
                    EntryName.MaximumLength = pNetResource->LocalNameLength;
                    EntryName.Length        = EntryName.MaximumLength;
                    EntryName.Buffer        = pNetResource->LocalName;
                }
                else
                {
                    EntryName.MaximumLength = pNetResource->RemoteNameLength;
                    EntryName.Length        = EntryName.MaximumLength;
                    EntryName.Buffer        = pNetResource->RemoteName;
                }

                DbgP((TEXT("NPCancelConnection: Name %S EntryName %S\n"),
                            lpName,EntryName.Buffer));
                DbgP((TEXT("NPCancelConnection: Name Length %d Entry Name Length %d\n"),
                           Name.Length,EntryName.Length));

                if (Name.Length == EntryName.Length)
                {
                    if ( _wcsnicmp(Name.Buffer, EntryName.Buffer, Name.Length) == 0 )
                    {
                        EntryFound = TRUE;
                        break;
                    }
                }
            }
        }

⌨️ 快捷键说明

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