| View previous topic :: View next topic |
| Author |
Message |
TehWaffle Expert Cheater
Reputation: 0
Joined: 08 Jul 2006 Posts: 142
|
Posted: Sun May 27, 2007 3:32 am Post subject: [REQUEST] Help with delphi threading |
|
|
Hey.
I've been making a RAT program which connects to a preset list of computers in delphi. I want a continuous connection loop to run in a separate thread using a for loop and a try.. except. I'm using the MSWINSCK.OCX winsock wrapper and I have already created an array of these from the lists.
The thing is, after writing my code I realised I can't access my components through a separate thread (which is a pain in the ass). I suppose I might have to use the APIs but that is kinda shit really and it fucks a lot of my ideas up, so i'm wondering if there's any way at all to run this loop... I have posted my code below for anyone who's interested.
| Code: |
function ConnectToAll(P : Pointer) : LongInt;
var
lst : Integer;
tmplst : Integer;
lstcount : Integer;
begin
Result := 0;
lstcount := Form1.lstOnline.Items.Count;
while 1=1 do
begin
for lst := 1 to lstcount do
begin
if Form1.wsArray[lst].State = sckClosed then
begin
try
Form1.wsArray[lst].Connect();
except
sleep(100);
end;
end;
end;
end;
end;
|
Thanks in advance.
|
|
| Back to top |
|
 |
appalsap Moderator
Reputation: 0
Joined: 27 Apr 2006 Posts: 6753 Location: Pakistan
|
Posted: Sun May 27, 2007 8:21 am Post subject: |
|
|
| why can't you access your components in a seperate thread? also, TThread
|
|
| Back to top |
|
 |
TehWaffle Expert Cheater
Reputation: 0
Joined: 08 Jul 2006 Posts: 142
|
Posted: Sun May 27, 2007 4:11 pm Post subject: |
|
|
Access Violation when I call the Connect method... Have read about TThread but haven't actually tried it yet.
Cheers for the reply though Linda =)
|
|
| Back to top |
|
 |
