I'm trying to use HLA to program CGI's. I can write stuff to the screen using stdout.put, and figured out how to read environment variables using _GetEnvironmentVariableA@12, but I'm stuck on reading input from a POST method (I suppose if I wanted I could use GET, but now that I'm stuck I'm stubborn as a mule ;) )...I tried stdin.get, but it didn't work (I suspect maybe it's waiting for the enter key?). After searching the archives here I tried importing MASM's stdin routine and adapting someone else's code, but that didn't work either. Then I tried something else I found in the archives using a few windows procedures (GetStdHandle, SetConsoleMode, ReadFile). It still doesn't work.

I checked the windows procedures' returns...GetStdHandle successfully returns something, but SetConsoleMode and ReadFile are returning 0 in EAX.

For any of you who know HLA here's my current code:


program CGItest;
#include("stdlib.hhf");
#include("win32.hhf");
#include("win32more.hhf"); // additional windows procedures
#include("masm.hhf"); // (attempted) MASM import
#asm
includelib \hla\hlalib\masm32.lib
#endasm

/**********************************************************
Main Program
**********************************************************/

static
env_buffer: string;
env_var: string;
blah: uns32;

begin CGItest;
stralloc(256);
mov(eax, env_buffer);
stralloc(80);
mov(eax, env_var);

stdout.put("Content-type: text/html",nl,nl);

stdout.put("<HTML>",nl,"<BODY TEXT=""FFFFFF"" BGCOLOR=""000000"">",nl);

mov(env_buffer,ebx);

str.cpy("REQUEST_METHOD", env_var);
winmore.GetEnv(256,ebx,env_var);
mov(eax, (type dword [ebx-4]));

str.eq(ebx, "POST");
if (eax == 0) then
stdout.put(" Error: Method must be ""POST"".<BR>",nl," ");
stdout.puts(env_buffer);
stdout.put("<BR><BR>",nl,nl);
// jmp endtest;
endif;

str.cpy("CONTENT_TYPE", env_var);
winmore.GetEnv(256,ebx,env_var);
mov(eax, (type dword [ebx-4]));
str.cpy("application/x-www-form-urlencoded", env_var);
str.eq(ebx, env_var);
if (eax == 0) then
stdout.put(" Error: This CGI must be accessed from a form.<BR>",nl," ");
stdout.puts(env_buffer);
stdout.put("<BR><BR>",nl,nl);
// jmp endtest;
endif;

str.cpy("CONTENT_LENGTH", env_var);
winmore.GetEnv(256,ebx,env_var);
mov(eax, (type dword [ebx-4]));

stdout.put("Content length: ");
stdout.puts(ebx);
stdout.put("<BR><BR>",nl,nl);

mov(0,ecx);
mov(0,eax);
while(ecx < (type dword [ebx-4])) do
mov(eax, edx);
shl(1,eax);
shl(3,edx);
add(edx,eax);
add((type dword (type byte [ebx])), eax);
sub('0',eax);
inc(ecx);
endwhile;

mov(0,ecx);
mov(eax,edx);
inc(eax);
mov(env_buffer, ebx);
mov(eax,(type dword [ebx-4]));
stdout.put(eax, " ");
masm.StdIn(ebx,eax);
stdout.put(eax, " ");
winmore.GetStdHandle(winmore.STD_INPUT_HANDLE);
stdout.put(eax, " ");
push(eax);
winmore.SetConsoleMode(eax,winmore.ENABLE_LINE_INPUT | winmore.ENABLE_ECHO_INPUT | winmore.ENABLE_PROCESSED_INPUT);
stdout.put(eax, " ");
pop(eax);
winmore.ReadFile(eax,env_buffer,eax,&blah,0);
stdout.put(eax, " ");
stdout.put(blah, " ");
mov(0, (type byte [ebx+ecx]));

stdout.put(" Content: ");
stdout.puts(env_buffer);
stdout.put("<BR><BR>",nl,nl);


endtest:
stdout.put(" End of test CGI.",nl);
stdout.put("</BODY>",nl,"</HTML>");

strfree(env_var);
strfree(env_buffer);
end CGItest;


Any help would be appreciated...I'm still learning HLA, and I don't know hardly any MASM, but if anyone has any ideas...

P.S. - those of you not used to HLA, the instructions are backwards of MASM... mov(eax, ebx) is equivalent to mov ebx, eax (I think...)
Posted on 2002-10-31 21:00:13 by sirchess2
first, is the filehandle (always) equal to the content-length?
winmore.ReadFile(eax,env_buffer,eax,&blah,0);
Maybe the second eax is supposec to be ebx?

Second, does stdout.put, and the other calls, preserve eax,ebx, etc?


winmore.GetStdHandle(winmore.STD_INPUT_HANDLE);
stdout.put(eax, " ");
push(eax);

I don't know the specifics of HLA, but most functions in other languages will return values, include success flags in eax. You should probably grab a value and save it into a well labeled memory location, that way your code will be more readable as a side effect.
Posted on 2002-11-01 01:34:18 by eet_1024
I figured it out (partially). The way I had my loop for extracting the content length from the env_buffer string, I wasn't zero-extending each character's value, giving me lengths of +/- 2 billion :eek:

I'm also getting some text from stdin now (before I got nothing), so I think I'm almost set.

Thanks a lot for the help...I'll try using variables more like you said, eet...Faster programs aren't any good if they dont run, right? ;)

