Получаем 'Имя клиента' из сеанса пользователя

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
alexnn
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 31.07.2014 (Чт) 16:05

Получаем 'Имя клиента' из сеанса пользователя

Сообщение alexnn » 31.07.2014 (Чт) 17:04

Можно ли получить 'Имя клиента' в сеансе пользователя в Windows?
Требуется не имя пользователя (его мы получаем с помощью GetUserName), а Имя клиента и, желательно, Имя сеанса (см. прикрепленный файл).

Необходимо для того, чтобы вести лог программы, размещённой на сервере, сохраняя информацию о именах компьютеров, с которых осуществлялось подключение к серверу.
Вложения
screen.jpg
скриншот
screen.jpg (126.42 Кб) Просмотров: 2190

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получаем 'Имя клиента' из сеанса пользователя

Сообщение Хакер » 01.08.2014 (Пт) 3:20

Код: Выделить всё
Option Explicit

Private Declare _
    Function WTSQuerySessionInformation _
    Lib "Wtsapi32" _
    Alias "WTSQuerySessionInformationW" _
    ( _
        ByVal hServer As Long, _
        ByVal SessionId As Long, _
        ByVal WTSInfoClass As WTS_INFO_CLASS, _
        ByRef ppBuffer As Long, _
        ByRef pBytesReturned As Long _
    ) As Long

Private Declare _
    Sub WTSFreeMemory _
    Lib "Wtsapi32" _
    ( _
        ByVal pMem As Long _
    )
   
Private Declare _
    Sub RtlMoveMemory _
    Lib "kernel32" _
    ( _
        pDst As Any, _
        pSrc As Any, _
        ByVal nBytes As Long _
    )
   
Private Enum WTS_INFO_CLASS
    TSInitialProgram
    WTSApplicationName
    WTSWorkingDirectory
    WTSOEMId
    WTSSessionId
    WTSUserName
    WTSWinStationName
    WTSDomainName
    WTSConnectState
    WTSClientBuildNumber
    WTSClientName
    WTSClientDirectory
    WTSClientProductId
    WTSClientHardwareId
    WTSClientAddress
    WTSClientDisplay
    WTSClientProtocolType
    WTSIdleTime
    WTSLogonTime
    WTSIncomingBytes
    WTSOutgoingBytes
    WTSIncomingFrames
    WTSOutgoingFrames
    WTSClientInfo
    WTSSessionInfo
    WTSSessionInfoEx
    WTSConfigInfo
    WTSValidationInfo
    WTSSessionAddressV4
    WTSIsRemoteSession
End Enum

Private Const WTS_CURRENT_SERVER_HANDLE As Long = 0
Private Const WTS_CURRENT_SESSION As Long = -1

Private Function tmp_BSTR_from_LPWSTR_bl(ByVal pBuf As Long, ByVal byte_length As Long)
    Dim ret As String
    ret = Space(byte_length / 2)
    RtlMoveMemory ByVal StrPtr(ret), ByVal pBuf, byte_length
    ret = Left$(ret, InStr(1, ret, vbNullChar) - 1)
    tmp_BSTR_from_LPWSTR_bl = ret
End Function

Private Sub Form_Load()
    Dim ret As Long
    Dim pBuf As Long
    Dim nbuf As Long
   
    ret = WTSQuerySessionInformation( _
        WTS_CURRENT_SERVER_HANDLE, _
        WTS_CURRENT_SESSION, _
        WTSClientName, _
        pBuf, _
        nbuf)
       
    If ret = 0 Then
        MsgBox "Error: " + CStr(Err.LastDllError)
        Exit Sub
    End If
   
    Dim client_name As String
    client_name = tmp_BSTR_from_LPWSTR_bl(pBuf, nbuf)
    WTSFreeMemory pBuf
   
    ret = WTSQuerySessionInformation( _
        WTS_CURRENT_SERVER_HANDLE, _
        WTS_CURRENT_SESSION, _
        WTSWinStationName, _
        pBuf, _
        nbuf)
       
    If ret = 0 Then
        MsgBox "Error: " + CStr(Err.LastDllError)
        Exit Sub
    End If
   
    Dim winsta_name As String
    winsta_name = tmp_BSTR_from_LPWSTR_bl(pBuf, nbuf)
    WTSFreeMemory pBuf
   
    MsgBox "Имя клиента: " + CStr(client_name) + ", Сеанс: " + CStr(winsta_name)
End Sub


И вообще, посмотри на WTSQuerySessionInformation и WTS_INFO_CLASS, чтобы узнать, сколько ещё интересного ты можешь получить. Сам же диспетчер, судя по импортам, пользуется чем-то другим, чтобы получить эту информацию. При желании можно узнать, чем.

Функция tmp_BSTR_from_LPWSTR_bl — чисто временная и демонстрационная. В реальном боевом коде нужно использовать объявленную в TLB функцию SysAllocStringLen.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

alexnn
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 31.07.2014 (Чт) 16:05

Re: Получаем 'Имя клиента' из сеанса пользователя

Сообщение alexnn » 01.08.2014 (Пт) 11:56

Огромное спасибо за помощь! Сейчас буду пробовать. :cyclops:

alexnn
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 31.07.2014 (Чт) 16:05

Re: Получаем 'Имя клиента' из сеанса пользователя

Сообщение alexnn » 01.08.2014 (Пт) 19:24

Да, все отлично работает!
Только появился еще один вопрос: WTSClientAddress передаёт внутренний IP адрес компьютера, с которого осуществляется подключение к серверу. Можно ли каким-то образом получить внешний IP-адрес подключившегося компьютера, т.к. от внутреннего толку мало, если подключение идёт из другой сети (он может совпадать с адресом из текущей сети)?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Получаем 'Имя клиента' из сеанса пользователя

Сообщение Хакер » 02.08.2014 (Сб) 4:44

alexnn писал(а):Можно ли каким-то образом получить внешний IP-адрес подключившегося компьютера, т.к. от внутреннего толку мало, если подключение идёт из другой сети (он может совпадать с адресом из текущей сети)?


Пример. Суть IP-сетей в том, что разные сети соединяются с собой в одну огромную сеть с сохранением IP-адресов в пределах всей сети. Понятие «внутренний» и «внешний» появляется только с тех пор, как между сетями вставляется NAT. Это тот случай или нет? Или речь о случаях, когда хосты имеют несколько присвоенных IP-адресов?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

alexnn
Начинающий
Начинающий
 
Сообщения: 9
Зарегистрирован: 31.07.2014 (Чт) 16:05

Re: Получаем 'Имя клиента' из сеанса пользователя

Сообщение alexnn » 02.08.2014 (Сб) 9:41

Да, я и имею ввиду NAT.
Допустим, компьютер из внешней сети подключается к серверу. Сервер в логах подключения видит его внешний адрес, например 82.205.47.xxx , а WTSClientAddress определяет адрес его сетевой карты (локальный, до преобразования NAT), например 192.168.0.25
В документации WTSClientAddress сказано об этом, что она видит только локальный адрес, а не тот, через который на самом деле идёт подключение через NAT.
Вот и вопрос, можно ли каким-то образом получать IP адрес компьютера "внешний", если он подключается к серверу через NAT?


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

    TopList