Windows 2000 に OnLinkPrefixLength を実装してみる
副題 UTAU Plugin autoCVVC Win2000 で エラーになる件について その4 なのです
UTAU Plugin autoCVVC Win2000 で エラーになる件について その1
Windows 2000 と PIP_ADAPTER_UNICAST_ADDRESS
UTAU Plugin autoCVVC Win2000 で エラーになる件について その2
Windows 2000 と PIP_ADAPTER_ADDRESSES
UTAU Plugin autoCVVC Win2000 で エラーになる件について その3
jz L773043CA mov ecx,[ebp-08h] and ecx,ebx cmp ecx,edi jz L7730442D push 00000003h pop ecx mov [esi+14h],ecx // PrefixOrigin mov [esi+18h],ecx // SuffixOrigin L773043CA: cmp dword ptr [esi+18h],00000005h // SuffixOrigin push 00000004h pop ecx mov [esi+1Ch],ecx jz L773043EB cmp dword ptr [ebp-08h],7F000001h // localhost 127.0.0.1 jz L773043EB mov edx,[ebp-08h] and edx,ebx cmp edx,edi jz L773043EB mov [esi+04h],eax L773043EB: mov eax,[ebp+0Ch] // MIB_IPADDRROW_W2K test byte ptr [eax+16h],80h // wType jnz L7730443D L773043F4: test byte ptr [eax+16h],01h // wType jz L773043FD or [esi+04h],ecx |
さて、もう少し解析してみて、分かったことがあります。
実は、 *(int*) (ebp + 0xc) には、 IPv4 の MIB_IPADDRTABLE 構造体のアドレスが入っています
これのオフセットの 0x08 を見ると、サブネットマスクが入ってるのです。
例えば、255.255.255.0 なら、 0x00FFFFFF となり、
255.0.0.0 なら、 0x000000FF となります。
欲しい数値は、0x18 と 0x8 です。
mov eax,DWORD PTR[ebp+0xc] mov eax,DWORD PTR[eax+8] mov bl,al shl ebx,8 shr eax,8 mov bl,al shl ebx,8 shr eax,8 mov bl,al shl ebx,8 shr eax,8 mov bl,al xor eax,eax L1: shl ebx,1 jnc L2 inc eax jmp L1 L2: mov [esi+0x2c],eax // OnLinkPrefixLength |
これで、実装できそうです ・ω・ (ebx がこの関数内で使えるため)
ちなみに、ConvertLengthToIpv4Mask は逆の演算をすればOKです
Windows Vista を見るとあらかじめテーブルを 32 QWORD 用意して 返すようにしてますね・ω・
ConvertLengthToIpv4Mask: push ebp mov ebp,esp mov eax,[ebp+08h] cmp eax,00000021h jnc ERR xor ecx,ecx and eax,eax jz CALEND LP: stc rcr ecx,1 dec eax jnz LP mov al,cl shr ecx,8 shl eax,8 mov al,cl shr ecx,8 shl eax,8 mov al,cl shr ecx,8 shl eax,8 mov al,cl CALEND: mov ecx,[ebp+0Ch] mov [ecx],eax xor eax,eax jmp END ERR: mov eax,[ebp+0Ch] or dword ptr [eax],FFFFFFFFh push 00000057h pop eax END: pop ebp retn 0008h |
実装前
sizeof(pUnicast)=48 pUnicast->OnLinkPrefixLength=0 ConvertLengthToIpv4Mask=false (ローカル エリア接続 2:2:192.168.79.152:255.255.255.0::) sizeof(pUnicast)=0 pUnicast->OnLinkPrefixLength=0 ConvertLengthToIpv4Mask=false (ローカル エリア接続:2:192.168.79.202:255.255.255.0::) sizeof(pUnicast)=48 pUnicast->OnLinkPrefixLength=0 ConvertLengthToIpv4Mask=false (MS TCP Loopback interface:2:127.0.0.1:255.0.0.0::) |
実装後
sizeof(pUnicast)=48 pUnicast->OnLinkPrefixLength=24 ConvertLengthToIpv4Mask=00ffffff (ローカル エリア接続 2:2:192.168.79.152:255.255.255.0::) sizeof(pUnicast)=48 pUnicast->OnLinkPrefixLength=24 ConvertLengthToIpv4Mask=00ffffff (ローカル エリア接続:2:192.168.79.202:255.255.255.0::) sizeof(pUnicast)=48 pUnicast->OnLinkPrefixLength=8 ConvertLengthToIpv4Mask=000000ff (MS TCP Loopback interface:2:127.0.0.1:255.0.0.0::) |
うまくいきました・ω・
ここで、autoCVVC を動かしてみます。
ですよねー ・ω・
psutil/_psutil_windows.c at master ・ giampaolo/psutil
#if (_WIN32_WINNT >= 0x0600) // Windows Vista and above SecureZeroMemory((PVOID)pIfRow, sizeof(MIB_IF_ROW2)); pIfRow->InterfaceIndex = pCurrAddresses->IfIndex; dwRetVal = GetIfEntry2(pIfRow); #else // Windows XP pIfRow->dwIndex = pCurrAddresses->IfIndex; dwRetVal = GetIfEntry(pIfRow); #endif |
あかん、これは、ソースが無い限り無理なやつや…。
これ、使えそう?
https://github.com/wine-mirror/wine/blob/master/dlls/iphlpapi/iphlpapi_main.c#L1718
>>1
ありがとうございます。
私が作ったのとほぼ同じみたいですね。
考えることは同じと言うわけのようです。