25 Jun
2013
Posted in: 코드
By    No Comments

Vista 이상 시스템에 TDI 포팅 시 주의할 점


Vista 이상 시스템에 TDI 포팅 시 주의할 점
by 신영진(YoungJin Shin), codewiz at gmail.com, @codemaru, http://www.jiniya.net

MS에서 Vista 이상부터 TDI 지원을 끊겠다고 했으나 Windows 8까지 TDI는 여전히 지원되고 있습니다. 하위호환성을 그렇게 쉽게 끊진 못하죠 ㅋ~ 몇 해 전 만들었던 TDI 클라이언트 드라이버가 Vista 이상에서 동작하지 않는다고 해서 오늘 디버깅을 좀 했습니다. 별거 아닌 곳에서 삽질을 좀 해서 기록을 남겨 놓습니다. 우선 문제는 다른 건 다 잘 되는데 이상하게 TdiConnectionContext만 하면 STATUS_INVALID_PARAMETER가 떨어지는 문제였습니다. 아래와 같은 코드에서 ZwCreateFile이 성공하지 못하는 상황이었죠.

struct MY_KERNEL_SOCKET *scoket;
NTSTATUS status;
IO_STATUS_BLOCK iosb = {0};
PFILE_FULL_EA_INFORMATION ea;

UNICODE_STRING name;
OBJECT_ATTRIBUTES oa;

RtlInitUnicodeString(&name, L"\\Device\\Tcp");

InitializeObjectAttributes(&oa
                              , &name
                              , OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE
                              , 0
                              , 0);

ea = ExAllocatePool(...);
if(!ea)
    return STATUS_INSUFFICIENT_RESOURCES;

ea->EaNameLength = TDI_CONNECTION_CONTEXT_LENGTH;
ea->EaValueLength = sizeof(*socket);

RtlCopyMemory(ea->EaName, TdiConnectionContext, ea->EaNameLength);
RtlCopyMemory(&ea->EaName[ea->EaNameLength + 1], socket, sizeof(*socket));


status = ZwCreateFile(&cfh
                        , GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE
                        , &oa
                        , &iosb
                        , NULL
                        , FILE_ATTRIBUTE_NORMAL
                        , 0
                        , FILE_OPEN_IF
                        , 0
                        , ea
                        , ea_len);

if(!NT_SUCCESS(status))
{
    // 요기서 STATUS_INVALID_PARAMETER 발생
    return status;
}

처음에 별거 아닌 문제로 보여서 그냥 구글링을 했는데, 저같은 이슈를 겪는 사용자가 의외로 없더군요. 질문은 올라와 있는데 그냥 해결됐다 고맙다 이런 답변만 있는… ㅠㅜ~ 삽질을 좀 하다 문제가 해결이 안 돼서 tdx.sys 드라이버 파일을 열었습니다. 그제야 답이 보이더군요. Windows XP까지는 TDI를 tcpip.sys에서 처리했으나, Vista 부터는 tdx.sys에서 처리하고 있습니다.


tdx32-1

TdiConnectionContext 인지를 검사하는 루틴

tdx32-2

점프하면 이곳으로 옵니다. EaValueLength가 4인지를 검사하고 있습니다.

tdx64

64비트 운영체제의 tdx.sys, EaValueLength가 8인지를 검사하고 있습니다.

결론만 말하면 TdiConnectionContext의 EA Value로는 항상 포인터 크기의 핸들만 전달해야 합니다. XP에서는 이런 체크가 없어서 정상적으로 동작했던 것 같네요. 헐~ 아래는 MSDN 전문입니다. 교과서를 열심히 봐야 삽질이 없습니다.

For a connection endpoint, the EaName member is set to the system-defined constant TdiConnectionContext and the EA value following the EaName array is a client-supplied handle, opaque to the transport driver. The transport must save this handle and subsequently pass it back to the client’s registered event handlers for this connection.

http://msdn.microsoft.com/en-us/library/windows/hardware/ff565046(v=vs.85).aspx

이거 말고는 기존 XP 소스를 특별히 변경하지 않아도 잘 동작했습니다. 당연한 거겠지만 ㅋㅋ~

Browser does not supports flash movie

  • 트랙백 주소: http://www.jiniya.net/wp/archives/11424/trackback

관련 글