dポイントプレゼントキャンペーン実施中!

現在Windowsのログオン画面のカスタマイズを検討しております。

で、カスタマイズしたログオン画面がローカルからの起動されたのか
リモートデスクトップからの起動かは「GetSystemMetrics(SM_REMOTESESSION)」を
用いて判別できました。

次にリモートデスクトップから起動された場合、接続元のIPアドレスを
判別したいのですが、IPアドレスを取得する方法はあるのでしょうか?


環境:OS=Windows7 Pro
   :VisualStudio2005 (VC++ or VB)

A 回答 (2件)

WTSQuerySessionInformation


http://msdn.microsoft.com/en-us/library/windows/ …
にWTSClientAddressを渡すことで取得できます。
*ppBufferをWTS_CLIENT_ADDRESS *にキャスとして使います。
なお,WTS_CLIENT_ADDRESS::Addressの先頭2バイトは読み飛ばす必要があるみたいです。
ちなみに,TS接続でなくてもAPI呼び出しは成功しますが,AddressFamilyが0なので,GetSystemMetricsを使わずに判断できそうです。

なお,AF_INETはWindows.h(というかWinSock.h)で定義されていますが,
AF_INET6はWinSock2.hをインクルードしておく必要があります。
Windows 7だと,リンクローカルIPv6アドレスで接続している可能性がありますので,
IPv6の可能性は捨てない方が良いです。

---- 以下,適当サンプル ----
#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <cstring>
#include <WinSock2.h>
#include <Windows.h>
#include <WtsApi32.h>

#pragma comment(lib, "WtsApi32")

int main (void)
{
LPTSTR pBuffer;
DWORD bytesReturned;

if (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSClientAddress, &pBuffer, &bytesReturned))
{
return ::GetLastError();
}

const WTS_CLIENT_ADDRESS & addr = *reinterpret_cast<WTS_CLIENT_ADDRESS *>(pBuffer);

char message[512];
switch (addr.AddressFamily)
{
case AF_INET:
std::sprintf(message, "IPv4 : %d.%d.%d.%d", addr.Address[2], addr.Address[3], addr.Address[4], addr.Address[5]);
break;
case AF_INET6:
std::sprintf(message, "IPv6 : %x:%x:%x:%x:%x:%x:%x:%x",
addr.Address[2] << 8 | addr.Address[3],
addr.Address[4] << 8 | addr.Address[5],
addr.Address[6] << 8 | addr.Address[7],
addr.Address[8] << 8 | addr.Address[9],
addr.Address[10] << 8 | addr.Address[11],
addr.Address[12] << 8 | addr.Address[13],
addr.Address[14] << 8 | addr.Address[15],
addr.Address[16] << 8 | addr.Address[17]);
break;
case AF_IPX:
std::strcpy(message, "IPX");
break;
case AF_NETBIOS:
std::strcpy(message, "NETBIOS");
break;
default:
std::strcpy(message, "unknown");
break;
}
std::puts(message);

return 0;
}
    • good
    • 0
この回答へのお礼

Yune-Kichi様、ご回答ありがとうございます。

ずばりの回答で本当に助かりました。
IPアドレスを取得することができました。

当方ではVB.netでの開発を検討しております。
参考までに、作成したVB.net用のIPアドレス取得モジュールを記載します。

----------------------------------------------------------------------
Imports System.Runtime.InteropServices

Module MWTS

' *************************************************************************
' * 定数
' *************************************************************************
Private Const WTS_CURRENT_SERVER_HANDLE As Integer = 0&
Private Const WTS_CURRENT_SESSION As Integer = -1

Private Enum WTS_INFO_CLASS
WTSInitialProgram
WTSApplicationName
WTSWorkingDirectory
WTSOEMId
WTSSessionId
WTSUserName
WTSWinStationName
WTSDomainName
WTSConnectState
WTSClientBuildNumber
WTSClientName
WTSClientDirectory
WTSClientProductId
WTSClientHardwareId
WTSClientAddress
WTSClientDisplay
WTSClientProtocolType
End Enum

' *************************************************************************
' * 構造体
' *************************************************************************
<StructLayout(LayoutKind.Sequential)> _
Public Structure WTS_CLIENT_ADDRESS
Public AddressFamily As Integer
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=20)> _
Public Address As Byte()
End Structure

' *************************************************************************
' * Win32 関数用宣言
' *************************************************************************
Private Declare Auto Function WTSQuerySessionInformation Lib "wtsapi32.dll" ( _
ByVal hServer As Int32, _
ByVal SessionId As Int32, _
ByVal InfoClass As WTS_INFO_CLASS, _
ByRef ppBuffer As IntPtr, _
ByRef pCount As Int32) As Int32
Private Declare Auto Sub WTSFreeMemory Lib "wtsapi32.dll" ( _
ByVal pMemory As IntPtr)

' *************************************************************************
' * 関数
' *************************************************************************
'
' IPアドレス取得
'
Public Function GetWTSClientAddress() As WTS_CLIENT_ADDRESS
Dim lpBuffer As IntPtr
Dim count As Integer
Dim ClientAddress As New WTS_CLIENT_ADDRESS()

If WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTS_INFO_CLASS.WTSClientAddress, lpBuffer, count) Then
ClientAddress = CType(Marshal.PtrToStructure(lpBuffer, ClientAddress.GetType()), WTS_CLIENT_ADDRESS)
WTSFreeMemory(lpBuffer)
End If

Return ClientAddress
End Function
End Module
----------------------------------------------------------------------

お礼日時:2013/07/01 11:19

質問の意味を取り違えてるかもしれませんが


ipconfig /all で調べるってのは無し?
    • good
    • 0
この回答へのお礼

koi1234様、ご回答ありがとうございます。

質問がわかりにくくて申し訳ありません。
ipconfigでは私の希望する動作となりませんでした。

(ローカルで起動したときとリモート接続で起動したときも同じIPアドレスが取得されます。)

お礼日時:2013/07/01 11:12

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!