smbmrxnp.c

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

C
1,729
字号
        if (EntryFound)
        {
            PWCHAR  pUserName;
            PWCHAR  pPassword;
            PSMBMRX_CONNECTINFO ConnectInfo;
            UNICODE_STRING ConnectionName;
            ULONG TransferBytes;

            DbgP((TEXT("NPCancelConnection: Connection Found:\n")));

            ConnectionName.Length        = pNetResource->ConnectionNameLength;
            ConnectionName.MaximumLength = ConnectionName.Length;
            ConnectionName.Buffer        = pNetResource->ConnectionName;
            pUserName                    = pNetResource->UserName;
            pPassword                    = pNetResource->Password;

            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_DELCONN,
                                        ConnectInfo,
                                        MAX_CONNECT_INFO_SIZE,
                                        NULL,
                                        &TransferBytes );
                LocalFree( ConnectInfo );
            }
            else
            {
                Status = WN_OUT_OF_MEMORY;
            }

            DbgP((TEXT("NPCancelConnection: SendToMiniRdr returned Status %lx\n"),Status));

            if ( bLocalName )
            {
                if (DefineDosDevice(DDD_REMOVE_DEFINITION | DDD_RAW_TARGET_PATH | DDD_EXACT_MATCH_ON_REMOVE,
                                    lpName,
                                    pNetResource->ConnectionName) == FALSE)
                {
                    DbgP((TEXT("RemoveDosDevice:  DefineDosDevice error: %d\n"), GetLastError()));
                    Status = GetLastError();
                }
                else
                {
                    pNetResource->InUse = FALSE;

                    if (Index == pSharedMemory->HighestIndexInUse)
                    {
                        pSharedMemory->HighestIndexInUse      -= 1;
                        pSharedMemory->NumberOfResourcesInUse -= 1;
                    }
                }
            }
        }

        CloseSharedMemory( &hMutex,
                           &hMemory,
                          (PVOID)&pSharedMemory);
    }

    return Status;
}


DWORD APIENTRY
NPGetConnection(
    LPWSTR  lpLocalName,
    LPWSTR  lpRemoteName,
    LPDWORD lpBufferSize )
/*++

Routine Description:

    This routine returns the information associated with a connection

Arguments:

    lpLocalName - local name associated with the connection

    lpRemoteName - the remote name associated with the connection

    lpBufferSize - the remote name buffer size

Return Value:

    WN_SUCCESS if successful, otherwise the appropriate error

Notes:

--*/
{
    DWORD   Status = 0;

    UNICODE_STRING Name;

    HANDLE  hMutex, hMemory;
    PSMBMRXNP_SHARED_MEMORY  pSharedMemory;

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

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

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

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

            if (pNetResource->InUse)
            {
                UNICODE_STRING EntryName;

                EntryName.MaximumLength = pNetResource->LocalNameLength;
                EntryName.Length        = EntryName.MaximumLength;
                EntryName.Buffer        = pNetResource->LocalName;

                if (Name.Length == EntryName.Length)
                {
                    if ( wcsncmp( Name.Buffer, EntryName.Buffer, Name.Length/sizeof(WCHAR)) == 0 )
                    {
                        EntryFound = TRUE;
                        break;
                    }
                }
            }
        }

        if (EntryFound)
        {
            if (*lpBufferSize < pNetResource->RemoteNameLength)
            {
                *lpBufferSize = pNetResource->RemoteNameLength;
                Status = ERROR_BUFFER_OVERFLOW;
            }
            else
            {
                *lpBufferSize = pNetResource->RemoteNameLength;
                CopyMemory( lpRemoteName,
                            pNetResource->RemoteName,
                            pNetResource->RemoteNameLength);
                Status = WN_SUCCESS;
            }
        }
        else
        {
            Status = ERROR_NO_NET_OR_BAD_PATH;
        }

        CloseSharedMemory( &hMutex, &hMemory, (PVOID)&pSharedMemory);
    }

    return Status;
}


DWORD APIENTRY
NPGetResourceParent(
    LPNETRESOURCE   lpNetResource,
    LPVOID  lpBuffer,
    LPDWORD lpBufferSize )
/*++

Routine Description:

    This routine returns the parent of a given resource

Arguments:

    lpNetResource - the NETRESOURCE struct

    lpBuffer - the buffer for passing back the parent information

    lpBufferSize - the buffer size

Return Value:

    WN_NOT_SUPPORTED

Notes:

    The current sample does not handle this call.

--*/
{
    return WN_NOT_SUPPORTED;
}

DWORD APIENTRY
NPGetResourceInformation(
    LPNETRESOURCE   lpNetResource,
    LPVOID  lpBuffer,
    LPDWORD lpBufferSize,
    LPWSTR  *lplpSystem )
/*++

Routine Description:

    This routine returns the information associated net resource

Arguments:

    lpNetResource - the NETRESOURCE struct

    lpBuffer - the buffer for passing back the parent information

    lpBufferSize - the buffer size

    lplpSystem -

Return Value:

Notes:

--*/
{
    DWORD dwStatus = 0;
    LPNETRESOURCE   pOutNetResource;
    DbgP((TEXT("NPGetResourceInformation\n")));

    return dwStatus;
}


DWORD APIENTRY
NPGetUniversalName(
    LPCWSTR lpLocalPath,
    DWORD   dwInfoLevel,
    LPVOID  lpBuffer,
    LPDWORD lpBufferSize )
