?? transferfile.c
字號:
#ifndef __TRANSFER_FILE_C__
#define __TRANSFER_FILE_C__
#include <WinSock.h>
#include "TransferFile.h"
#include "net_list.h"
//#pragma comment(lib,"ws2_32.lib")
LPWSADATA inet_WsaData;
PTRAN_LIST inet_TransList = NULL;
SOCKET inet_Listen_Socket = INVALID_SOCKET;
PCHAR inet_Local_Dir = NULL;
void net_InsertItemIntoList(PTRAN_THREAD item)
{
PTRAN_LIST p = inet_TransList, pt = NULL;
while (p)
{
pt = p;
p = p->next;
}
p = malloc(sizeof(TRAN_LIST));
p->context = item;
p->next = NULL;
if (!pt)
{
inet_TransList = p;
}
else
{
pt->next = p;
}
}
PTRAN_LIST net_SearchItemFromListByItem(PTRAN_THREAD item)
{
PTRAN_LIST p = inet_TransList;
while (p)
{
if (p->context == item)
{
break;
}
p = p->next;
}
return p;
}
PTRAN_LIST net_SearchItemFromListBySocket(SOCKET sock)
{
PTRAN_LIST p = inet_TransList;
while (p)
{
if (p->context->sock == sock)
{
break;
}
p = p->next;
}
return p;
}
void net_DisposeListItemByItem(PTRAN_THREAD item)
{
DWORD dwExitCode;
PTRAN_LIST p = inet_TransList, pt = NULL;
while (p)
{
if (p->context == item)
{
if (!pt) //delete the header
{
inet_TransList = p->next;
}
else
if (!p->next) //delete the tail
{
if (pt)
{
pt->next = NULL;
}
}
else
{
pt->next = p->next;
}
if (p->context)
{
if (p->context->ctrl)
{
free(p->context->ctrl);
}
if (p->context->hfile != INVALID_HANDLE_VALUE)
{
CloseHandle(p->context->hfile);
p->context->hfile = INVALID_HANDLE_VALUE;
}
if (p->context->sock != INVALID_SOCKET)
{
closesocket(p->context->sock);
p->context->sock = INVALID_SOCKET;
}
if (p->context->thread != INVALID_HANDLE_VALUE)
{
if (GetExitCodeThread(p->context->thread, &dwExitCode))
{
TerminateThread(p->context->thread, dwExitCode);
}
p->context->thread = INVALID_HANDLE_VALUE;
}
free(p->context);
}
free(p);
break;
}
pt = p;
p = p->next;
}
}
void net_RemoveItemFromListBySocket(SOCKET item)
{
PTRAN_LIST p = inet_TransList, pt = NULL;
while (p)
{
if (p->context->sock == item)
{
net_DisposeListItemByItem(p->context);
break;
}
pt = p;
p = p->next;
}
}
void net_RemoveList()
{
PTRAN_LIST p = inet_TransList;
while (p)
{
net_DisposeListItemByItem(p->context);
p = inet_TransList;
}
}
DWORD inet_Accept_Connect(SOCKET sock)
{
PTRAN_THREAD p = malloc(sizeof(TRAN_THREAD));
int len;
len = sizeof(SOCKADDR_IN);
p->ctrl = NULL;
p->hfile = INVALID_HANDLE_VALUE;
p->thread = INVALID_HANDLE_VALUE;
p->sock = accept(sock, (struct sockaddr *)&p->addr, &len);
net_InsertItemIntoList(p);
return RET_SUCCESS;
}
WORD inet_Extract_FileName_From_Buffer(PBYTE buf, WORD len, char * fname, PWORD fnlen, PDWORD fsize) //get file name & length
{
WORD i = 0;
if (len < 5)
{
return RET_FAILURE;
}
//get file size from buffer
*fsize = (DWORD)(*(buf + 0));
*fsize += (DWORD)(*(buf + 1)) * 256;
*fsize += (DWORD)(*(buf + 2)) * 256 * 256;
*fsize += (DWORD)(*(buf + 3)) * 256 * 256 * 256;
//get filename from buffer
memcpy(fname, buf + 4, len - 4);
*fnlen = strlen(fname);
return RET_SUCCESS;
}
BYTE inet_Calc_BCC(PBYTE buf, WORD len)
{
BYTE ret = 0;
while (len > 0)
{
ret ^= *buf++;
len --;
}
return ret;
}
void inet_Reply_Remote(SOCKET s, PTF_COMMAND pcmd)
{
WORD len = COMMAND_HEADER_LENGTH + pcmd->low + (WORD)pcmd->high * 256;
PBYTE buf = malloc(len);
memcpy(buf, pcmd, COMMAND_HEADER_LENGTH - 1);
if ((pcmd->low + (WORD)pcmd->high * 256 > 0) && (pcmd->data))
{
memcpy(buf + COMMAND_HEADER_LENGTH - 1, pcmd->data, len - COMMAND_HEADER_LENGTH);
}
// *(buf + len - 1) = inet_Calc_BCC(pcmd->data, (WORD)(len - COMMAND_HEADER_LENGTH));
send(s, buf, len, 0);
free(buf);
}
void inet_Save_File_To_Local(SOCKET s, PTF_COMMAND pcmd)
{
char * fname = NULL;
PWORD fnlen = 0;
char * fdir = NULL;
WORD len = (WORD)pcmd->low + (WORD)pcmd->high * 256;
PDWORD fsize = 0;
DWORD dwRead = 0;
PTRAN_LIST p = net_SearchItemFromListBySocket(s);
if (p)
{
if (!p->context->ctrl)
{
p->context->ctrl = malloc(sizeof(TRAN_CTRL));
memset(p->context->ctrl, 0, sizeof(TRAN_CTRL));
}
fname = malloc(1024);
memset(fname, 0, 1024);
fnlen = malloc(sizeof(WORD));
fsize = malloc(sizeof(DWORD));
if (p->context->hfile == INVALID_HANDLE_VALUE)
{
if (inet_Extract_FileName_From_Buffer(
pcmd->data,
len,
fname,
fnlen,
fsize) == 0)
{
len = strlen(inet_Local_Dir) + 1 + *fsize + 1;
fdir = malloc(len);
memset(fdir, 0, len);
memcpy(fdir, inet_Local_Dir, strlen(inet_Local_Dir));
if (*(inet_Local_Dir + strlen(inet_Local_Dir) - 1) != '\\')
{
*(fdir + strlen(inet_Local_Dir)) = '\\';
memcpy(fdir + strlen(inet_Local_Dir) + 1, fname, *fnlen);
}
else
{
memcpy(fdir + strlen(inet_Local_Dir), fname, *fnlen);
}
memset(fname, 0, 1024);
memcpy(fname, fdir, strlen(fdir));
free(fdir);
}
p->context->hfile = CreateFile(
fname,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (p->context->ctrl->status == TRAN_STOP)
{
if (pcmd->data)
{
free(pcmd->data);
}
pcmd->opcode = RET_SUCCESS;
p->context->ctrl->fsize = *fsize;
pcmd->data = malloc(1);
pcmd->low = 1;
pcmd->high = 0;
*(pcmd->data + 0) = TRAN_SYN;
inet_Reply_Remote(p->context->sock, pcmd);
p->context->ctrl->status = TRAN_START;
}
}
else
{
WriteFile(
p->context->hfile,
pcmd->data,
pcmd->low + pcmd->high * 256,
&dwRead,
NULL);
pcmd->low = 0;
pcmd->high = 0;
free(pcmd->data);
pcmd->data = NULL;
pcmd->opcode = RET_SUCCESS;
inet_Reply_Remote(p->context->sock, pcmd);
p->context->ctrl->offset += dwRead;
if (p->context->ctrl->offset == p->context->ctrl->fsize)
{
CloseHandle(p->context->hfile);
p->context->hfile = INVALID_HANDLE_VALUE;
free(p->context->ctrl);
p->context->ctrl = NULL;
}
}
free(fname);
free(fnlen);
free(fsize);
}
}
DWORD inet_Process_Remote_Command(SOCKET s, PTF_COMMAND pcmd)
{
switch (pcmd->cmd)
{
case TRAN_REQ_READ: //remote request read data from local
switch (pcmd->opcode)
{
case TRAN_REQ_DATA: //get file
break;
case TRAN_REQ_DIR: //get directory information
break;
default:
break;
}
break;
case TRAN_REQ_WRITE: //remote request write data to local
switch (pcmd->opcode)
{
case TRAN_REQ_DATA: //receive file
inet_Save_File_To_Local(s, pcmd);
break;
default:
break;
}
break;
}
free(pcmd);
return RET_SUCCESS;
}
DWORD inet_Recv_Remote_Data(SOCKET sock)
{
int buflen, ret = -1;
PBYTE buf = NULL;
BYTE headercnt = 0, dat = 0;
PTF_COMMAND cmd = NULL;
PTRAN_LIST p = net_SearchItemFromListBySocket(sock);
ioctlsocket(sock, FIONREAD, (u_long *)&buflen);
if (buflen > 0)
{
buf = malloc(buflen);
ret = recv(sock, buf, buflen, 0);
if (ret != buflen)
{
ret = RET_FAILURE | 0x01;
free(buf);
return ret;
}
ret = 0;
cmd = malloc(sizeof(TF_COMMAND));
INIT_CMD(cmd);
while (ret < buflen)
{
dat = *(buf + ret);
switch (headercnt)
{
case 0: //command header
if (dat == COMMAND_HEADER)
{
cmd->header = dat;
headercnt ++;
}
break;
case 1: //command name
if (INVALID_COMMAND(dat))
{
cmd->cmd = dat;
headercnt ++;
}
else
{
memset(cmd, 0, sizeof(TF_COMMAND));
}
break;
case 2: //command sequence
cmd->seq = dat;
headercnt ++;
break;
case 3: //command opcode
cmd->opcode = dat;
headercnt ++;
break;
case 4: //command data length low byte
cmd->low = dat;
headercnt ++;
break;
case 5: //command data length high byte
cmd->high = dat;
headercnt ++;
break;
case 6: //command data context
headercnt ++;
break;
}
if (headercnt >= COMMAND_HEADER_LENGTH)
{
break;
}
ret ++;
}
if (headercnt >= COMMAND_HEADER_LENGTH)
{
buflen = cmd->low + (int)cmd->high * 256;
if (buflen > 0)
{
cmd->data = malloc(buflen);
memcpy(cmd->data, buf + ret, buflen);
}
//check the bcc of the command data context here
ret = (int)inet_Process_Remote_Command(sock, cmd);
}
else
{
cmd->low = 1;
cmd->high = 0;
cmd->data = malloc(1);
*(cmd->data) = RET_FAILURE;
inet_Reply_Remote(sock, cmd);
}
free(buf);
buf = NULL;
}
return (DWORD)ret;
}
DWORD inet_Write_Data(SOCKET sock)
{
return RET_SUCCESS;
}
DWORD inet_Remote_Close(SOCKET sock)
{
PTRAN_LIST p = net_SearchItemFromListBySocket(sock);
net_DisposeListItemByItem(p->context);
return RET_SUCCESS;
}
DWORD WINAPI net_Event(PNETSOCKETMESSAGE msg)
{
DWORD ret = 0;
switch (msg->event)
{
case FD_ACCEPT:
case FD_CONNECT:
ret = inet_Accept_Connect(msg->sock);
break;
case FD_READ:
ret = inet_Recv_Remote_Data(msg->sock);
break;
case FD_WRITE:
ret = inet_Write_Data(msg->sock);
break;
case FD_CLOSE:
ret = inet_Remote_Close(msg->sock);
break;
default:
break;
}
return ret;
}
DWORD WINAPI net_Initialization(PBYTE dir, HWND hwnd, WORD port)
{
int ret = -1;
SOCKADDR_IN addr;
WSAStartup(0x0101, inet_WsaData);
inet_Local_Dir = malloc(strlen(dir) + 1);
memset(inet_Local_Dir, 0, strlen(dir) + 1);
memcpy(inet_Local_Dir, dir, strlen(dir));
addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
inet_Listen_Socket = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
if (inet_Listen_Socket != INVALID_SOCKET)
{
ret = bind(inet_Listen_Socket, (struct sockaddr *)&addr, sizeof(SOCKADDR_IN));
if (ret == 0)
{
ret = listen(inet_Listen_Socket, 1024);
if (ret == 0)
{
ret = WSAAsyncSelect(inet_Listen_Socket, hwnd, CM_SOCKETMESSAGE, 63);
}
}
}
if (ret != 0)
{
closesocket(inet_Listen_Socket);
inet_Listen_Socket = INVALID_SOCKET;
}
return (DWORD)ret;
}
DWORD WINAPI net_Finalization()
{
net_RemoveList();
if (inet_Listen_Socket != INVALID_SOCKET)
{
closesocket(inet_Listen_Socket);
inet_Listen_Socket = INVALID_SOCKET;
}
WSACleanup();
return RET_SUCCESS;
}
#endif //__TRANSFER_FILE_C__
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -