Everybody, please help to change the below ISAPI Extention for the MASM32 source

Started by haoren108, March 09, 2013, 02:00:25 PM

Previous topic - Next topic

haoren108

各位大侠,请帮忙把以下CPP的ISAPI扩展网站程序转为MASM32源码。劳烦各位啦
Everybody, please help to change the below ISAPI Extention for the MASM32 source code.Thanks.

//isapi.cpp
/*Tips:
This is an isapi Extention to test Concurrent performance among VC6,BC6,DEV-CPP,OpenWatcom.

It first gets two parameters from "param.txt". One is the upper bound of an addition. The other one is to format the output string.

*/


//#define Export extern "C" _declspec(dllexport)
//VC6 must define as the below way :
#define Export  ;

#include "stdafx.h"
#include <httpext.h>
#pragma comment(lib,"USER32.lib")

static HANDLE g_hModule;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD  dwReason, LPVOID lpReserved)
{
    switch(dwReason)
    {
    case DLL_PROCESS_ATTACH:
        g_hModule = hModule;
        break;
    case DLL_PROCESS_DETACH:
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

void GetCalcParam(DWORD &MaxValue, BOOL &bFixLen)
{
    char FileName[300];
    ::GetModuleFileName((HMODULE)g_hModule, FileName, 300);
    strcpy(strrchr(FileName, '\\') + 1, "param.txt");//param.txt:99999,8

    MaxValue = 100;
    bFixLen = FALSE;

    FILE *pFile = fopen(FileName, "r");
    if(pFile == NULL)
        return;
    fscanf(pFile, "%d%d", &MaxValue, &bFixLen);
    if(MaxValue > 100000)
        MaxValue = 100000;
    fclose(pFile);
}




Export BOOL WINAPI GetExtensionVersion(OUT HSE_VERSION_INFO * pVer)
{
    pVer->dwExtensionVersion = MAKELONG(HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
    strcpy(pVer->lpszExtensionDesc, "ISAPI Hello World");
    return TRUE;
}

Export DWORD WINAPI HttpExtensionProc(IN EXTENSION_CONTROL_BLOCK *pECB)
{
    DWORD MaxValue;
    BOOL bFixLen;
    GetCalcParam(MaxValue, bFixLen);
    const char *pTimeFormat = bFixLen ? "Time elapsed is%05d ms<hr>\r\n" : "Time elapsed is %d ms<hr>\r\n";

    const DWORD BufSize = MaxValue * 30 + 1024;
    char *pDataBuf = (char *)malloc(BufSize);

    const DWORD PreBufLen = 100;
    char *pResultStr = pDataBuf + PreBufLen;

    //Data
    DWORD Len = 0, Count = 0;
    DWORD T1 = GetTickCount();
    for(DWORD i = 1; i <= MaxValue; i++)
    {
        Count += i;
        Len += wsprintf(pResultStr + Len, "From 1 to %d=%d<br>\r\n", i, Count);
    }
    DWORD T2 = GetTickCount();

    Len += wsprintf(pResultStr + Len, "</body></html>");
    assert(Len < BufSize - PreBufLen - 1);

    //PreData
    DWORD PreDataLen = wsprintf(pDataBuf, "<html><body>");
    PreDataLen += wsprintf(pDataBuf + PreDataLen, pTimeFormat, T2 - T1);
    assert(PreDataLen < PreBufLen);
    Len += PreDataLen;
    pResultStr = pDataBuf + PreBufLen - PreDataLen;
    memmove(pResultStr, pDataBuf, PreDataLen);

    //Header
    char HeadStr[256];
    wsprintf(HeadStr, "Content-Type: text/html\r\nContent-Length: %d\r\n\r\n", Len);
    pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER,
        "200 OK", NULL, (DWORD *)HeadStr);

    assert(strlen(pResultStr) == Len);
    pECB->WriteClient(pECB->ConnID, (void *)pResultStr, &Len, 0);

    free(pDataBuf);
    return HSE_STATUS_SUCCESS;
}

Export BOOL WINAPI TerminateExtension(IN DWORD dwFlags)
{
    return TRUE;
}


// stdafx.h : include file for standard system include files,
//  or project specific include files that are used frequently, but
//      are changed infrequently
//
#if !defined(AFX_STDAFX_H__21F009DC_C3E5_4641_9678_884989ABE6AA__INCLUDED_)
#define AFX_STDAFX_H__21F009DC_C3E5_4641_9678_884989ABE6AA__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// Insert your headers here
#define WIN32_LEAN_AND_MEAN      // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <assert.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__21F009DC_C3E5_4641_9678_884989ABE6AA__INCLUDED_)




//def.txt
#define   HSE_VERSION_MAJOR           4      //major version of this spec
#define   HSE_VERSION_MINOR           0      //minor version of this spec
#define   HSE_LOG_BUFFER_LEN         80
#define   HSE_MAX_EXT_DLL_NAME_LEN  256
#define   HSE_VERSION     MAKELONG( HSE_VERSION_MINOR, HSE_VERSION_MAJOR )

//the following are the status codes returned by the Extension DLL
#define   HSE_STATUS_SUCCESS                       1
#define   HSE_STATUS_SUCCESS_AND_KEEP_CONN         2
#define   HSE_STATUS_PENDING                       3
#define   HSE_STATUS_ERROR                         4

//The following are the values to request services with the
//ServerSupportFunction().
//Values from 0 to 1000 are reserved for future versions of the interface
#define   HSE_REQ_BASE                             0
#define   HSE_REQ_SEND_URL_REDIRECT_RESP           ( HSE_REQ_BASE + 1 )
#define   HSE_REQ_SEND_URL                         ( HSE_REQ_BASE + 2 )
#define   HSE_REQ_SEND_RESPONSE_HEADER             ( HSE_REQ_BASE + 3 )
#define   HSE_REQ_DONE_WITH_SESSION                ( HSE_REQ_BASE + 4 )
#define   HSE_REQ_END_RESERVED                     1000

//These are Microsoft specific extensions
#define   HSE_REQ_MAP_URL_TO_PATH                  (HSE_REQ_END_RESERVED+1)
#define   HSE_REQ_GET_SSPI_INFO                    (HSE_REQ_END_RESERVED+2)
#define   HSE_APPEND_LOG_PARAMETER                 (HSE_REQ_END_RESERVED+3)
#define   HSE_REQ_IO_COMPLETION                    (HSE_REQ_END_RESERVED+5)
#define   HSE_REQ_TRANSMIT_FILE                    (HSE_REQ_END_RESERVED+6)
#define   HSE_REQ_REFRESH_ISAPI_ACL                (HSE_REQ_END_RESERVED+7)
#define   HSE_REQ_IS_KEEP_CONN                     (HSE_REQ_END_RESERVED+8)
#define   HSE_REQ_ASYNC_READ_CLIENT                (HSE_REQ_END_RESERVED+10)
#define   HSE_REQ_GET_IMPERSONATION_TOKEN          (HSE_REQ_END_RESERVED+11)
#define   HSE_REQ_MAP_URL_TO_PATH_EX               (HSE_REQ_END_RESERVED+12)
#define   HSE_REQ_ABORTIVE_CLOSE                   (HSE_REQ_END_RESERVED+14)
#define   HSE_REQ_GET_CERT_INFO_EX                 (HSE_REQ_END_RESERVED+15)
#define   HSE_REQ_SEND_RESPONSE_HEADER_EX          (HSE_REQ_END_RESERVED+16)
#define   HSE_REQ_CLOSE_CONNECTION                 (HSE_REQ_END_RESERVED+17)
#define   HSE_REQ_IS_CONNECTED                     (HSE_REQ_END_RESERVED+18)
#define   HSE_REQ_EXTENSION_TRIGGER                (HSE_REQ_END_RESERVED+20)

//Bit Flags for TerminateExtension
//
//HSE_TERM_ADVISORY_UNLOAD - Server wants to unload the extension,
//extension can return TRUE if OK, FALSE if the server should not
//unload the extension
//
//HSE_TERM_MUST_UNLOAD - Server indicating the extension is about to be
//unloaded, the extension cannot refuse.
//
#define HSE_TERM_ADVISORY_UNLOAD                   0x00000001
#define HSE_TERM_MUST_UNLOAD                       0x00000002

//Flags for IO Functions, supported for IO Funcs.
//TF means ServerSupportFunction( HSE_REQ_TRANSMIT_FILE)
//

# define HSE_IO_SYNC                      0x00000001   //for WriteClient
# define HSE_IO_ASYNC                     0x00000002   //for WriteClient/TF
# define HSE_IO_DISCONNECT_AFTER_SEND     0x00000004   //for TF
# define HSE_IO_SEND_HEADERS              0x00000008   //for TF
# define HSE_IO_NODELAY                   0x00001000   //turn off nagling

typedef   LPVOID          HCONN;
typedef struct _EXTENSION_CONTROL_BLOCK {

    DWORD     cbSize;                 //size of this struct.
    DWORD     dwVersion;              //version info of this spec
    HCONN     ConnID;                 //Context number not to be modified!
    DWORD     dwHttpStatusCode;       //HTTP Status code
    CHAR      lpszLogData[HSE_LOG_BUFFER_LEN];//null terminated log info specific to this Extension DLL

    LPSTR     lpszMethod;             //REQUEST_METHOD
    LPSTR     lpszQueryString;        //QUERY_STRING
    LPSTR     lpszPathInfo;           //PATH_INFO
    LPSTR     lpszPathTranslated;     //PATH_TRANSLATED

    DWORD     cbTotalBytes;           //Total bytes indicated from client
    DWORD     cbAvailable;            //Available number of bytes
    LPBYTE    lpbData;                //pointer to cbAvailable bytes

    LPSTR     lpszContentType;        //Content type of client data

    BOOL (WINAPI * GetServerVariable) ( HCONN       hConn,
                                        LPSTR       lpszVariableName,
                                        LPVOID      lpvBuffer,
                                        LPDWORD     lpdwSize );

    BOOL (WINAPI * WriteClient)  ( HCONN      ConnID,
                                   LPVOID     Buffer,
                                   LPDWORD    lpdwBytes,
                                   DWORD      dwReserved );

    BOOL (WINAPI * ReadClient)  ( HCONN      ConnID,
                                  LPVOID     lpvBuffer,
                                  LPDWORD    lpdwSize );

    BOOL (WINAPI * ServerSupportFunction)( HCONN      hConn,
                                           DWORD      dwHSERequest,
                                           LPVOID     lpvBuffer,
                                           LPDWORD    lpdwSize,
                                           LPDWORD    lpdwDataType );

} EXTENSION_CONTROL_BLOCK, *LPEXTENSION_CONTROL_BLOCK;

jj2007

Hi,

You need help to translate this code from C++ to Masm32?
What do you want to do with this code?

qWord

Quote from: haoren108 on March 09, 2013, 02:00:25 PM
各位大侠,请帮忙把以下CPP的ISAPI扩展网站程序转为MASM32源码。劳烦各位啦
Everybody, please help to change the CPP's ISAPI site procedures for the MASM32 source code.Thanks.
see here
MREAL macros - when you need floating point arithmetic while assembling!

Vortex

Hi haoren108,

You would like to read the forum rules :

QuoteThe NO HELP DESK Rule.
10. This forum is a forum of members, it is not a help desk and should not be treated as one. The high quality of assistance in the MASM Forum over many years is based on the goodwill of other members who have made their time available to help other members and it should be treated in this manner.

haoren108

Nice to have your reply.
I programed ISAPI Extensions in C/CPP to make my website before. Longing for the most effective code, I searched the internet and found masm32 by chance.Then i tried hard to build my ISAPI in MASM32,but i only met roadblocks. The key problem is how to respond in function:
HttpExtensionProc proc pECB:EXTENSION_CONTROL_BLOCK
   mov szBuffer,"hello isapi"
   invoke pECB.WriteClient,pECB.ConnID,szBuffer,sizeof szBuffer,0);

   mov eax,HSE_STATUS_SUCCESS
   ret
HttpExtensionProc endp

So i need your help.


qWord

Quote from: haoren108 on March 09, 2013, 11:18:49 PMLonging for the most effective code, I searched the internet and found masm32 by chance.
why do you think that Assembler yields in more efficient code here?
For your problem, you need to declare the correct pointer type in the structure. Also, a register must be used to reference the structure:
;...
; declare function pointer
GETSERVERVARIABLE typedef proto hConn:HCONN,lpszVariableName:LPSTR,lpvBuffer:LPVOID,lpdwSize:LPDWORD
PGETSERVERVARIABLE typedef ptr GETSERVERVARIABLE
;...

EXTENSION_CONTROL_BLOCK struct
; other members ...
GetServerVariable PGETSERVERVARIABLE ?
; other members ...
EXTENSION_CONTROL_BLOCK ends
;...
mov edx,pECB
invoke [edx].EXTENSION_CONTROL_BLOCK.GetServerVariable,...
MREAL macros - when you need floating point arithmetic while assembling!

haoren108

Quote from: qWord on March 09, 2013, 11:41:54 PM
Quotewhy do you think that Assembler yields in more efficient code here?
i have had a test among vc6,bc6,Dev-Cpp,openWatcom. The test makes me interested in rebuild isapi in MASM32 so as to test again.

HttpExtensionProc proc pECB:EXTENSION_CONTROL_BLOCK
   local @szWord[99]:LPVOID
   local @dwTemp:LPDWORD

   mov edx,pECB
   invoke [edx].EXTENSION_CONTROL_BLOCK.GetServerVariable,[edx].EXTENSION_CONTROL_BLOCK.ConnID,"REMOTE_ADDR",@szWord,addr @dwTemp

   mov eax,HSE_STATUS_SUCCESS
   ret
HttpExtensionProc endp

Just now,i met error:
my.asm(48) : error A2084: constant value too large

my.asm(48) : error A2114: INVOKE argument type mismatch : argument : 2
my.asm(47) : error A2022: instruction operands must be the same size
Microsoft (R) Incremental Linker Version 5.12.8078

What's wrong ?

qWord,the below way is invalid:
fn [edx].EXTENSION_CONTROL_BLOCK.GetServerVariable...


dedndave

i don't think you put prototypes inside a structure definition   :P
i have never seen a struct quite like that, before
but, my guess would be they are pointers to functions - type them as LPVOID

qWord

MASM's INVOKE does not handle strings - replace it with the fn-macro from the MASM SDK:

include \masm32\include\masm32rt.inc
;...
fn [edx].EXTENSION_CONTROL_BLOCK.GetServerVariable,[edx].EXTENSION_CONTROL_BLOCK.ConnID ,"HELLO",NULL,NULL


Quote from: dedndave on March 10, 2013, 12:28:57 AM
i don't think you put prototypes inside a structure definition   :P
that is no problem.

Quote from: dedndave on March 10, 2013, 12:28:57 AMi have never seen a struct quite like that, before
but, my guess would be they are pointers to functions - type them as LPVOID
no, that is wrong because he want to use INVOKE  :t
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

as for protoypes inside a struct....
that still doesn't make sense to me - lol
but, if qWord says it's right, i will believe him   :t

qWord

Quote from: dedndave on March 10, 2013, 03:31:05 AM
as for protoypes inside a struct....
that still doesn't make sense to me - lol
why should this make no sense?
You are maybe also surprised that you we can declare and use a pointer type for a structure inside it's declaration.
MREAL macros - when you need floating point arithmetic while assembling!

dedndave

i thought i'd sit back and see how this thread develops - see what i can learn   :biggrin:

haoren108

Quote from: dedndave on March 10, 2013, 09:46:26 AM
i thought i'd sit back and see how this thread develops - see what i can learn   :biggrin:
Nice to have your supports.
I'm sorry to say that i have to try on.

japheth

Quote from: haoren108 on March 10, 2013, 10:36:37 AM
I'm sorry to say that i have to try on.

Then you just didn't read carefully qword's suggestions.

Sample for HttpExtensionProc:


HttpExtensionProc proc public uses ebx pECB:ptr EXTENSION_CONTROL_BLOCK

local dwLength:DWORD
local dwConLength:DWORD
local hti:HSE_TF_INFO
local szHeader[512]:byte

DebugOut "ISAPI1: HttpExtensionProc"

mov ebx,pECB
assume ebx:ptr EXTENSION_CONTROL_BLOCK

if TRANSMIT_FILE
invoke CreateFile, CStr("d:\html\crackdown.htm"), GENERIC_READ, FILE_SHARE_READ,\
0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, 0
.if (eax == INVALID_HANDLE_VALUE)
mov [ebx].dwHttpStatusCode, 404
mov eax, HSE_STATUS_ERROR
jmp exit
.endif
mov hti.hFile, eax
invoke GetFileSize, hti.hFile, NULL
mov dwConLength, eax

invoke wsprintf, addr szHeader, \
CStr(<"Content-Type: %s",0dh,0ah,"Content-Length: %i",0dh,0ah,0dh,0ah>),
CStr("text/html"), dwConLength
mov hti.HeadLength, eax

if 0
invoke [ebx].ServerSupportFunction, [ebx].ConnID, \
HSE_REQ_SEND_RESPONSE_HEADER,\
0, 0, addr szHeader
endif

mov hti.pfnHseIO, offset IOCompletionCallback
mov hti.pContext, 0
mov hti.pszStatusCode, CStr("200 OK")
mov hti.BytesToWrite,0
mov hti.Offset_,0
lea eax, szHeader
mov hti.pHead, eax
mov hti.pTail, 0
mov hti.TailLength, 0
mov hti.dwFlags, HSE_IO_SEND_HEADERS or HSE_IO_ASYNC

invoke [ebx].ServerSupportFunction, [ebx].ConnID, \
HSE_REQ_TRANSMIT_FILE,\
addr hti, 0, 0
.if (eax)
DebugOut "ISAPI1: HttpExtensionProc leaving with HSE_STATUS_PENDING"
mov eax, HSE_STATUS_PENDING
.else
DebugOut "HSE_REQ_TRANSMIT_FILE doesnt work"
mov eax, HSE_STATUS_ERROR
.endif
endif

if SEND_URL
mov dwLength, sizeof szHeader
invoke lstrcpy, addr szHeader, CStr("/Test/TestForm.html")
invoke [ebx].ServerSupportFunction, [ebx].ConnID, \
HSE_REQ_SEND_URL,\
addr szHeader, addr dwLength, 0
.if (eax)
DebugOut "ISAPI1: HttpExtensionProc leaving with HSE_STATUS_SUCCESS_AND_KEEP_CONN"
mov eax, HSE_STATUS_SUCCESS_AND_KEEP_CONN
.else
DebugOut "HSE_REQ_SEND_URL doesnt work"
mov eax, HSE_STATUS_ERROR
.endif
endif


exit:
ret
assume ebx:nothing

HttpExtensionProc endp


EDIT: I just found a working ISAPI extension sample, written in assembly: http://www.japheth.de/Download/Samples/AsmIsapi.zip