Определение ip адреса удаленного компьютера в терминальной сессии через win api
Модератор: Дед Пахом
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5078
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 11 раз
- Поблагодарили: 50 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
Это, наверно, надо смотреть в сторону WinStationQueryInformation. Может у кого есть пример работы на кларионе? Или другие способы без вызова внешних скриптов.
C6/C11, ШВС, tps/btrieve.
- Игорь Столяров
- Ветеран движения
- Сообщения: 7867
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 28 раз
- Поблагодарили: 85 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
А через штатные функции Winsock API здесь не получится работать ?
У меня нет терминального сервера для проверки ...
Например как вот здесь: https://attryde.com/clarion/col_tcpip.htm
У меня нет терминального сервера для проверки ...
Например как вот здесь: https://attryde.com/clarion/col_tcpip.htm
Make Clarion Great Again ! 
-
- ✯ Ветеран ✯
- Сообщения: 5119
- Зарегистрирован: 28 Май 2009, 15:54
- Откуда: Москва
- Благодарил (а): 11 раз
- Поблагодарили: 23 раза
Определение ip адреса удаленного компьютера в терминальной сессии через win api
Мы вытаскивали из реестра. Вроде проблем не наблюдали. Правильно ли я понимаю. Рабочая станция, которая вошла через rdp, должна сообщить свой ip-адрес?
We are hard at work… for you. 

- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5078
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 11 раз
- Поблагодарили: 50 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
Да, правильно. Из того, что я успел прочитать, есть 2 адреса. Один, который передает удаленный компьютер, второй реальный адрес, который определяет система при подключении. Винда знает оба. Нужен второй. Смысл в том, чтобы можно на уровне приложения устанавливать разрешение для пользователя входить с определенного ip адреса или блокировать какие-то ip адреса. Обычно для этих целей используют отдельные сторонние продукты, но хотелось бы все иметь в одном флаконе, проще управлять и контролировать.
C6/C11, ШВС, tps/btrieve.
- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5078
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 11 раз
- Поблагодарили: 50 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
В интернете есть такой пример на c. ХЗ, как это в кларионе может выглядеть.
Код: Выделить всё
typedef enum _WINSTATIONINFOCLASS {
// ...
WinStationRemoteAddress = 29,
// ...
} WINSTATIONINFOCLASS;
#define LOGONID_CURRENT ((ULONG)-1)
typedef struct {
unsigned short sin_family;
union {
struct {
USHORT sin_port;
ULONG in_addr;
UCHAR sin_zero[8];
} ipv4;
struct {
USHORT sin6_port;
ULONG sin6_flowinfo;
USHORT sin6_addr[8];
ULONG sin6_scope_id;
} ipv6;
};
} WINSTATIONREMOTEADDRESS,
*PWINSTATIONREMOTEADDRESS;
EXTERN_C
DECLSPEC_IMPORT
BOOLEAN
WINAPI
WinStationQueryInformationW(
_In_opt_ HANDLE hServer,
_In_ ULONG SessionId,
_In_ WINSTATIONINFOCLASS WinStationInformationClass,
_Out_writes_bytes_(WinStationInformationLength) PVOID pWinStationInformation,
_In_ ULONG WinStationInformationLength,
_Out_ PULONG pReturnLength
);
ULONG GetRdpClientAddressFromServerView()
{
ULONG dwError = NOERROR;
ULONG cb;
union {
SOCKADDR sa;
SOCKADDR_IN sa4;
SOCKADDR_IN6 sa6;
};
WINSTATIONREMOTEADDRESS ra;
if (WinStationQueryInformationW(0, LOGONID_CURRENT, WinStationRemoteAddress, &ra, sizeof(ra), &cb))
{
switch (sa.sa_family = ra.sin_family)
{
case AF_INET:
sa4.sin_port = ra.ipv4.sin_port;
sa4.sin_addr.S_un.S_addr = ra.ipv4.in_addr;
RtlZeroMemory(sa4.sin_zero, sizeof(sa4.sin_zero));
cb = sizeof(SOCKADDR_IN);
break;
case AF_INET6:
sa6.sin6_port = ra.ipv6.sin6_port;
sa6.sin6_flowinfo = ra.ipv6.sin6_flowinfo;
memcpy(&sa6.sin6_addr, &ra.ipv6.sin6_addr, sizeof(in6_addr));
sa6.sin6_scope_id = ra.ipv6.sin6_scope_id;
cb = sizeof(SOCKADDR_IN6);
break;
default:
dwError = ERROR_GEN_FAILURE;
}
if (dwError == NOERROR)
{
// assume that WSAStartup already called
// WSADATA wd;
// WSAStartup(WINSOCK_VERSION, &wd);
char AddressString[64];
ULONG dwAddressStringLength = _countof(AddressString);
if (WSAAddressToStringA(&sa, cb, 0, AddressString, &dwAddressStringLength) == NOERROR)
{
DbgPrint("client ip is %s\n", AddressString);
}
else
{
dwError = WSAGetLastError();
}
}
}
else
{
dwError = GetLastError();
}
return dwError;
}
C6/C11, ШВС, tps/btrieve.
- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5078
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 11 раз
- Поблагодарили: 50 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
Решил спросить у DeepSeek, давно была мысль его на перевод с win api попробовать.
Вот что выдал (прототип и пример использования).