Does anyone know if HLA has a string-to-number function? It'd probably be more reliable than my code...
Posted on 2002-11-01 16:28:51 by sirchess2
Ok, I've got it mostly figured out now. The only problem I have is that 2 bytes of stdin data get cut off, and it adds an <ENTER> character...so, for example:

"testtxt=test...&submit=Subm", CRLF
-or-
"submit=Submit&testtxt=test.",CRLF

Is there any way to retrieve the last two characters or should I just add an unimportant "filler" value at the end of my form?

(BTW, I did a test and apparently stdout.put doesn't modify EAX...)



program CGItest;
#include("stdlib.hhf");
#include("win32.hhf");
#include("win32more.hhf");
#include("masm.hhf");
#asm
includelib \hla\hlalib\masm32.lib
#endasm

/**********************************************************
Main Program
**********************************************************/

static
env_buffer: string;
env_var: string;
blah: uns32;

begin CGItest;
stralloc(256);
mov(eax, env_buffer);
stralloc(80);
mov(eax, env_var);

stdout.put("Content-type: text/html",nl,nl);

stdout.put("<HTML>",nl,"<BODY TEXT=""FFFFFF"" BGCOLOR=""000000"">",nl);

/* stdout.put(" <I>", nl);
mov(1,ebx);
while(ebx < 5) do
stdout.put(" 1<BR>");
stdout.put(nl);
inc(ebx);
endwhile;*/

mov(env_buffer,ebx);

str.cpy("REQUEST_METHOD", env_var);
winmore.GetEnv(256,ebx,env_var);
mov(eax, (type dword [ebx-4]));

str.eq(ebx, "POST");
if (eax == 0) then
stdout.put(" Error: Method must be ""POST"".<BR>",nl," ");
stdout.puts(env_buffer);
stdout.put("<BR><BR>",nl,nl);
// jmp endtest;
endif;

str.cpy("CONTENT_TYPE", env_var);
winmore.GetEnv(256,ebx,env_var);
mov(eax, (type dword [ebx-4]));
str.cpy("application/x-www-form-urlencoded", env_var);
str.eq(ebx, env_var);
if (eax == 0) then
stdout.put(" Error: This CGI must be accessed from a form.<BR>",nl," ");
stdout.puts(env_buffer);
stdout.put("<BR><BR>",nl,nl);
// jmp endtest;
endif;

str.cpy("CONTENT_LENGTH", env_var);
winmore.GetEnv(256,ebx,env_var);
mov(eax, (type dword [ebx-4]));

stdout.put("Content length: ");
stdout.puts(ebx);
stdout.put("<BR>",nl);

mov(0,ecx);
mov(0,eax);
while(ecx < (type dword [ebx-4])) do
mov(eax, edx);
shl(1,eax);
shl(3,edx);
add(edx,eax);
movzx((type byte [ebx+ecx]),edx);
add(edx, eax);
sub('0',eax);
inc(ecx);
endwhile;

stdout.put("Extracted Content Length: ", (type int32 eax),"<BR><BR>",nl,nl);

mov(env_buffer, ebx);
mov(0, (type byte [ebx+eax]));
dec(eax);
dec(eax);
mov(eax,(type dword [ebx-4]));

stdout.put("Stdin: ");
mov(0,ecx);
while((type int32 ecx) < (type int32 eax)) do
push(eax);
stdin.getc();
mov(al, (type byte [ebx+ecx]));
stdout.put((type char al));
inc(ecx);
pop(eax);
endwhile;
stdout.put("<BR><BR>",nl,nl);

stdout.put(" Content: ");
stdout.puts(env_buffer);
stdout.put("<BR><BR>",nl,nl);


endtest:
stdout.put(" End of test CGI.",nl);
stdout.put("</BODY>",nl,"</HTML>");

strfree(env_var);
strfree(env_buffer);

mov(0,eax);
end CGItest;
Posted on 2002-11-01 18:32:05 by sirchess2
sirchess2,

I would try for an answer from Randy Hyde on this one as he is the author. I don't think Randy has posted in this forum as yet but I know he posts in the alt lang asm newsgroup so you may have some success there.

Regards,

hutch@movsd.com
Posted on 2002-11-01 20:45:32 by hutch--
Forgive my idiocity, but what's a newsgroup, and how does one subscribe/browse to it? :o
Posted on 2002-11-01 21:11:27 by sirchess2
Network News is a web application that has thread forums, like this HTTP forum, but it has it's own protocal NNTP. A quick google, tucows, etc for a News Reader/Browser should find the app you're looking for. Most ISPs provide NNTP servers. You can also do a google for servers.
Posted on 2002-11-02 02:08:02 by eet_1024