/*++

Routine Description:

    This routine returns the information associated net resource

Arguments:

    lpLocalPath - the local path name

    dwInfoLevel  - the desired info level

    lpBuffer - the buffer for the univeral name

    lpBufferSize - the buffer size

Return Value:

    WN_SUCCESS if successful

Notes:

--*/
{
    DWORD   dwStatus;

    DWORD   BufferRequired      = 0;
    DWORD   UniversalNameLength = 0;
    DWORD   RemoteNameLength    = 0;
    DWORD   RemainingPathLength = 0;

    LPWSTR  pDriveLetter,
            pRemainingPath,
            SourceStrings[3];

    WCHAR   RemoteName[MAX_PATH],
            LocalPath[MAX_PATH],
            UniversalName[MAX_PATH],
            ReplacedChar;

    DbgP((TEXT("NPGetUniversalName: lpLocalPath: %S  InfoLevel: %d\n"), lpLocalPath, dwInfoLevel));

    if (dwInfoLevel != UNIVERSAL_NAME_INFO_LEVEL &&
        dwInfoLevel != REMOTE_NAME_INFO_LEVEL)
    {
        DbgP((TEXT("NPGetUniversalName:  bad dwInfoLevel value: %d\n"), dwInfoLevel));
        return WN_BAD_LEVEL;
    }

    lstrcpynW(LocalPath, lpLocalPath, MAX_PATH);

    pDriveLetter = LocalPath;
    if (pRemainingPath = wcschr(pDriveLetter, L':'))
    {
        ReplacedChar = *(++pRemainingPath);
        *pRemainingPath = L'\0';

    }


    RemoteNameLength = MAX_PATH;
    if ((dwStatus = NPGetConnection(pDriveLetter, RemoteName, &RemoteNameLength)) != WN_SUCCESS)
    {
        DbgP((TEXT("NPGetUniversalName:  NPGetConnection return dwStatus: %d\n"), dwStatus));
        return dwStatus;
    }

    if (pRemainingPath)
    {
        *pRemainingPath = ReplacedChar;
    }

    DbgP((TEXT("NPGetUniversalName: pRemainingPath: %S  RemoteName: %S\n"), pRemainingPath, RemoteName));

    lstrcpynW(UniversalName, RemoteName, MAX_PATH);

    if (pRemainingPath)
    {
        wcsncat(UniversalName, pRemainingPath, MAX_PATH - RemoteNameLength/sizeof(WCHAR) - 1);
        UniversalName[MAX_PATH-1] = L'\0';
    }

    DbgP((TEXT("NPGetUniversalName: UniversalName: %S\n"), UniversalName));

    // Determine if the provided buffer is large enough.
    UniversalNameLength = (wcslen(UniversalName) + 1) * sizeof(WCHAR);
    BufferRequired = UniversalNameLength;

    if (dwInfoLevel == UNIVERSAL_NAME_INFO_LEVEL)
    {
        BufferRequired += sizeof(UNIVERSAL_NAME_INFO);
    }
    else
    {
        RemoteNameLength = (wcslen(RemoteName) + 1) * sizeof(WCHAR);
        BufferRequired += sizeof(REMOTE_NAME_INFO) + RemoteNameLength;
        if (pRemainingPath)
        {
            RemainingPathLength = (wcslen(pRemainingPath) + 1) * sizeof(WCHAR);
            BufferRequired += RemainingPathLength;
        }
    }

    if (*lpBufferSize < BufferRequired)
    {
        DbgP((TEXT("NPGetUniversalName: WN_MORE_DATA BufferRequired: %d\n"), BufferRequired));
        *lpBufferSize = BufferRequired;
        return WN_MORE_DATA;
    }

    if (dwInfoLevel == UNIVERSAL_NAME_INFO_LEVEL)
    {
        LPUNIVERSAL_NAME_INFOW pUniversalNameInfo;

        pUniversalNameInfo = (LPUNIVERSAL_NAME_INFOW)lpBuffer;

        pUniversalNameInfo->lpUniversalName = (PWCHAR)((PBYTE)lpBuffer + sizeof(UNIVERSAL_NAME_INFOW));

        CopyMemory( pUniversalNameInfo->lpUniversalName,
                    UniversalName,
                    UniversalNameLength);
    }
    else
    {
        LPREMOTE_NAME_INFOW pRemoteNameInfo;

        pRemoteNameInfo = (LPREMOTE_NAME_INFOW)lpBuffer;

        pRemoteNameInfo->lpUniversalName  = (PWCHAR)((PBYTE)lpBuffer + sizeof(REMOTE_NAME_INFOW));
        pRemoteNameInfo->lpConnectionName = pRemoteNameInfo->lpUniversalName + UniversalNameLength;
        pRemoteNameInfo->lpRemainingPath  = pRemoteNameInfo->lpConnectionName + RemoteNameLength;

        CopyMemory( pRemoteNameInfo->lpUniversalName,
                    UniversalName,
                    UniversalNameLength);

        CopyMemory( pRemoteNameInfo->lpConnectionName,
                    RemoteName,
                    RemoteNameLength);

        CopyMemory( pRemoteNameInfo->lpRemainingPath,
                    pRemainingPath,
                    RemainingPathLength);
    }

    DbgP((TEXT("NPGetUniversalName: WN_SUCCESS\n")));

    return WN_SUCCESS;
}


int _cdecl _vsnwprintf( wchar_t *buffer, size_t count, wchar_t *format, va_list arg_ptr);

// Format and write debug information to OutputDebugString
ULONG
_cdecl
DbgPrint(
    LPTSTR Format,
    ...
    )
{   
    ULONG rc = 0;
    TCHAR szbuffer[256];

    va_list marker;
    va_start( marker, Format );
    {
         rc = _vsnwprintf( szbuffer, 254, Format, marker );
         szbuffer[255] = (TCHAR)0;
         OutputDebugString( TRACE_TAG );
         OutputDebugString( szbuffer );
    }

    return rc;
}

⌨️ 快捷键说明

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