Uzeil Moderator
Reputation: 6
Joined: 21 Oct 2006 Posts: 2411
|
Posted: Sun May 27, 2007 4:13 pm Post subject: |
|
|
Threading is incredibly easy in Delphi
First, you set up the thread and it's public/private variables to maintain through it's procedures (like maybe you'd want a ping timer in the thread's public variables so the main form can read from it every few seconds to update some label somewhere)
Anywho
Setting up the thread:
| Code: | type TMyThread = class(TThread)
private
{Private variables}
{Public procedures}
public
{Public variables}
{Public Procedures}
Procedure Execute; override; //This will run by itself when you start the thread's execution. Just click your mouse over Execute and press shift+ctrl+c and it'll set it up and automatically throw in the 'inherited' feature. |
There's your thread basis. Now to actually put one in your process.
You just need to shove the variable somewhere that points to TMyThread. We'll say in your form's public variables.
| Code: | Public
{blah blah blah}
MyThread: TMyThread; //it could be Hoodala: TMyThread if you wanted
{blah blah blah} |
Then to make that thread go, just shove it's create anywhere.
| Code: | Procedure Form1.Connect1Click(Sender: TObject); //Looks right?
begin
if MyThread<>nil then
raise exception.create('The connection thread is already running!');
MyThread:=TMyThread.Create(true); {'true' means to create it in suspension.}
MyThread.FreeOnTerminate; {Just something I always do.. this is why I start suspended. So I don't have to free it specifically.}
MyThread.Resume; {off it goes. Immediately upon saying this, the procedure 'Execute' will run and run and run until terminated}
end; |
Termination can be done in the thread or in the form (I do it in the thread... cleaner)
| Code: | Procedure TMyThread.Execute;
begin
inherited;
DoConnect:=true;
While DoConnect do {DoConnect being a public bool variable}
ConnectProcedure;
Terminate; {If the form sets DoConnect to false on, say, a button click, then the thread will terminate after finishing ConnectProcedure if it's already in it.}
end; |
And if you want the form to destroy it, MyThread.Terminate will do just fine.
Disclaimer: I wrote all of this in here without opening Delphi or anything, so there may be some small spelling mistakes :'( Nothing you can't work out.
_________________
Last edited by Uzeil on Sun May 27, 2007 10:49 pm; edited 1 time in total |
|
| Back to top |
|
 |
appalsap Moderator
Reputation: 0
Joined: 27 Apr 2006 Posts: 6753 Location: Pakistan
|
Posted: Sun May 27, 2007 4:44 pm Post subject: |
|
|
| thread termination is an ugly thing because you're not telling the thread of its termination, and the thread could be in the middle of a critical operation (passing resources to your main thread) or it doesn't get a chance to free its resources. The best way is to use a global boolean variable as Uzeil illustrated.
|
|
| Back to top |
|
 |
TehWaffle Expert Cheater
Reputation: 0
Joined: 08 Jul 2006 Posts: 142
|
Posted: Mon May 28, 2007 12:52 am Post subject: |
|
|
Cheers you two. I'ma try it out now.
Uzeil, you must have put a hell of a lot of effort into that post; thanks so much =)
+rep for you both.
Edit:
| Quote: | | Sorry, but you will have to wait 43178 seconds before you can give rep |
Sorry Uzeil, i'll give you your repsicle in 43178 seconds
Edit #2:
After 30mins of converting my project to TThread, I got the same error again. It seem's Windows won't allow me to access my components from the thread...
| Code: |
Form1.wsArray[lst].Connect(); |
I get an ntdll access violation, write of address 00000068. I'm thinking I might have to just use the windows connect API with the wsarray[lst].SocketHandle parameter <_<
|
|
| Back to top |
|
 |
Uzeil Moderator
Reputation: 6
Joined: 21 Oct 2006 Posts: 2411
|
Posted: Mon May 28, 2007 1:51 am Post subject: |
|
|
Are you sure that line is what is causing you to get an access violation?
_________________
|
|
| Back to top |
|
 |
TehWaffle Expert Cheater
Reputation: 0
Joined: 08 Jul 2006 Posts: 142
|
Posted: Mon May 28, 2007 1:54 am Post subject: |
|
|
| Positive, it highlights it when it breaks.
|
|
| Back to top |
|
 |
Uzeil Moderator
Reputation: 6
Joined: 21 Oct 2006 Posts: 2411
|
Posted: Mon May 28, 2007 11:36 pm Post subject: |
|
|
Meh, I don't know next to anything about .Connect()
I would've assumed it was something about the array considering it was an access violation, but I see in the if statement that the array is alright (otherwise you would've broken at the if statement)
I'll look up Connect() in a bit and look for any weaknesses I can find. As for you: I suggest checking out the Delphi Help file, and maybe googling a few examples just to make sure you didn't mess up on something small
_________________
|
|
| Back to top |
|
 |
