tftpd.exe源代码分析
第一部分:TftpdIoCompletionCallback函数调用TftpdProcessReceivedBuffer函数
void
TftpdIoCompletionCallback(DWORD dwErrorCode,
DWORD dwBytes,
LPOVERLAPPED overlapped) {
PTFTPD_BUFFER buffer = CONTAINING_RECORD(overlapped, TFTPD_BUFFER,
internal.io.overlapped);
PTFTPD_CONTEXT context = buffer->internal.context;
PTFTPD_SOCKET socket = buffer->internal.socket;
TFTPD_DEBUG((TFTPD_TRACE_IO,
"TftpdIoCompletionCallback(buffer = %p): bytes = %d.\n",
buffer, dwBytes));
if (context == NULL)
InterlockedDecrement((PLONG)&socket->postedBuffers);
switch (dwErrorCode) {
case STATUS_SUCCESS :
if (context == NULL) {
if (dwBytes < TFTPD_MIN_RECEIVED_DATA)
goto exit_completion_callback;
buffer->internal.io.bytes = dwBytes;
buffer = TftpdProcessReceivedBuffer(buffer);
} // if (context == NULL)
break;
case STATUS_PORT_UNREACHABLE :
第二部分:TftpdProcessReceivedBuffer函数调用TftpdReadRequest函数
PTFTPD_BUFFER
TftpdProcessReceivedBuffer(PTFTPD_BUFFER buffer) {
TFTPD_DEBUG((TFTPD_TRACE_PROCESS,
"TftpdProcessReceivedBuffer(buffer = %p).\n",
buffer));
buffer->message.opcode = ntohs(buffer->message.opcode);
switch (buffer->message.opcode) {
//
// Sending files to a client:
//
case TFTPD_RRQ :
buffer = TftpdReadRequest(buffer);
break;
case TFTPD_ACK :
buffer->message.ack.block = ntohs(buffer->message.ack.block);
buffer = TftpdReadAck(buffer);
break;
//
// Receiving files from a client:
//
第三部分:TftpdReadRequest函数调用TftpdContextAquire函数和然后调用TftpdContextAllocate函数
PTFTPD_BUFFER
TftpdReadRequest(PTFTPD_BUFFER buffer) {
PTFTPD_CONTEXT context = NULL;
NTSTATUS status;
// Ensure that a RRQ is from the master socket only.
if (buffer->internal.socket != &globals.io.master) {
TftpdIoSendErrorPacket(buffer, TFTPD_ERROR_ILLEGAL_OPERATION,
"Illegal TFTP operation");
goto exit_read_request;
}
// Is this a duplicate request? Do we ignore it or send an error?
if ((context = TftpdContextAquire(&buffer->internal.io.peer)) != NULL) {
if (context->block > 0)
TftpdIoSendErrorPacket(buffer, TFTPD_ERROR_ILLEGAL_OPERATION,
"Illegal TFTP operation");
TftpdContextRelease(context);
context = NULL;
goto exit_read_request;
}
// Allocate a context for this request (this gives us a reference to it as well).
if ((context = (PTFTPD_CONTEXT)TftpdContextAllocate()) == NULL)
goto exit_read_request;
TFTPD_DEBUG((TFTPD_TRACE_PROCESS,
"TftpdReadRequest(buffer = %p): context = %p.\n",
buffer, context));
// Initialize the context.
context->type = TFTPD_RRQ;
CopyMemory(&context->peer, &buffer->internal.io.peer, sizeof(context->peer));
context->state = TFTPD_STATE_BUSY;