2025-04-27 07:49:33 -04:00

241 lines
5.0 KiB
C

/*++
Copyright (c) 1996 Microsoft Corporation
This program is released into the public domain for any purpose.
Module Name:
worker.c
Abstract:
This module is a simple work item for the Multi-Threaded ISAPI example
Revision History:
--*/
#include <windows.h>
#include <httpext.h>
#include "worker.h"
#include <time.h>
#include <stdlib.h>
//
// Constants
//
//
// The set of response headers we want to include with the servers. Note
// this includes the header terminator
//
#define RESPONSE_HEADERS "Content-Type: text/html\r\n\r\n"
//
// Globals
//
//
// This global variable maintains the current state about the
// the lottery number generated.
//
// The lottery number is generated using a combination
// of the sequence number and a random number generated on the fly.
//
DWORD g_dwLotteryNumberSequence = 0;
//
// Critical section to protect the global counter.
//
CRITICAL_SECTION g_csGlobal;
//
// Prototypes
//
VOID
GenerateLotteryNumber(
LPDWORD pLotNum1,
LPDWORD pLotNum2
);
//
// Functions
//
BOOL
InitializeLottery(
VOID
)
/*++
Routine Description:
Sets up the initial state for the lottery number generator
Returns:
TRUE on success, FALSE on failure
--*/
{
time_t pTime;
//
// Seed the random number generator
//
srand(time(&pTime));
g_dwLotteryNumberSequence = rand();
InitializeCriticalSection( &g_csGlobal );
return TRUE;
}
BOOL
SendLotteryNumber(
EXTENSION_CONTROL_BLOCK * pecb
)
/*++
Routine Description:
This function sends a randomly generated lottery number back to the client
Arguments:
pecb - pointer to EXTENSION_CONTROL_BLOCK for this request
Returns:
TRUE on success, FALSE on failure
--*/
{
BOOL fRet;
char rgBuff[2048];
//
// Send the response headers and status code
//
fRet = pecb->ServerSupportFunction(
pecb->ConnID, /* ConnID */
HSE_REQ_SEND_RESPONSE_HEADER, /* dwHSERRequest */
"200 OK", /* lpvBuffer */
NULL, /* lpdwSize. NULL=> send string */
(LPDWORD ) RESPONSE_HEADERS); /* header contents */
if ( fRet )
{
CHAR rgchLuckyNumber[40];
DWORD dwLotNum1, dwLotNum2;
DWORD cb;
CHAR rgchClientHost[200] = "LT";
DWORD cbClientHost = 200;
if ( !pecb->GetServerVariable(pecb->ConnID,
"REMOTE_HOST",
rgchClientHost,
&cbClientHost))
{
// No host name is available.
// Make up one
strcpy(rgchClientHost, "RH");
}
else
{
// terminate with just two characters
rgchClientHost[2] = '\0';
}
//
// Generate a lottery number, generate the contents of body and
// send the body to client.
//
GenerateLotteryNumber( &dwLotNum1, &dwLotNum2);
// Lottery Number format is: Number-2letters-Number.
wsprintf( rgchLuckyNumber, "%03d-%s-%05d",
dwLotNum1,
rgchClientHost,
dwLotNum2);
//
// Body of the message sent back.
//
cb = wsprintf( rgBuff,
"<head><title>Lucky Number</title></head>\n"
"<body><center><h1>Lucky Corner </h1></center><hr>"
"<h2>Your lottery number is: "
" <i> %s </i></h2>\n"
"<p><hr></body>",
rgchLuckyNumber);
fRet = pecb->WriteClient (pecb->ConnID, /* ConnID */
(LPVOID ) rgBuff, /* message */
&cb, /* lpdwBytes */
0 ); /* reserved */
}
return ( fRet ? HSE_STATUS_SUCCESS : HSE_STATUS_ERROR);
} /* SendLotteryNumber */
VOID
TerminateLottery(
VOID
)
{
DeleteCriticalSection( &g_csGlobal );
}
VOID
GenerateLotteryNumber(
LPDWORD pLotNum1,
LPDWORD pLotNum2
)
{
DWORD dwLotteryNum;
DWORD dwModulo;
//
// Obtain the current lottery number an increment the counter
// To keep this multi-thread safe use critical section around it
//
EnterCriticalSection( &g_csGlobal);
dwLotteryNum = g_dwLotteryNumberSequence++;
LeaveCriticalSection( &g_csGlobal);
// obtain a non-zero modulo value
do {
dwModulo = rand();
} while ( dwModulo == 0);
// split the lottery number into two parts.
*pLotNum1 = (dwLotteryNum / dwModulo);
*pLotNum2 = (dwLotteryNum % dwModulo);
return;
} // GenerateLotteryNumber()