Код: Выделить всё
MODULE('USER32')
WinStationQueryInformationW(ULONG, ULONG, WSTRING, ULONG, ULONG),BOOL,RAW,PASCAL,NAME('WinStationQueryInformationW')
END
Код: Выделить всё
LOCAL(infoBuffer AS WSTRING(256))
LOCAL(bufferSize AS ULONG)
LOCAL(result AS BOOL)
bufferSize = SIZEOF(infoBuffer)
result = WinStationQueryInformationW(0, 0, 'WinStationInfo', infoBuffer, bufferSize)
IF result THEN
MESSAGE('Информация успешно получена: ' & infoBuffer)
ELSE
MESSAGE('Ошибка при получении информации')
END
C6/C11, ШВС, tps/btrieve.
- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5078
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 11 раз
- Поблагодарили: 50 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
Пример для получения ip адреса. Правда пишет, что нужны права администратора.
Код: Выделить всё
MODULE('USER32')
WinStationQueryInformationW(ULONG, ULONG, ULONG, *GROUP, ULONG, *ULONG),BOOL,RAW,PASCAL,NAME('WinStationQueryInformationW')
END
WTS_CLIENT_ADDRESS GROUP, TYPE
AddressFamily ULONG
Address BYTE(20)
END
LOCAL(clientAddress AS WTS_CLIENT_ADDRESS)
LOCAL(returnedLength AS ULONG)
LOCAL(result AS BOOL)
! Запрашиваем информацию о клиентском адресе
result = WinStationQueryInformationW(0, 0, 14, ADDRESS(clientAddress), SIZEOF(clientAddress), ADDRESS(returnedLength))
IF result THEN
! Извлекаем IP-адрес из структуры
LOCAL(ipAddress AS STRING(16))
ipAddress = FORMAT(clientAddress.Address[2]) & '.' & FORMAT(clientAddress.Address[3]) & '.' & FORMAT(clientAddress.Address[4]) & '.' & FORMAT(clientAddress.Address[5])
MESSAGE('IP-адрес клиента: ' & ipAddress)
ELSE
MESSAGE('Ошибка при получении IP-адреса клиента')
END
C6/C11, ШВС, tps/btrieve.
- Дед Пахом
- Старичок
- Сообщения: 3267
- Зарегистрирован: 07 Июль 2005, 16:51
- Откуда: Москва, Россия
- Благодарил (а): 15 раз
- Поблагодарили: 48 раз
- Контактная информация:
Определение ip адреса удаленного компьютера в терминальной сессии через win api
А это не смущает?
[WinStationQueryInformationW is not supported and may be altered or unavailable in the future. Instead, use the GetSystemMetrics function with SM_REMOTESESSION to obtain this information (see Detecting the Remote Desktop Services Environment). ]
С уважением, ДП
- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5078
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 11 раз
- Поблагодарили: 50 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
Автор примера написал, что это работает на всех версиях винды. Ему такой же вопрос задали. Потом автор вопроса попробовал, отписался, что все норм.Дед Пахом писал(а): ↑03 Март 2025, 16:37 А это не смущает?[WinStationQueryInformationW is not supported and may be altered or unavailable in the future. Instead, use the GetSystemMetrics function with SM_REMOTESESSION to obtain this information (see Detecting the Remote Desktop Services Environment). ]
DeepSeek, конечно, полную ахинею написал.
C6/C11, ШВС, tps/btrieve.
- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5078
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 11 раз
- Поблагодарили: 50 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
В списке запросов GetSystemMetrics получения адреса не увидел, специально проверил.
C6/C11, ШВС, tps/btrieve.
- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5078
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 11 раз
- Поблагодарили: 50 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
На всякий случай напишу, что утилита GETTSCIP.exe не подходит для этих целей, так как она возвращает адрес компьютера в локальной сети, а не внешний ip адрес компьютера, с которого делается терминальное подключение.
C6/C11, ШВС, tps/btrieve.
- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5078
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 11 раз
- Поблагодарили: 50 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
Подумал, подумал, сделал пока проверку через GETTSCIP.exe. Может, позже что-то получится с определением внешнего ip адреса.
C6/C11, ШВС, tps/btrieve.
- Admin
- Администратор
- Сообщения: 4009
- Зарегистрирован: 05 Июль 2005, 15:59
- Откуда: Хабаровск
- Благодарил (а): 51 раз
- Поблагодарили: 30 раз
- Контактная информация:
Определение ip адреса удаленного компьютера в терминальной сессии через win api
Смысл в том, чтобы можно на уровне приложения устанавливать разрешение для пользователя входить с определенного ip адреса или блокировать какие-то ip адреса.
Обратите внимание что клиент(ы) может сидеть за NAT и в таком случае в получите не совсем верную информацию.
Сторонние продукты м.б. заточены на идентификацию по многим признакам.Обычно для этих целей используют отдельные сторонние продукты, но хотелось бы все иметь в одном флаконе, проще управлять и контролировать.
Рай совершает ошибки ничуть не реже чем ад. Просто у него хорошая пресса
- finsoftrz
- ✯ Ветеран ✯
- Сообщения: 5078
- Зарегистрирован: 06 Ноябрь 2014, 12:48
- Благодарил (а): 11 раз
- Поблагодарили: 50 раз
Определение ip адреса удаленного компьютера в терминальной сессии через win api
Там 2 варианта задачи.
Первый сделать возможным вход в приложение пользователя, подключающегося только с определенного ip адреса. Сейчас я сделал, как написал, через gettscip.exe. Эта утилита возвращает тот ip адрес, который передает на сервер удаленный компьютер. Если она за роутером, то это будет адрес компьютера в локальной сети, то есть что-то типа 192.168.1.88. Внешний ip адрес, с которого происходит подключение к серверу, будет другой. Для первого варианта задачи, в принципе, такой вариант можно использовать, так как внутренний адрес в сети можно согласовать с клиентом.
Второй это запрет или разрешение входа в программу с определенных ip адресов. Для этих целей нужен внешний ip адрес удаленного компьютера, и gettscip.exe не подойдет. В интернете я нашел только информацию с WinStationQueryInformationW, про это как-то очень скудно пишут. Может, есть и еще какие-то варианты. Нужно ли включать в приложение такую проверку, это открытый вопрос, так как эта проверка будет работать после запуска кларионовского приложения, предпочтительнее ее проводить до этого. Для tsplus есть отдельный продукт tsplus advanced security (за отдельную плату), который как раз таким, в том числе, и занимается. По сути, это все держится на достаточно простой настройке, если удастся определить внешний ip адрес.
Другие фишки для входа в приложение у меня есть. Это отключение выбора из списка пользователей и ввод имени пользователя напрямую в окне подключения (как в винде), запрет подключения определенным пользователям в режиме терминального сервера, запрет доступа к файловой системе сервера из приложения, ограничение подключения по часам в течении дня, запрет подключения в выходные дни, автоматическая блокировка на определенное время после заданного количества неудачных попыток авторизации.
Первый сделать возможным вход в приложение пользователя, подключающегося только с определенного ip адреса. Сейчас я сделал, как написал, через gettscip.exe. Эта утилита возвращает тот ip адрес, который передает на сервер удаленный компьютер. Если она за роутером, то это будет адрес компьютера в локальной сети, то есть что-то типа 192.168.1.88. Внешний ip адрес, с которого происходит подключение к серверу, будет другой. Для первого варианта задачи, в принципе, такой вариант можно использовать, так как внутренний адрес в сети можно согласовать с клиентом.
Второй это запрет или разрешение входа в программу с определенных ip адресов. Для этих целей нужен внешний ip адрес удаленного компьютера, и gettscip.exe не подойдет. В интернете я нашел только информацию с WinStationQueryInformationW, про это как-то очень скудно пишут. Может, есть и еще какие-то варианты. Нужно ли включать в приложение такую проверку, это открытый вопрос, так как эта проверка будет работать после запуска кларионовского приложения, предпочтительнее ее проводить до этого. Для tsplus есть отдельный продукт tsplus advanced security (за отдельную плату), который как раз таким, в том числе, и занимается. По сути, это все держится на достаточно простой настройке, если удастся определить внешний ip адрес.
Другие фишки для входа в приложение у меня есть. Это отключение выбора из списка пользователей и ввод имени пользователя напрямую в окне подключения (как в винде), запрет подключения определенным пользователям в режиме терминального сервера, запрет доступа к файловой системе сервера из приложения, ограничение подключения по часам в течении дня, запрет подключения в выходные дни, автоматическая блокировка на определенное время после заданного количества неудачных попыток авторизации.
C6/C11, ШВС, tps/btrieve.