241 lines
5.0 KiB
C
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()
|
|
|
|
|