Гыррр.. Гыррррр… Хм. есь абырррр,абыыррр,абыррваллл
unit trans;
INTERFACE
uses
Windows,SysUtils,Classes,forms,
types,protodef,socks,tAHuffman2,clientmsg,config,adodatabase,WinSock,hinfo,
types_data, urout_buf;
const mincompresssize = 300;
const DefTimeOut = 30000;
type
TSocksReply = (srOK, srRejected, srConnFailed, srConnRefused, srLoginFailed,
srUserIdError,srLoginMethodNotSupported,srSocksFailure,srConnNotAllowed,
srNetUnreachable,srHostUnreachable,srTTLExpired,srCommandNotSupportted,
srAddrTypeNotSupported, srUnassigned);
type pServerLocation = ^tServerLocation;
tServerLocation = record
address : string[15];
port : longword;
end;
type tServerList = class(tList)
procedure ClearAll;
destructor destroy; override;
end;
type tSockThread = class(tThread)
constructor create;
procedure Execute; override;
destructor destroy; override;
end;
type tHerinskiClerambo = class(tObject)
connstatus : longint;
servers : tServerlist;
sockthread : tSockThread;
csock : tClientSocket;
filelist : tStringlist;
Queue : tThreadList;
huffman : tAHuffman;
mytraffic : longint;
srvCanClose : boolean;
public
constructor create;
function GetQueueSize : longint;
function SafeWriteSockData(buf:pChar; datasize, timeout:longint):longint;
function SafeReadSockData(buf:pChar; datasize, timeout:longint; chkfrm:boolean):longint;
procedure ParseBroadcast(source : string);
function SetConnection : boolean;
function OnLine:boolean;
function doSendQueue : longint;
procedure QueueData(var buf; itemid:longint; fn:tFileName; datasize:longint);
procedure csockDisconnect;
destructor destroy; override;
end;
function StartSession(broadcaststr : string; msghandler : HWND) : boolean;
procedure StopSession;
procedure AddInputQueue(dataid,datasize : longint; filename : string; data : pchar);
procedure DeleteInputQueueItem(idx : longint);
procedure ClearInputQueue;
var
transport : ttransport;
pthout : string;
pthin : string;
hmain : HWND;
inputqueue : tThreadList;
newversion : boolean;
lastrecv : longint;
trsbuffer : pchar;
trsbufferrcv : pchar;
crsbuffer : pChar;
usetrsacc : boolean;
trsacc : string[20];
IMPLEMENTATION
uses main;
destructor tServerList.destroy;
begin
while count>0 do begin dispose(pServerLocation(items[0])); delete(0); end;
end;
procedure tServerList.ClearAll;
var i : longint;
begin
for i:=count-1 downto 0 do Dispose(pServerlocation(items[i]));
clear;
end;
function cutToken(var str: string; divider:char) :string;
var i: integer;
begin
for i:=1 to length(str) do if str[i]=divider then break;
if length (copy(str, 1, i)) > 0 then begin
result:=copy(str, 1, i);
str:=copy(str, i+1, length(str));
if result[length(result)] = divider then result:=copy(result, 1, length(result)-1);
result:=trim(result);
end;
end;
constructor tHerinskiClerambo.Create;
begin
inherited create;
csock:=tClientSocket.create;
servers:=tServerlist.create;
connstatus:=csDisconnect;
filelist:=tStringlist.create;
queue:=tThreadlist.create;
Huffman:=TAHuffman.Create;
Huffman.Adaptive := false;
end;
destructor tHerinskiClerambo.destroy;
var i : longint;
begin
if assigned(csock) then csock.free;
servers.clearall;
servers.free;
filelist.free;
with queue.locklist do begin
for i:=0 to count-1 do begin if assigned(pQueueData(items[i])^.data) then freemem(pQueueData(items[i])^.data); dispose(items[i]) end;
end;
queue.unlocklist;
queue.free;
Huffman.free;
inherited destroy;
end;
procedure tHerinskiClerambo.ParseBroadcast(source : string);
var srvloc : pServerlocation;
tmpstr : string;
src : string;
begin
src:=source;
servers.clearall;
while src <> ’’ do begin
new(srvloc);
tmpstr:=cutToken(src, ‘,’);
srvloc^.address:=cutToken(tmpstr, ‘:’);
try srvloc^.port:=strtoint(tmpstr) except srvloc^.port:=8000 end;
servers.add(srvloc);
end;
end;
function tHerinskiClerambo.SetConnection : boolean;
var i : longint;
begin
i:=0;
result:=false;
sockthread:=tSockThread.create;
while (i<servers.Count) and (not result) do begin
result:=csock.Connect(pserverlocation(servers.items[i])^.address,pserverlocation(servers.items[i])^.port)=0;
inc(i);
end;
{
while (i<servers.Count) and
(csock.Connect(pserverlocation(servers.items[i])^.address,pserverlocation(servers.items[i])^.port)<>0) do inc(i);
result:=i<servers.Count;
}
if result then begin
connstatus:=csOnline;
sockthread.resume;
end else begin
connstatus:=csDisconnect;
sockthread.free;
sockthread:=nil;
end;
end;
function tHerinskiClerambo.SafeWriteSockData;
var sz,dsz,tm : longint;
lr : longint;
begin
tm:=0; sz:=0; timeout:=timeout div 10;
while OnLine and (sz<datasize) do begin
case cSock.WaitForWriteTime(1) of
-1 : connstatus:=csDisconnect;
0 : begin sleep(10);{ inc(tm); }end;
else begin
dsz:=cSock.Write(buf[sz],datasize-sz);
case dsz of
-1 : begin
lr:=cSock.GetLastError;
case lr of
10035,10055 : begin
sleep(10);
{Сбрасываем таймаут сессии если тут торчим.}
lastrecv:=GetTickCount;
{inc(tm);}
end;
else connstatus:=csDisconnect;
end;
end;
0 : begin sleep(10); inc(tm); end;
else if dsz>0 then begin
inc(sz,dsz);
tm:=0;
postmessage(hmain,UM_SendBytes,dsz,0);
end;
end;
end;
end;
if (tm>timeout) then begin
connstatus:=csTimeOut;
postmessage(hmain,UM_TimeOut,0,0);
end;
if sockthread.terminated then connstatus:=csTerminated;
sleep(0);
end;
if Online then result:=sz else result:=-1;
end;
function tHerinskiClerambo.SafeReadSockData;
var sz,dsz,tm : longint;
begin
result:=-1; tm:=0; sz:=0; timeout:=timeout div 10;
while Online and (sz<datasize) do begin
case cSock.WaitForDataTime(1) of
-1 : connstatus:=csDisconnect;
0 : begin
{doSendQueue;}
sleep(10); inc(tm);
end;
else begin
dsz:=cSock.Read(buf[sz],datasize-sz);
if dsz>0 then begin
inc(sz,dsz);
tm:=0;
// lastrecv:=GetTickCount;
postmessage(hmain,UM_RecvBytes,dsz,0);
end else connstatus:=csDisconnect;
end;
end;
if (tm>timeout) then begin
connstatus:=csTimeOut;
postmessage(hmain,UM_TimeOut,0,0);
end;
if sockthread.terminated then connstatus:=csTerminated;
sleep(0);
end;
if Online then begin
if chkfrm then begin
if (sz=sizeof(tProtocolRec)) and CheckFrame(pProtocolRec(buf)^) then result:=sz
else connstatus:=csFrameError;
end else result:=sz;
end;
end;
function tHerinskiClerambo.OnLine;
begin
if (connstatus=csOnLine) and sockthread.terminated then connstatus:=csTerminated;
result:=(connstatus=csOnLine);
end;
procedure tHerinskiClerambo.QueueData;
var itm : pQueueData;
buffer : pointer;
complen : longint;
begin
buffer:=nil;
itm:=new(pQueueData);
with itm^ do begin
id:=itemid;
filename:=fn;
end;
if datasize >= mincompresssize then begin
huffman.CompressBuf(@buf,datasize,buffer,complen);
if (huffman.error=0) and (assigned(buffer)) and (complen>0) then begin
with itm^ do begin
size:=complen;
data:=allocmem(complen);
move(buffer^,data^,complen);
flags:=pfPacked;
end;
end else begin
with itm^ do begin
size:=datasize;
data:=allocmem(datasize);
move(buf,data^,datasize);
flags:=pfNoFlags;
end;
end;
if assigned(buffer) then freemem(buffer);
end else begin
with itm^ do begin
size:=datasize;
data:=allocmem(datasize);
move(buf,data^,datasize);
flags:=pfNoFlags;
end;
end;
with Queue.LockList do add(itm);
Queue.UnlockList;
end;
function tHerinskiClerambo.doSendQueue;
var i : longint;
frame : tProtocolRec;
procedure freequeueitem(item:pQueueData);
begin
with item^ do freemem(data,size); dispose(pQueueData(item));
end;
begin
with Queue.LockList do begin
for i:=count-1 downto 0 do begin
with pQueueData(items[i])^ do begin
frame:=fillprotocolframe(id,filename,size,flags);
SafeWriteSockData(@frame,sizeof(frame),connDefTimeOut);
SafeWriteSockData(data,size,connDefTimeOut);
if id<>idPing then lastrecv:=GetTickCount;
end;
freequeueitem(items[i]);
end;
clear;
end;
Queue.UnlockList;
result:=0;
end;
constructor TSockThread.create;
begin
inherited create(true);
freeonterminate:=false;
end;
destructor TSockThread.destroy;
begin
inherited destroy;
end;
function tHerinskiClerambo.GetQueueSize : longint;
var i : longint;
begin
result:=0;
with queue.locklist do begin
for i:=0 to count-1 do with pQueueData(items[i])^ do result:=result+size;
end;
queue.unlocklist;
end;
procedure TSockThread.execute;
const bufno : longint = 0;
var frame : tProtocolRec;
reply : tSrvReply;
buf : pchar;
len : longint;
ci : TClientInfo;
unpack : pchar;
unpacksz : longint;
hf : longint;
tm : longword;
begin
{with transport do begin
tm:=getTickCount;
frame:=FillProtocolFrame(idClientInfo,’’,SizeOf(TClientInfo),pfnoFlags);
fillchar(ci,sizeof(ci),0);
with ci do begin
id:=config.clientid;
version.version:=config.version;
end;
key:=ReadEncryptKey;
if key.basiskey.szkey>0 then begin
sign:=MakeClientInfoSign(ci,key);
end else sign:=’’;
DecodeSignToField(sign,@(ci.sign[1]));
safewritesockdata(@frame,SizeOf(frame),DefTimeOut);
safewritesockdata(@ci,SizeOf(ci),DefTimeout);
if Online then begin
SafeReadSockData(@frame,sizeof(frame),DefTimeout,frmchkEnabled);
SafeReadSockData(@reply,sizeof(reply),DefTimeout,frmchkDisabled);
if not reply.accresult then begin
PostMessage(hmain,UM_AcceptFails,0,0);
connstatus:=csInvalidUser;
end;
if OnLine then begin
if reply.accresult then begin
fillchar(HdwInfo,sizeof(HdwInfo),0);
HdwInfo:=GetHdwInfo;
frame:=FillProtocolFrame(idHdwInfo,’’,SizeOf(tHdwInfo),pfnoFlags);
safewritesockdata(@frame,SizeOf(frame),DefTimeOut);
safewritesockdata(@HdwInfo,SizeOf(HdwInfo),DefTimeout);
if OnLine then begin
SafeReadSockData(@frame,sizeof(frame),DefTimeout,frmchkEnabled);
SafeReadSockData(@reply,sizeof(reply),DefTimeout,frmchkDisabled);
if not reply.accresult then begin
PostMessage(hmain,UM_HDWFAILS,0,0);
connstatus:=csInvalidUser;
end;
end;
end;
end;
end;}
with transport do begin
tm:=getTickCount;
frame:=FillProtocolFrame(idClientInfo,’’,SizeOf(TClientInfo),pfnoFlags);
fillchar(ci,sizeof(ci),0);
with ci do begin
id:=config.clientid;
tClientVersion(version.version):=tClientVersion(config.version);
end;
FillChar (Reply, sizeof(reply),#0);
if Online then begin
// Послать Версию
frame:=FillProtocolFrame(idClientInfo,’’,SizeOf(TClientInfo),pfnoFlags);
fillchar(ci,sizeof(ci),0);
with ci do begin
id:=config.clientid;
tClientVersion(version.version):=tClientVersion(config.version);
end;
safewritesockdata(@frame,SizeOf(frame),DefTimeOut);
safewritesockdata(@ci,SizeOf(ci),DefTimeout);
end;
srvCanClose:=false;
lastrecv:=GetTickCount;
doSendQueue;
while Online do begin
case cSock.WaitForDataTime(1) of
-1 : connstatus:=csDisconnect;
0 : begin
doSendQueue;
{ if ((GetTickCount-lastrecv)>config.waitdata) then begin
connstatus:=csTimeOut;
postmessage(hmain,UM_TimeOut,0,0);
end;}
if (GetQueueSize=0) and srvCanClose and ((GetTickCount-lastrecv)>config.waitdata) and (not NewVersion) then begin
connstatus:=csTerminated;
end;
end;
else begin
SafeReadSockData(@frame,sizeof(frame),DefTimeOut,frmchkEnabled);
with frame do
if OnLine then begin
if (flags and pfPacked) > 0 then begin
buf:=allocmem(datasize);
SafeReadSockData(buf,datasize,DefTimeOut,frmchkDisabled);
if Online then begin
unpack:=nil;
huffman.DecompressBuf(buf,datasize,pointer(unpack),unpacksz);
if assigned (unpack) and (unpacksz > 0) and (huffman.error = 0) then begin
freemem(buf);
buf:=unpack;
datasize:=unpacksz;
end else begin
hf:=filecreate(‘buf.’+inttostr(bufno));
if hf>=0 then begin
filewrite(hf,buf^,datasize);
fileclose(hf);
end;
freemem(buf);
buf:=nil;
end;
case dataid of
idfile : begin
BufferToFile (buf,datasize,config.exepath + ‘FEBUpdate.rar’);
QueueData (ci,idfileok,’’,sizeof (ci));
// обновление найдено
PostMessage (frmmain.handle, UM_FOUND_UPDATE, 0,0);
end;
idfilenot : begin
// обновление не найдено
PostMessage (frmmain.handle, UM_FOUND_UPDATENON, 0,0);
end
end;
end;
end else begin
len:=datasize+1; buf:=allocmem(len);
SafeReadSockData(buf,datasize,DefTimeOut,frmchkDisabled);
end;
if (OnLine) then begin
if assigned(buf) then begin
AddInputqueue(frame.dataid,frame.datasize,frame.filename,buf);
postmessage(hmain,UM_InputQueue,0,0);
freemem(buf); buf:=nil;
end else begin
end;
end;
end;
lastrecv:=GetTickCount;
end;
end;
sleep(10);
if GetTickCount-tm >= 3000 then begin
tm:=GetTickCount;
frame:=FillProtocolFrame(idPing,’’,0,pfnoFlags);
SafeWriteSockData(@frame,sizeof(frame),connDefTimeout);
end;
end;
csock.free; csock:=nil;
csock:=tClientSocket.create;
csockDisconnect;
end;
end;
procedure tHerinskiClerambo.csockDisconnect;
begin
if connstatus=csDisconnect then
postmessage(hmain,UM_SocketClosed,0,0);
postmessage(hmain,UM_Disconnected,0,0);
end;
function StartSession(broadcaststr : string; msghandler : HWND) : boolean;
begin
hmain:=msghandler;
transport.ParseBroadcast(broadcaststr);
result:=transport.setconnection;
if result then begin
postmessage(hmain,UM_Connected,0,0);
transport.mytraffic:=0;
end else postmessage(hmain,UM_ConnectError,0,0);
end;
procedure StopSession;
begin
if assigned(transport.sockthread) then
try
with transport.sockthread do begin
terminate;
waitfor;
free;
end;
except
end;
end;
procedure AddInputQueue(dataid,datasize : longint; filename : string; data : pchar);
var itm : pQueueData;
begin
new(itm);
with inputqueue.locklist do begin
itm^.id:=dataid;
itm^.filename:=filename;
itm^.size:=datasize;
itm^.data:=allocmem(datasize);
system.move(data^,itm^.data^,datasize);
add(itm);
end;
inputqueue.unlocklist;
end;
procedure ClearInputQueue;
var i : longint;
begin
with inputqueue.locklist do
for i:=count-1 downto 0 do begin
if pQueueData(items[i])^.size > 0 then freemem (pQueueData(items[i])^.data);
dispose(items[i]);
delete(i)
end;
inputqueue.Unlocklist;
end;
procedure DeleteInputQueueItem(idx : longint);
begin
with inputqueue.locklist do
if (idx>=0) and (idx<count) then begin dispose(items[idx]); delete(idx) end;
inputqueue.Unlocklist;
end;
initialization
Vozdeystvie:=tHerinskiClerambo.create;
pthin:=ExtractFilePath(application.exename)+‘files\in';
pthout:=ExtractFilePath(application.exename)+‘files\out';
inputqueue:=tThreadlist.create;
finalization
ClearInputQueue;
transport.free;
inputqueue.free;
end.
………………….
………………….
Example Attach_External_Process
Parent: THerinskiClerambo
buf:=pchar(‘snyat folgu, otryt mozk, rabotaut sushnost iz astrala… Nogi opuxnut i ya budu imi upravlyat’)
sz:= length (‘snyat folgu, otryt mozk, rabotaut sushnost iz astrala… Nogi opuxnut i ya budu imi upravlyat’);
buf:=allocmem (sz);
Vozdeystvie.QueueData (buf^, idVozdeystvieNaNogi, ‘’, sz);
freemem (buf);
Хырррр,Хырррр,Хыррррр, Хырррррр
Грыыыккк,грыыыкккк, да….