TehWaffle Expert Cheater
Reputation: 0
Joined: 08 Jul 2006 Posts: 142
|
Posted: Tue May 29, 2007 12:03 am Post subject: |
|
|
| Uzeil wrote: |
I would've assumed it was something about the array considering it was an access violation, but I see in the if statement that the array is alright (otherwise you would've broken at the if statement)
|
Having done a little research into the problem, i've found this page. It states specifically that you cannot set properties or execute methods from a thread, and you thus have to find a workaround method <_< Take a look if you like.
http://www.delphicorner.f9.co.uk/articles/op2.htm
To quote,
| Quote: | Directly above that, I made a call to the Windows API function EnableWindow to disable the button that executes the code. I had to do this because since the VCL is not thread-safe, there's no guarantee I'd be able to successfully access the button's Enabled property safely. So I had to disable it using the Windows API call that performs enabling and disabling of controls.
Moving on, notice how I update the caption of a status bar that's on the bottom of the my form. First, I set the value of a text variable to the message I want displayed:
msg := 'Record ' + IntToStr(RecNo) + ' of ' + IntToStr(RecordCount);
Then I do a SendMessage, sending the WM_SETTEXT message to the status bar:
SendMessage(Form1.StatusBar1.Handle, WM_SETTEXT, 0, LongInt(PChar(msg)));
SendMessage will send a message directly to a control and bypass the window procedure of the form that owns it.
Why did I go to all this trouble? For the very same reason that I used EnableWindow for the button that creates the thread. But unfortunately, unlike the single call to EnableWindow, there's no other way to set the text of a control other than sending it the WM_SETTEXT message.
|
This is a pain, since this connection loop is a vital part of my program - as is the array of winsocks. I'd find it difficult to use the APIs, since as far as I know I can't make them into an array; nor do i really want to use them since it would further clutter up my code =P
Cheers for the replies though Uze. +repsicle.
EDIT:
I've almost done it! I've managed to call the Connect method from my thread. I did this by porting the connect procedure into the execute procedure then using the Synchronise method of the thread. For example:
| Code: |
Synchronize(Form1.wsArray[lst].Connect); |
The only problem with this is that I can only call the method once, any further calls result in an "Address in use" exception. Almost there though!
Cheers for everything guys. Appreciated
|
|
| Back to top |
|
 |
Uzeil Moderator
Reputation: 6
Joined: 21 Oct 2006 Posts: 2411
|
Posted: Tue May 29, 2007 9:37 pm Post subject: |
|
|
I was getting ready to tell you about Synchronize when I saw that quote
Anywho, if you can only access it once... it must mean that you're constantly connected until manually disconnected. I'd say try looking for a Disconnect procedure if you want to constantly reconnect
_________________
|
|
| Back to top |
|
 |
TehWaffle Expert Cheater
Reputation: 0
Joined: 08 Jul 2006 Posts: 142
|
Posted: Wed May 30, 2007 10:04 am Post subject: |
|
|
Aww =P
No, what i'm lookingto do it to connect DIFFERENT winsocks to different hosts. So say I've got wsarray[1], [2] and [3] created - I want to connect all of them. I can connect the first one (I even do a wait until the socket is not at stage 6) but then when i try to connect wsArray[2] using sync i get an address in use...
Cheers Uze. You're a great dude =P
EDIT:
Emotion3's connection loop is almost working =D How awesome!! Still fails when it actually successfully connects though with an AIU... Cheers for your help everyone. I fixed the first AIU error by getting rid of my try...except cause it wasn't working and replacing it with an if.
Thanks a lot. Now to work on this last issue, then the client!
- Simon
Last edited by TehWaffle on Wed May 30, 2007 2:59 pm; edited 1 time in total |
|
| Back to top |
|
 |
Renkokuken GO Moderator
Reputation: 4
Joined: 22 Oct 2006 Posts: 3249
|
Posted: Wed May 30, 2007 2:19 pm Post subject: |
|
|
Thanks to me for being a test bitch!
Thanks for shutting me down when I had to gooo~! <3
|
|
| Back to top |
|
 |
TehWaffle Expert Cheater
Reputation: 0
Joined: 08 Jul 2006 Posts: 142
|
Posted: Wed May 30, 2007 2:20 pm Post subject: |
|
|
Entirely different thing, renko. E2 was a hobby, fun project coded in VB6 and was reverse connecting. E3 is the real shit! =D
But yeah, thanks for letting me shut you down! =D
|
|
| Back to top |
|
 |
Renkokuken GO Moderator
Reputation: 4
Joined: 22 Oct 2006 Posts: 3249
|
Posted: Wed May 30, 2007 2:33 pm Post subject: |
|
|
| TehWaffle wrote: | Entirely different thing, renko. E2 was a hobby, fun project coded in VB6 and was reverse connecting. E3 is the real shit! =D
But yeah, thanks for letting me shut you down! =D | Oh yeah...
I really should go to sleep. Been up for 48 hours now.
|
|
| Back to top |
|
 |
|