2401 lines
68 KiB
C
2401 lines
68 KiB
C
/*++
|
||
|
||
Copyright (C) Microsoft Corporation, 1996 - 1999
|
||
|
||
Module Name:
|
||
|
||
Client.c
|
||
|
||
Abstract:
|
||
|
||
Client side of Data Transfer test.
|
||
|
||
Author:
|
||
|
||
Brian Wong (t-bwong) 10-Mar-1996
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include <rpcperf.h>
|
||
#include <assert.h>
|
||
#include <WinINet.h>
|
||
|
||
#include <DataTran.h>
|
||
#include <DTCommon.h>
|
||
|
||
//
|
||
// Uncomment this for debugging (to make sure files are sent
|
||
// properly). Note that under normal circumstances, only
|
||
// the receiver retains the temp file - if A creates a temp
|
||
// file to sends it to B (ie B gets a copy of the file), then after the
|
||
// transfer A deletes its temp file while B keeps its copy.
|
||
//
|
||
// If DELETE_TEMP_FILES is defined, then B will also delete its copy
|
||
// of the temp file.
|
||
//
|
||
#define DELETE_TEMP_FILES
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
|
||
#ifdef MAC
|
||
extern void _cdecl PrintToConsole(const char *lpszFormat, ...) ;
|
||
extern unsigned long ulSecurityPackage ;
|
||
#else
|
||
#define PrintToConsole printf
|
||
unsigned long ulSecurityPackage = RPC_C_AUTHN_WINNT ;
|
||
#endif
|
||
|
||
// Usage
|
||
|
||
const char *USAGE = "-n <threads> -a <authnlevel> -s <server> -t <protseq>\n"
|
||
"Server controls iterations, test cases, and compiles the results.\n"
|
||
"AuthnLevel: none, connect, call, pkt, integrity, privacy.\n"
|
||
"Default threads=1, authnlevel=none\n";
|
||
|
||
#define CHECK_RET(status, string) if (status)\
|
||
{ PrintToConsole("%s failed -- %lu (0x%08X)\n", string,\
|
||
(unsigned long)status, (unsigned long)status);\
|
||
return (status); }
|
||
|
||
static HINTERNET hInternet = NULL;
|
||
|
||
//
|
||
// Note: ulBufferSize should be greater than the largest chunk size used.
|
||
//
|
||
const unsigned long ulBufferSize = 512*1024L;
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
|
||
RPC_STATUS DoRpcBindingSetAuthInfo(handle_t Binding)
|
||
{
|
||
if (AuthnLevel != RPC_C_AUTHN_LEVEL_NONE)
|
||
return RpcBindingSetAuthInfo(Binding,
|
||
NULL,
|
||
AuthnLevel,
|
||
ulSecurityPackage,
|
||
NULL,
|
||
RPC_C_AUTHZ_NONE);
|
||
else
|
||
return(RPC_S_OK);
|
||
}
|
||
|
||
/********************************************************************
|
||
* Test wrappers
|
||
********************************************************************/
|
||
|
||
//===================================================================
|
||
// Regular RPC
|
||
//===================================================================
|
||
unsigned long Do_S_to_C_NBytes (handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
/*++
|
||
Routine Description:
|
||
Do_S_to_C_NBytes
|
||
|
||
Arguments:
|
||
b - Binding Handle
|
||
i - number of iterations
|
||
Length - Length of data to transfer in bytes
|
||
ChunkSize - Size of the chunks in which data is to be transfered
|
||
Buffer - the buffer allocated for this Worker thread
|
||
|
||
Return Value:
|
||
The time it took to perform the test.
|
||
--*/
|
||
{
|
||
unsigned long n;
|
||
unsigned long Time = 0;
|
||
|
||
//
|
||
// Division by zero is evil, make sure this doesn't happen.
|
||
//
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
while (i--)
|
||
{
|
||
n = Length; // Reset length to send.
|
||
|
||
StartTime(); // Start the timer for this iteration.
|
||
|
||
//
|
||
// Send in complete chunks.
|
||
//
|
||
for (; n > ChunkSize; n -= ChunkSize)
|
||
{
|
||
S_to_C_Buffer(*b, ChunkSize, p);
|
||
}
|
||
//
|
||
// Send last bit that doesn't fit into a chunk.
|
||
//
|
||
S_to_C_Buffer(*b, n, p);
|
||
|
||
Time += FinishTiming(); // Update total time elapsed.
|
||
}
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_C_to_S_NBytes (handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
char __RPC_FAR *pCur;
|
||
unsigned long n;
|
||
unsigned long Time = 0;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
StartTime();
|
||
|
||
while(i--)
|
||
{
|
||
n = Length;
|
||
pCur = p;
|
||
|
||
StartTime();
|
||
|
||
for (; n > ChunkSize; n -= ChunkSize, pCur+=ChunkSize)
|
||
{
|
||
C_to_S_Buffer(*b, ChunkSize, pCur);
|
||
}
|
||
C_to_S_Buffer(*b, n, pCur);
|
||
|
||
Time += FinishTiming();
|
||
}
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_S_to_C_NBytesWithFile (handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
/*++
|
||
Routine Description:
|
||
Get a stream of bytes from the Server and save it to a file.
|
||
--*/
|
||
{
|
||
static const char *szFuncName = "Do_S_to_C_NBytesWithFile";
|
||
TCHAR pFileName[MAX_PATH];
|
||
unsigned long Time = 0;
|
||
|
||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||
DT_FILE_HANDLE hRemoteContext;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Create a temporary file to transfer
|
||
//
|
||
if (FALSE == CreateTempFile (NULL, TEXT("FCR"), 0, pFileName))
|
||
return 0;
|
||
|
||
//
|
||
// Open the temporary file.
|
||
//
|
||
hFile = CreateFile ((LPCTSTR) pFileName,
|
||
GENERIC_WRITE,
|
||
0,
|
||
(LPSECURITY_ATTRIBUTES) NULL,
|
||
CREATE_ALWAYS,
|
||
FILE_ATTRIBUTE_NORMAL,
|
||
(HANDLE) NULL
|
||
);
|
||
if (hFile == INVALID_HANDLE_VALUE)
|
||
{
|
||
printf(szFormatCantOpenTempFile,
|
||
szFuncName,
|
||
pFileName);
|
||
PrintSysErrorStringA(GetLastError());
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Get the server to prepare a file to send us.
|
||
//
|
||
if (0 == (hRemoteContext = RemoteOpen(*b, Length)))
|
||
{
|
||
printf(szFormatCantOpenServFile, szFuncName);
|
||
|
||
CloseHandle (hFile);
|
||
DeleteFile (pFileName);
|
||
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
{
|
||
DWORD dwBytesRead;
|
||
DWORD dwBytesWritten;
|
||
|
||
while(i--)
|
||
{
|
||
SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
|
||
RemoteResetFile (hRemoteContext);
|
||
|
||
StartTime();
|
||
do
|
||
{
|
||
//
|
||
// Assume that the transfer is finished when we receive zero bytes.
|
||
//
|
||
if (0 == (dwBytesRead = S_to_C_BufferWithFile(*b,
|
||
hRemoteContext,
|
||
ChunkSize,
|
||
p)))
|
||
{
|
||
break;
|
||
}
|
||
|
||
WriteFile(hFile, p, dwBytesRead, &dwBytesWritten, NULL);
|
||
} while (dwBytesRead == ChunkSize);
|
||
|
||
Time += FinishTiming();
|
||
}
|
||
}
|
||
|
||
//
|
||
// Clean Up
|
||
//
|
||
RemoteClose(&hRemoteContext, TRUE); // Close and delete remote file
|
||
CloseHandle(hFile); // Close local temp file
|
||
|
||
#ifdef DELETE_TEMP_FILES
|
||
DeleteFile (pFileName);
|
||
#endif
|
||
|
||
return (Time);
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_C_to_S_NBytesWithFile (handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
/*++
|
||
Routine Description:
|
||
Create a temporary file of size Length, then send it to the server.
|
||
--*/
|
||
{
|
||
static const char *szFuncName = "Do_C_to_S_NBytesWithFile";
|
||
TCHAR pFileName[MAX_PATH];
|
||
unsigned long Time = 0;
|
||
|
||
HANDLE hFile = INVALID_HANDLE_VALUE;
|
||
DT_FILE_HANDLE hRemoteContext;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Create a temporary file to send.
|
||
//
|
||
if (FALSE == CreateTempFile (NULL, TEXT("FCS"), Length, pFileName))
|
||
return 0;
|
||
|
||
//
|
||
// Open that temp file.
|
||
//
|
||
hFile = CreateFile ((LPCTSTR) pFileName,
|
||
GENERIC_READ,
|
||
0,
|
||
(LPSECURITY_ATTRIBUTES) NULL,
|
||
OPEN_EXISTING,
|
||
FILE_ATTRIBUTE_NORMAL,
|
||
(HANDLE) NULL);
|
||
if (hFile == INVALID_HANDLE_VALUE)
|
||
{
|
||
printf(szFormatCantOpenTempFile,
|
||
szFuncName,
|
||
pFileName);
|
||
PrintSysErrorStringA(GetLastError());
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Open a temp file on the server to receive our data.
|
||
//
|
||
if (0 == (hRemoteContext = RemoteOpen (*b, 0)))
|
||
{
|
||
printf(szFormatCantOpenServFile, szFuncName);
|
||
DeleteFile (pFileName);
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
{
|
||
DWORD dwBytesRead;
|
||
|
||
while(i--)
|
||
{
|
||
SetFilePointer (hFile, 0, NULL, FILE_BEGIN);
|
||
RemoteResetFile (hRemoteContext);
|
||
|
||
StartTime();
|
||
for(;;)
|
||
{
|
||
//
|
||
// If ReadFile fails we keep trying.
|
||
// This could go on forever, though.
|
||
//
|
||
if (FALSE == ReadFile (hFile, p, ChunkSize, &dwBytesRead, NULL))
|
||
{
|
||
printf("%s: ReadFile failed.\n", szFuncName);
|
||
PrintSysErrorStringA(GetLastError());
|
||
continue;
|
||
}
|
||
|
||
if (0 == dwBytesRead)
|
||
break;
|
||
|
||
C_to_S_BufferWithFile (*b, hRemoteContext, dwBytesRead, p);
|
||
}
|
||
|
||
Time += FinishTiming ();
|
||
}
|
||
}
|
||
|
||
//
|
||
// Clean Up
|
||
//
|
||
#ifdef DELETE_TEMP_FILES
|
||
RemoteClose (&hRemoteContext, TRUE); // Close and Delete remote file.
|
||
#else
|
||
RemoteClose (&hRemoteContext, FALSE); // Close Remote File but don't delete it.
|
||
#endif
|
||
|
||
CloseHandle (hFile); // Close local file.
|
||
DeleteFile (pFileName); // Delete local file.
|
||
|
||
return (Time);
|
||
}
|
||
|
||
|
||
//===================================================================
|
||
// RPC PIPES
|
||
//===================================================================
|
||
|
||
typedef struct
|
||
{
|
||
unsigned long BufferSize;
|
||
char __RPC_FAR *pBuffer;
|
||
|
||
unsigned long nBytesToGo;
|
||
}PIPE_STATE, *P_PIPE_STATE;
|
||
|
||
typedef struct
|
||
{
|
||
unsigned long BufferSize;
|
||
char __RPC_FAR *pBuffer;
|
||
|
||
HANDLE hFile;
|
||
} FILE_PIPE_STATE;
|
||
|
||
//---------------------------------------------------------
|
||
void PipeAlloc (PIPE_STATE *state,
|
||
unsigned long RequestedSize,
|
||
unsigned char **buf,
|
||
unsigned long *ActualSize)
|
||
{
|
||
*buf = state->pBuffer;
|
||
|
||
*ActualSize = (RequestedSize < state->BufferSize ?
|
||
RequestedSize :
|
||
state->BufferSize);
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
void PipePull (PIPE_STATE *state,
|
||
unsigned char *pBuffer,
|
||
unsigned long BufferSize,
|
||
unsigned long *ActualSizePulled)
|
||
{
|
||
if (state->nBytesToGo > BufferSize)
|
||
{
|
||
*ActualSizePulled = BufferSize;
|
||
state->nBytesToGo -= BufferSize;
|
||
}
|
||
else
|
||
{
|
||
*ActualSizePulled = state->nBytesToGo;
|
||
state->nBytesToGo = 0;
|
||
}
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
void PipePush (PIPE_STATE *state,
|
||
unsigned char *pBuffer,
|
||
unsigned long BufferSize)
|
||
{
|
||
state->nBytesToGo -= BufferSize;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
void FilePipePull (FILE_PIPE_STATE *state,
|
||
unsigned char *pBuffer,
|
||
unsigned long BufferSize,
|
||
unsigned long *ActualSizePulled)
|
||
{
|
||
ReadFile (state->hFile,
|
||
pBuffer,
|
||
BufferSize,
|
||
ActualSizePulled,
|
||
NULL);
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
void FilePipePush (FILE_PIPE_STATE *state,
|
||
unsigned char *pBuffer,
|
||
unsigned long BufferSize)
|
||
{
|
||
DWORD dwBytesWritten;
|
||
|
||
if (BufferSize != 0)
|
||
{
|
||
WriteFile (state->hFile,
|
||
pBuffer,
|
||
BufferSize,
|
||
&dwBytesWritten,
|
||
NULL);
|
||
}
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_S_to_C_Pipe (handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
const static char *szFuncName = "Do_S_to_C_Pipe";
|
||
PIPE_STATE State;
|
||
UCHAR_PIPE ThePipe;
|
||
unsigned long Time = 0;
|
||
|
||
DT_MEM_HANDLE hRemoteMem;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Allocate a buffer on the server
|
||
// This is done so that each server thread will have its own buffer
|
||
// without forcing a memory allocation on every RPC call.
|
||
//
|
||
if (NULL == (hRemoteMem = RemoteAllocate (*b, ChunkSize)))
|
||
{
|
||
printf("%s: RemoteAllocate failed.\n", szFuncName);
|
||
return 0;
|
||
}
|
||
|
||
State.pBuffer = p; // Use the thread's buffer as the buffer.
|
||
State.BufferSize = ChunkSize;
|
||
|
||
ThePipe.state = (char __RPC_FAR *) &State;
|
||
ThePipe.alloc = (void __RPC_FAR *) PipeAlloc;
|
||
ThePipe.push = (void __RPC_FAR *) PipePush;
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
while (i--)
|
||
{
|
||
State.nBytesToGo = Length; // Reset the pipe's state.
|
||
|
||
StartTime();
|
||
S_to_C_Pipe (*b, ThePipe, Length, hRemoteMem);
|
||
Time += FinishTiming();
|
||
}
|
||
|
||
//
|
||
// Clean Up
|
||
//
|
||
RemoteFree(&hRemoteMem);
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_C_to_S_Pipe(handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
const static char *szFuncName = "Do_C_to_S_Pipe";
|
||
PIPE_STATE State;
|
||
UCHAR_PIPE ThePipe;
|
||
unsigned long Time = 0;
|
||
|
||
DT_MEM_HANDLE hRemoteMem;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Allocate a buffer on the server.
|
||
// This is done so that each server thread will have its own buffer
|
||
// without forcing a memory allocation on every RPC call.
|
||
//
|
||
if (NULL == (hRemoteMem = RemoteAllocate (*b, ChunkSize)))
|
||
{
|
||
printf("%s: RemoteAllocate failed.\n", szFuncName);
|
||
return 0;
|
||
}
|
||
|
||
State.pBuffer = p; // Use the thread's buffer as the buffer.
|
||
State.BufferSize = ChunkSize;
|
||
|
||
ThePipe.state = (char __RPC_FAR *) &State;
|
||
ThePipe.alloc = (void __RPC_FAR *) PipeAlloc;
|
||
ThePipe.pull = (void __RPC_FAR *) PipePull;
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
while (i--)
|
||
{
|
||
State.nBytesToGo = Length;
|
||
|
||
StartTime();
|
||
C_to_S_Pipe (*b, ThePipe, hRemoteMem);
|
||
Time += FinishTiming();
|
||
}
|
||
|
||
//
|
||
// Clean up
|
||
//
|
||
RemoteFree(&hRemoteMem);
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_S_to_C_PipeWithFile(handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
/*++
|
||
Routine Description:
|
||
Receives a file from server via a pipe
|
||
--*/
|
||
{
|
||
static const char *szFuncName = "Do_S_to_C_PipeWithFile";
|
||
FILE_PIPE_STATE State;
|
||
UCHAR_PIPE ThePipe;
|
||
TCHAR pFileName[MAX_PATH];
|
||
unsigned long Time = 0;
|
||
|
||
HANDLE hFile;
|
||
DT_MEM_HANDLE hRemoteMem;
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Create a temporary file.
|
||
//
|
||
if (FALSE == CreateTempFile (NULL, TEXT("FCR"), 0, pFileName))
|
||
return 0;
|
||
|
||
//
|
||
// Open that temp file.
|
||
//
|
||
hFile = CreateFile ((LPCTSTR) pFileName,
|
||
GENERIC_WRITE,
|
||
0,
|
||
(LPSECURITY_ATTRIBUTES) NULL,
|
||
CREATE_ALWAYS,
|
||
FILE_ATTRIBUTE_NORMAL,
|
||
(HANDLE) NULL);
|
||
if (hFile == INVALID_HANDLE_VALUE)
|
||
{
|
||
printf(szFormatCantOpenTempFile,
|
||
szFuncName,
|
||
pFileName);
|
||
PrintSysErrorStringA(GetLastError());
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Allocate a buffer on the server
|
||
// This is done so that each server thread will have its own buffer
|
||
// without forcing a memory allocation on every RPC call.
|
||
//
|
||
if (NULL == (hRemoteMem = RemoteAllocate (*b, ChunkSize)))
|
||
{
|
||
printf("%s: RemoteAllocate failed.\n", szFuncName);
|
||
|
||
CloseHandle (hFile);
|
||
DeleteFile (pFileName);
|
||
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Get the server to prepare a file to send us.
|
||
//
|
||
if (0 == (hRemoteFile = RemoteOpen(*b, Length)))
|
||
{
|
||
printf(szFormatCantOpenServFile, szFuncName);
|
||
|
||
RemoteFree(&hRemoteMem);
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
|
||
return 0;
|
||
}
|
||
|
||
State.pBuffer = p; // Use the thread's buffer as the buffer
|
||
State.BufferSize = ChunkSize;
|
||
State.hFile = hFile;
|
||
|
||
ThePipe.state = (char __RPC_FAR *) &State;
|
||
ThePipe.alloc = (void __RPC_FAR *) PipeAlloc;
|
||
ThePipe.push = (void __RPC_FAR *) FilePipePush;
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
while (i--)
|
||
{
|
||
SetFilePointer (State.hFile, 0, NULL, FILE_BEGIN);
|
||
RemoteResetFile (hRemoteFile);
|
||
|
||
StartTime();
|
||
S_to_C_PipeWithFile (*b, ThePipe, hRemoteFile, hRemoteMem);
|
||
Time += FinishTiming();
|
||
}
|
||
|
||
//
|
||
// Clean Up
|
||
//
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
RemoteFree (&hRemoteMem);
|
||
CloseHandle (hFile);
|
||
|
||
#ifdef DELETE_TEMP_FILES
|
||
DeleteFile (pFileName);
|
||
#endif
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_C_to_S_PipeWithFile (handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
/*++
|
||
Routine Description:
|
||
Sends a file to server via a pipe
|
||
--*/
|
||
{
|
||
static const char *szFuncName = "Do_C_to_S_PipeWithFile";
|
||
FILE_PIPE_STATE State;
|
||
UCHAR_PIPE ThePipe;
|
||
TCHAR pFileName[MAX_PATH];
|
||
unsigned long Time = 0;
|
||
|
||
HANDLE hFile;
|
||
DT_MEM_HANDLE hRemoteMem;
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Create a temporary file to send.
|
||
//
|
||
if (FALSE == CreateTempFile (NULL, TEXT("FCS"), Length, pFileName))
|
||
return 0;
|
||
|
||
//
|
||
// Open that temp file.
|
||
//
|
||
hFile = CreateFile ((LPCTSTR) pFileName,
|
||
GENERIC_READ,
|
||
0,
|
||
(LPSECURITY_ATTRIBUTES) NULL,
|
||
OPEN_EXISTING,
|
||
FILE_ATTRIBUTE_NORMAL,
|
||
(HANDLE) NULL);
|
||
if (hFile == INVALID_HANDLE_VALUE)
|
||
{
|
||
printf(szFormatCantOpenTempFile,
|
||
szFuncName,
|
||
pFileName);
|
||
PrintSysErrorStringA(GetLastError());
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Allocate a buffer on the server
|
||
// This is done so that each server thread will have its own buffer
|
||
// without forcing a memory allocation on every RPC call.
|
||
//
|
||
if (NULL == (hRemoteMem = RemoteAllocate (*b, ChunkSize)))
|
||
{
|
||
printf("%s: RemoteAllocate failed.\n", szFuncName);
|
||
|
||
CloseHandle (hFile);
|
||
DeleteFile (pFileName);
|
||
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Open a temporary file on server to receive our data
|
||
//
|
||
if (0 == (hRemoteFile = RemoteOpen(*b, 0)))
|
||
{
|
||
printf(szFormatCantOpenServFile, szFuncName);
|
||
|
||
RemoteFree (&hRemoteMem);
|
||
CloseHandle (hFile);
|
||
DeleteFile (pFileName);
|
||
|
||
return 0;
|
||
}
|
||
|
||
State.pBuffer = p; // Use the thread's buffer as the buffer
|
||
State.BufferSize = ChunkSize;
|
||
State.hFile = hFile;
|
||
|
||
ThePipe.state = (char __RPC_FAR *) &State;
|
||
ThePipe.alloc = (void __RPC_FAR *) PipeAlloc;
|
||
ThePipe.pull = (void __RPC_FAR *) FilePipePull;
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
while (i--)
|
||
{
|
||
SetFilePointer (State.hFile, 0, NULL, FILE_BEGIN);
|
||
RemoteResetFile (hRemoteFile);
|
||
|
||
StartTime();
|
||
C_to_S_PipeWithFile (*b, ThePipe, hRemoteFile, hRemoteMem);
|
||
Time += FinishTiming();
|
||
}
|
||
|
||
//
|
||
// Clean up
|
||
//
|
||
#ifdef DELETE_TEMP_FILES
|
||
RemoteClose (&hRemoteFile, TRUE); // Close and Delete remote file.
|
||
#else
|
||
RemoteClose (&hRemoteFile, FALSE); // Close Remote File but don't delete it.
|
||
#endif
|
||
RemoteFree (&hRemoteMem);
|
||
CloseHandle (hFile);
|
||
DeleteFile (pFileName);
|
||
|
||
return Time;
|
||
}
|
||
|
||
//===================================================================
|
||
// Internet APIs
|
||
//===================================================================
|
||
static void PrintInternetError (LPCSTR lpszStr)
|
||
{
|
||
unsigned long ulBufLength = 255;
|
||
char szErrorString[256];
|
||
DWORD ulErrorCode;
|
||
DWORD ulWinErrCode;
|
||
|
||
ulWinErrCode = GetLastError();
|
||
|
||
printf("%s: %ld:", lpszStr, ulWinErrCode);
|
||
PrintSysErrorStringA(ulWinErrCode);
|
||
|
||
if (TRUE == InternetGetLastResponseInfoA ((DWORD __RPC_FAR *) &ulErrorCode,
|
||
(char __RPC_FAR *) szErrorString,
|
||
(unsigned long __RPC_FAR *) &ulBufLength))
|
||
{
|
||
assert (NULL != szErrorString);
|
||
|
||
printf(" %s", szErrorString);
|
||
}
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
static BOOL InternetCommonSetup (LPCSTR szCallerId, // [in]
|
||
BOOL f_Ftp, // [in]
|
||
BOOL f_StoC, // [in]
|
||
handle_t __RPC_FAR *b, // [in]
|
||
unsigned long ulLength, // [in]
|
||
HINTERNET *phINetSession, // [out]
|
||
DT_FILE_HANDLE *phRemoteFile, // [out]
|
||
LPTSTR szFtpFilePath // [out]
|
||
)
|
||
/*++
|
||
Routine Description:
|
||
Performs several common setup functions in FTP tests
|
||
|
||
Arguments:
|
||
szCallerId - a string that identifies the invoker for display
|
||
in error messages
|
||
|
||
f_Ftp - indicates whether to perform setup for an FTP test.
|
||
TRUE indicates FTP
|
||
|
||
f_StoC - indicates whether to set up a file for a Server-to-Client
|
||
or a Client-to-Server transfer. TRUE indicates the former.
|
||
|
||
b - the binding handle
|
||
|
||
ulLength - specifies the length of the file
|
||
|
||
phFtpSession - where to store the handle for an FTP session
|
||
|
||
phRemoteFile - where to store the handle for the server's file
|
||
|
||
szFtpFilePath - the path to the file on the FTP server
|
||
|
||
Return Value:
|
||
TRUE if successful,
|
||
FALSE if otherwise
|
||
--*/
|
||
{
|
||
TCHAR szServerName[81];
|
||
|
||
//
|
||
// Get Server's machine name.
|
||
//
|
||
GetServerName (*b, 80, szServerName);
|
||
|
||
//
|
||
// Open an Internet session.
|
||
//
|
||
*phINetSession = InternetConnect (hInternet,
|
||
szServerName,
|
||
0, // Default Port
|
||
NULL, // Anonymous
|
||
NULL, // Default Password
|
||
(TRUE == f_Ftp ?
|
||
INTERNET_SERVICE_FTP :
|
||
INTERNET_SERVICE_HTTP),
|
||
0,
|
||
0);
|
||
if (NULL == *phINetSession)
|
||
{
|
||
PrintInternetError (szCallerId);
|
||
return FALSE;
|
||
}
|
||
|
||
//
|
||
// Get the server to set up a file that we can get.
|
||
// Or get a filename from the server so we can send
|
||
// data to it if ulLength is zero.
|
||
//
|
||
if (TRUE == f_Ftp)
|
||
{
|
||
if (NULL == (*phRemoteFile = RemoteCreateFtpFile (*b,
|
||
(boolean)f_StoC,
|
||
ulLength,
|
||
MAX_PATH,
|
||
szFtpFilePath)))
|
||
{
|
||
printf(szFormatCantOpenServFile, szCallerId);
|
||
|
||
InternetCloseHandle (*phINetSession);
|
||
|
||
return FALSE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (NULL == (*phRemoteFile = RemoteCreateHttpFile (*b,
|
||
(boolean)f_StoC,
|
||
ulLength,
|
||
MAX_PATH,
|
||
szFtpFilePath)))
|
||
{
|
||
printf(szFormatCantOpenServFile, szCallerId);
|
||
|
||
InternetCloseHandle (*phINetSession);
|
||
|
||
return FALSE;
|
||
}
|
||
}
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_S_to_C_FtpWithFile (handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
/*++
|
||
Routine Description:
|
||
Get a file from the server's FTP directory. The server
|
||
must have the FTP root directory set or the test will
|
||
fail.
|
||
--*/
|
||
{
|
||
const static char *szFuncName = "Do_S_to_C_FtpWithFile";
|
||
TCHAR pFileName[MAX_PATH];
|
||
TCHAR szFtpFilePath[MAX_PATH];
|
||
unsigned long Time=0;
|
||
|
||
HINTERNET hFtpSession;
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Create a temporary file.
|
||
//
|
||
if (FALSE == CreateTempFile (NULL, TEXT("FCR"), 0, pFileName))
|
||
return 0;
|
||
|
||
//
|
||
// Common setup for Internet API tests...
|
||
//
|
||
if (FALSE == InternetCommonSetup (szFuncName,
|
||
TRUE, // FTP setup
|
||
TRUE, // S_to_C
|
||
b,
|
||
Length,
|
||
&hFtpSession,
|
||
&hRemoteFile,
|
||
szFtpFilePath))
|
||
{
|
||
DeleteFile (pFileName);
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
StartTime();
|
||
while (i--)
|
||
{
|
||
if (FALSE == FtpGetFile (hFtpSession,
|
||
szFtpFilePath,
|
||
pFileName,
|
||
FALSE,
|
||
FILE_ATTRIBUTE_NORMAL,
|
||
FTP_TRANSFER_TYPE_BINARY,
|
||
0))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
return 0;
|
||
}
|
||
}
|
||
Time = FinishTiming();
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
#ifdef DELETE_TEMP_FILES
|
||
DeleteFile (pFileName);
|
||
#endif
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_C_to_S_FtpWithFile (handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
const static char *szFuncName = "Do_C_to_S_FtpWithFile";
|
||
TCHAR pFileName[MAX_PATH];
|
||
TCHAR szFtpFilePath[MAX_PATH];
|
||
unsigned long Time=0;
|
||
|
||
HINTERNET hFtpSession;
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Create a temporary file.
|
||
//
|
||
if (FALSE == CreateTempFile (NULL, TEXT("FCS"), Length, pFileName))
|
||
return 0;
|
||
|
||
//
|
||
// Common setup for Internet API tests...
|
||
//
|
||
if (FALSE == InternetCommonSetup (szFuncName,
|
||
TRUE, // FTP setup
|
||
FALSE, // C_to_S
|
||
b,
|
||
0,
|
||
&hFtpSession,
|
||
&hRemoteFile,
|
||
szFtpFilePath))
|
||
{
|
||
DeleteFile(pFileName);
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
while (i--)
|
||
{
|
||
StartTime();
|
||
if (FALSE == FtpPutFile (hFtpSession,
|
||
pFileName,
|
||
szFtpFilePath,
|
||
FTP_TRANSFER_TYPE_BINARY,
|
||
0))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
DeleteFile (pFileName);
|
||
|
||
return 0;
|
||
}
|
||
Time += FinishTiming();
|
||
}
|
||
|
||
#ifdef DELETE_TEMP_FILES
|
||
RemoteClose (&hRemoteFile, TRUE); // Close and Delete remote file.
|
||
#else
|
||
RemoteClose (&hRemoteFile, FALSE); // Close Remote File but don't delete it.
|
||
#endif
|
||
|
||
InternetCloseHandle (hFtpSession);
|
||
DeleteFile (pFileName);
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_S_to_C_Ftp1(handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
const static char *szFuncName = "Do_S_to_C_Ftp1";
|
||
TCHAR szFtpFilePath[MAX_PATH];
|
||
unsigned long Time=0;
|
||
|
||
HINTERNET hFtpSession;
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
|
||
//
|
||
// Common setup for Internet API tests...
|
||
//
|
||
if (FALSE == InternetCommonSetup (szFuncName,
|
||
TRUE, // FTP setup
|
||
TRUE, // S_to_C
|
||
b,
|
||
Length,
|
||
&hFtpSession,
|
||
&hRemoteFile,
|
||
szFtpFilePath))
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
{
|
||
HINTERNET hFtpFile;
|
||
DWORD nBytesRead;
|
||
|
||
while (i--)
|
||
{
|
||
//
|
||
// Open file on the server to read from.
|
||
//
|
||
hFtpFile = FtpOpenFile (hFtpSession,
|
||
szFtpFilePath,
|
||
GENERIC_READ,
|
||
FTP_TRANSFER_TYPE_BINARY,
|
||
0);
|
||
if (NULL == hFtpFile)
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
return 0;
|
||
}
|
||
|
||
StartTime();
|
||
|
||
//
|
||
// Transfer the file!
|
||
//
|
||
do
|
||
{
|
||
if (FALSE == InternetReadFile (hFtpFile,
|
||
p,
|
||
ChunkSize,
|
||
&nBytesRead))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hFtpFile);
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
return 0;
|
||
}
|
||
} while (0 != nBytesRead);
|
||
|
||
Time += FinishTiming();
|
||
|
||
InternetCloseHandle (hFtpFile);
|
||
}
|
||
}
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_C_to_S_Ftp1(handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
const static char *szFuncName = "Do_C_to_S_Ftp1";
|
||
TCHAR szFtpFilePath[MAX_PATH];
|
||
unsigned long Time=0;
|
||
|
||
HINTERNET hFtpSession;
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Common setup for Internet API tests...
|
||
//
|
||
if (FALSE == InternetCommonSetup (szFuncName,
|
||
TRUE, // FTP setup
|
||
FALSE, // C_to_S
|
||
b,
|
||
0,
|
||
&hFtpSession,
|
||
&hRemoteFile,
|
||
szFtpFilePath))
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
{
|
||
DWORD dwBytesWritten;
|
||
DWORD dwBytesRead;
|
||
HINTERNET hFtpFile;
|
||
unsigned int n;
|
||
|
||
while (i--)
|
||
{
|
||
//
|
||
// Open a file on server to write to.
|
||
//
|
||
hFtpFile = FtpOpenFile (hFtpSession,
|
||
szFtpFilePath,
|
||
GENERIC_WRITE,
|
||
FTP_TRANSFER_TYPE_BINARY,
|
||
0);
|
||
if (NULL == hFtpFile)
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
return 0;
|
||
}
|
||
|
||
n = Length;
|
||
|
||
StartTime();
|
||
|
||
//
|
||
// Transfer in complete chunks
|
||
//
|
||
for (; n > ChunkSize; n -= ChunkSize)
|
||
{
|
||
if (FALSE == InternetWriteFile (hFtpFile,
|
||
p,
|
||
ChunkSize,
|
||
&dwBytesWritten))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hFtpFile);
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
return 0;
|
||
}
|
||
}
|
||
//
|
||
// Transfer the last bit that doesn't fill a chunk
|
||
//
|
||
if (FALSE == InternetWriteFile (hFtpFile,
|
||
p,
|
||
n,
|
||
&dwBytesWritten))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hFtpFile);
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
return 0;
|
||
}
|
||
|
||
Time += FinishTiming();
|
||
|
||
InternetCloseHandle (hFtpFile);
|
||
}
|
||
}
|
||
|
||
RemoteClose (&hRemoteFile, FALSE);
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_S_to_C_Ftp1WithFile(handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
const static char *szFuncName = "Do_S_to_C_Ftp1WithFile";
|
||
TCHAR pFileName[MAX_PATH];
|
||
TCHAR szFtpFilePath[MAX_PATH];
|
||
unsigned long Time = 0;
|
||
|
||
HANDLE hFile;
|
||
HINTERNET hFtpSession;
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Create a temporary file.
|
||
//
|
||
if (FALSE == CreateTempFile (NULL, TEXT("FCR"), 0, pFileName))
|
||
return 0;
|
||
|
||
//
|
||
// Open the temporary file.
|
||
//
|
||
hFile = CreateFile ((LPCTSTR) pFileName,
|
||
GENERIC_WRITE,
|
||
0,
|
||
(LPSECURITY_ATTRIBUTES) NULL,
|
||
CREATE_ALWAYS,
|
||
FILE_ATTRIBUTE_NORMAL,
|
||
(HANDLE) NULL
|
||
);
|
||
if (hFile == INVALID_HANDLE_VALUE)
|
||
{
|
||
printf(szFormatCantOpenTempFile,
|
||
szFuncName,
|
||
pFileName);
|
||
PrintSysErrorStringA(GetLastError());
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Common setup for Internet API tests...
|
||
//
|
||
if (FALSE == InternetCommonSetup (szFuncName,
|
||
TRUE, // FTP setup
|
||
TRUE, // S_to_C
|
||
b,
|
||
Length,
|
||
&hFtpSession,
|
||
&hRemoteFile,
|
||
szFtpFilePath))
|
||
{
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
{
|
||
DWORD dwBytesWritten;
|
||
DWORD dwBytesRead;
|
||
HINTERNET hFtpFile;
|
||
|
||
while (i--)
|
||
{
|
||
//
|
||
// Open the remote file.
|
||
//
|
||
hFtpFile = FtpOpenFile (hFtpSession,
|
||
szFtpFilePath,
|
||
GENERIC_READ,
|
||
FTP_TRANSFER_TYPE_BINARY,
|
||
0);
|
||
if (NULL == hFtpFile)
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Reset the local file.
|
||
//
|
||
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
|
||
|
||
StartTime();
|
||
for (;;)
|
||
{
|
||
//
|
||
// Transfer in complete chunks
|
||
//
|
||
if (FALSE == InternetReadFile (hFtpFile,
|
||
p,
|
||
ChunkSize,
|
||
&dwBytesRead))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hFtpFile);
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
CloseHandle(hFile);
|
||
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Return value == TRUE and dwBytesRead == 0 means EOF
|
||
//
|
||
if (0 == dwBytesRead)
|
||
break;
|
||
|
||
WriteFile(hFile, p, dwBytesRead, &dwBytesWritten, NULL);
|
||
}
|
||
|
||
Time += FinishTiming();
|
||
|
||
//
|
||
// Close and re-open the file after each write.
|
||
//
|
||
InternetCloseHandle (hFtpFile);
|
||
}
|
||
}
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
CloseHandle(hFile);
|
||
|
||
#ifdef DELETE_TEMP_FILES
|
||
DeleteFile (pFileName);
|
||
#endif
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_C_to_S_Ftp1WithFile(handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
static const char *szFuncName="Do_C_to_S_Ftp1WithFile";
|
||
HINTERNET hFtpSession;
|
||
HANDLE hFile;
|
||
TCHAR pFileName[MAX_PATH];
|
||
unsigned long Time=0;
|
||
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
char szFtpFilePath[MAX_PATH];
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Create a temporary file.
|
||
//
|
||
if (FALSE == CreateTempFile (NULL, "FCS", Length, pFileName))
|
||
return 0;
|
||
|
||
//
|
||
// Open the temporary file.
|
||
//
|
||
hFile = CreateFile ((LPTSTR) pFileName,
|
||
GENERIC_READ,
|
||
0,
|
||
(LPSECURITY_ATTRIBUTES) NULL,
|
||
OPEN_EXISTING,
|
||
FILE_ATTRIBUTE_NORMAL,
|
||
(HANDLE) NULL
|
||
);
|
||
if (hFile == INVALID_HANDLE_VALUE)
|
||
{
|
||
printf(szFormatCantOpenTempFile,
|
||
szFuncName,
|
||
pFileName);
|
||
PrintSysErrorStringA(GetLastError());
|
||
DeleteFile(pFileName);
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Common setup for Internet API tests...
|
||
//
|
||
if (FALSE == InternetCommonSetup (szFuncName,
|
||
TRUE, // FTP setup
|
||
FALSE, // C_to_S
|
||
b,
|
||
0,
|
||
&hFtpSession,
|
||
&hRemoteFile,
|
||
szFtpFilePath))
|
||
{
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
{
|
||
DWORD dwBytesWritten;
|
||
DWORD dwBytesRead;
|
||
HINTERNET hFtpFile;
|
||
|
||
while (i--)
|
||
{
|
||
//
|
||
// Open the remote file.
|
||
//
|
||
hFtpFile = FtpOpenFile (hFtpSession,
|
||
szFtpFilePath,
|
||
GENERIC_WRITE,
|
||
FTP_TRANSFER_TYPE_BINARY,
|
||
0);
|
||
if (NULL == hFtpFile)
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hFtpSession);
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
|
||
return 0;
|
||
}
|
||
|
||
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
|
||
|
||
StartTime();
|
||
for (;;)
|
||
{
|
||
if (FALSE == ReadFile(hFile, p, ChunkSize, &dwBytesRead, NULL))
|
||
{
|
||
printf("%s: ReadFile failed.\n", szFuncName);
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// Return value == TRUE and dwBytesRead == 0 means EOF
|
||
//
|
||
if (0 == dwBytesRead)
|
||
break;
|
||
|
||
if (FALSE == InternetWriteFile (hFtpFile,
|
||
p,
|
||
dwBytesRead,
|
||
&dwBytesWritten))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hFtpFile);
|
||
RemoteClose (&hRemoteFile, FALSE);
|
||
CloseHandle(hFile);
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
Time += FinishTiming();
|
||
|
||
//
|
||
// Close and re-open the file after each write.
|
||
//
|
||
InternetCloseHandle (hFtpFile);
|
||
}
|
||
}
|
||
|
||
#ifdef DELETE_TEMP_FILES
|
||
RemoteClose (&hRemoteFile, TRUE); // Close and Delete remote file.
|
||
#else
|
||
RemoteClose (&hRemoteFile, FALSE); // Close Remote File but don't delete it.
|
||
#endif
|
||
|
||
InternetCloseHandle (hFtpSession);
|
||
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
// We want to accept all types of files, even binary.
|
||
static LPCTSTR lpszAcceptTypes[] = {TEXT("*"),0};
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_S_to_C_Http(handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
static const char *szFuncName = "Do_S_to_C_Http";
|
||
TCHAR szHttpFilePath[MAX_PATH];
|
||
unsigned long Time=0;
|
||
|
||
HINTERNET hHttpSession;
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Common setup for Internet API tests...
|
||
//
|
||
if (FALSE == InternetCommonSetup (szFuncName,
|
||
FALSE, // HTTP setup
|
||
TRUE, // S_to_C
|
||
b,
|
||
Length,
|
||
&hHttpSession,
|
||
&hRemoteFile,
|
||
szHttpFilePath))
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
{
|
||
HINTERNET hHttpFile;
|
||
DWORD nBytesRead;
|
||
|
||
while (i--)
|
||
{
|
||
//
|
||
// Open file on the server to read from.
|
||
//
|
||
hHttpFile = HttpOpenRequest (hHttpSession,
|
||
TEXT("GET"),
|
||
szHttpFilePath,
|
||
HTTP_VERSION,
|
||
NULL,
|
||
lpszAcceptTypes,
|
||
INTERNET_FLAG_RELOAD,
|
||
0);
|
||
if (NULL == hHttpFile)
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return 0;
|
||
}
|
||
|
||
if (FALSE == HttpSendRequest (hHttpFile,
|
||
NULL,
|
||
0,
|
||
NULL,
|
||
0))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hHttpFile);
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return 0;
|
||
}
|
||
|
||
StartTime();
|
||
|
||
//
|
||
// Transfer the file!
|
||
//
|
||
do
|
||
{
|
||
if (FALSE == InternetReadFile (hHttpFile,
|
||
p,
|
||
ChunkSize,
|
||
&nBytesRead))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hHttpFile);
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return 0;
|
||
}
|
||
} while (0 != nBytesRead);
|
||
|
||
Time += FinishTiming();
|
||
|
||
InternetCloseHandle (hHttpFile);
|
||
}
|
||
}
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return Time;
|
||
}
|
||
//---------------------------------------------------------
|
||
unsigned long Do_C_to_S_Http(handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
static const char *szFuncName="Do_C_to_S_HttpWithFile";
|
||
HINTERNET hHttpSession;
|
||
unsigned long Time=0;
|
||
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
char szHttpFilePath[MAX_PATH];
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Common setup for Internet API tests...
|
||
//
|
||
if (FALSE == InternetCommonSetup (szFuncName,
|
||
FALSE, // HTTP setup
|
||
FALSE, // C_to_S
|
||
b,
|
||
0,
|
||
&hHttpSession,
|
||
&hRemoteFile,
|
||
szHttpFilePath))
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
{
|
||
DWORD dwBytesWritten;
|
||
DWORD dwBytesRead;
|
||
unsigned int n;
|
||
HINTERNET hHttpFile;
|
||
|
||
while (i--)
|
||
{
|
||
//
|
||
// Open the remote file.
|
||
//
|
||
hHttpFile = HttpOpenRequest (hHttpSession,
|
||
TEXT("PUT"),
|
||
szHttpFilePath,
|
||
HTTP_VERSION,
|
||
NULL,
|
||
lpszAcceptTypes,
|
||
INTERNET_FLAG_RELOAD,
|
||
0);
|
||
if (NULL == hHttpFile)
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return 0;
|
||
}
|
||
|
||
if (FALSE == HttpSendRequest (hHttpFile,
|
||
NULL,
|
||
0,
|
||
NULL,
|
||
0))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hHttpFile);
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return 0;
|
||
}
|
||
|
||
StartTime();
|
||
//
|
||
// Transfer in complete chunks
|
||
//
|
||
for (n = Length; n > ChunkSize; n -= ChunkSize)
|
||
{
|
||
if (FALSE == InternetWriteFile (hHttpFile,
|
||
p,
|
||
ChunkSize,
|
||
&dwBytesWritten))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hHttpFile);
|
||
RemoteClose (&hRemoteFile, FALSE);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return 0;
|
||
}
|
||
}
|
||
//
|
||
// Transfer the last bit that doesn't fill a chunk
|
||
//
|
||
if (FALSE == InternetWriteFile (hHttpFile,
|
||
p,
|
||
n,
|
||
&dwBytesWritten))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hHttpFile);
|
||
RemoteClose (&hRemoteFile, FALSE);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return 0;
|
||
}
|
||
|
||
Time += FinishTiming();
|
||
|
||
//
|
||
// Close and re-open the file after each write.
|
||
//
|
||
InternetCloseHandle (hHttpFile);
|
||
}
|
||
}
|
||
|
||
#ifdef DELETE_TEMP_FILES
|
||
RemoteClose (&hRemoteFile, TRUE); // Close and Delete remote file.
|
||
#else
|
||
RemoteClose (&hRemoteFile, FALSE); // Close Remote File but don't delete it.
|
||
#endif
|
||
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_S_to_C_HttpWithFile(handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
/*++
|
||
Routine Description:
|
||
Grabs a file from the server using HTTP
|
||
--*/
|
||
{
|
||
static const char *szFuncName = "Do_S_to_C_HttpWithFile";
|
||
TCHAR pFileName[MAX_PATH];
|
||
TCHAR szHttpFilePath[MAX_PATH];
|
||
unsigned long Time=0;
|
||
|
||
HANDLE hFile;
|
||
HINTERNET hHttpSession;
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Create a temporary file.
|
||
//
|
||
if (FALSE == CreateTempFile (NULL, TEXT("FCR"), 0, pFileName))
|
||
return 0;
|
||
|
||
//
|
||
// Open the temporary file.
|
||
//
|
||
hFile = CreateFile ((LPCTSTR) pFileName,
|
||
GENERIC_WRITE,
|
||
0,
|
||
(LPSECURITY_ATTRIBUTES) NULL,
|
||
CREATE_ALWAYS,
|
||
FILE_ATTRIBUTE_NORMAL,
|
||
(HANDLE) NULL
|
||
);
|
||
if (hFile == INVALID_HANDLE_VALUE)
|
||
{
|
||
printf(szFormatCantOpenTempFile,
|
||
szFuncName,
|
||
pFileName);
|
||
PrintSysErrorStringA(GetLastError());
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Common setup for Internet API tests...
|
||
//
|
||
if (FALSE == InternetCommonSetup (szFuncName,
|
||
FALSE, // HTTP setup
|
||
TRUE, // S_to_C
|
||
b,
|
||
Length,
|
||
&hHttpSession,
|
||
&hRemoteFile,
|
||
szHttpFilePath))
|
||
{
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
{
|
||
DWORD dwBytesWritten;
|
||
DWORD dwBytesRead;
|
||
HINTERNET hHttpFile;
|
||
|
||
while (i--)
|
||
{
|
||
hHttpFile = HttpOpenRequest (hHttpSession,
|
||
TEXT("GET"),
|
||
szHttpFilePath,
|
||
HTTP_VERSION,
|
||
NULL,
|
||
lpszAcceptTypes,
|
||
INTERNET_FLAG_RELOAD,
|
||
0);
|
||
if (NULL == hHttpFile)
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
|
||
return 0;
|
||
}
|
||
|
||
if (FALSE == HttpSendRequest (hHttpFile,
|
||
NULL,
|
||
0,
|
||
NULL,
|
||
0))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hHttpFile);
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Reset the local file.
|
||
//
|
||
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
|
||
|
||
StartTime();
|
||
for (;;)
|
||
{
|
||
if (FALSE == InternetReadFile (hHttpFile,
|
||
p,
|
||
ChunkSize,
|
||
&dwBytesRead))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hHttpFile);
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
CloseHandle(hFile);
|
||
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Return value == TRUE and dwBytesRead == 0 means EOF
|
||
//
|
||
if (0 == dwBytesRead)
|
||
break;
|
||
|
||
WriteFile(hFile, p, dwBytesRead, &dwBytesWritten, NULL);
|
||
}
|
||
|
||
Time += FinishTiming();
|
||
|
||
//
|
||
// Close and re-open the file after each write.
|
||
//
|
||
InternetCloseHandle (hHttpFile);
|
||
}
|
||
}
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
CloseHandle(hFile);
|
||
|
||
#ifdef DELETE_TEMP_FILES
|
||
DeleteFile (pFileName);
|
||
#endif
|
||
|
||
return Time;
|
||
}
|
||
|
||
//---------------------------------------------------------
|
||
unsigned long Do_C_to_S_HttpWithFile(handle_t __RPC_FAR * b,
|
||
long i,
|
||
unsigned long Length,
|
||
unsigned long ChunkSize,
|
||
char __RPC_FAR *p)
|
||
{
|
||
static const char *szFuncName="Do_C_to_S_HttpWithFile";
|
||
HINTERNET hHttpSession;
|
||
HANDLE hFile;
|
||
TCHAR pFileName[MAX_PATH];
|
||
unsigned long Time=0;
|
||
|
||
DT_FILE_HANDLE hRemoteFile;
|
||
char szHttpFilePath[MAX_PATH];
|
||
|
||
assert( (Length == 0) || (ChunkSize != 0));
|
||
|
||
//
|
||
// Create a temporary file.
|
||
//
|
||
if (FALSE == CreateTempFile (NULL, "FCS", Length, pFileName))
|
||
return 0;
|
||
|
||
//
|
||
// Open the temporary file.
|
||
//
|
||
hFile = CreateFile ((LPTSTR) pFileName,
|
||
GENERIC_READ,
|
||
0,
|
||
(LPSECURITY_ATTRIBUTES) NULL,
|
||
OPEN_EXISTING,
|
||
FILE_ATTRIBUTE_NORMAL,
|
||
(HANDLE) NULL
|
||
);
|
||
if (hFile == INVALID_HANDLE_VALUE)
|
||
{
|
||
printf(szFormatCantOpenTempFile,
|
||
szFuncName,
|
||
pFileName);
|
||
PrintSysErrorStringA(GetLastError());
|
||
DeleteFile(pFileName);
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Common setup for Internet API tests...
|
||
//
|
||
if (FALSE == InternetCommonSetup (szFuncName,
|
||
FALSE, // HTTP setup
|
||
FALSE, // C_to_S
|
||
b,
|
||
0,
|
||
&hHttpSession,
|
||
&hRemoteFile,
|
||
szHttpFilePath))
|
||
{
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// The Actual Test
|
||
//
|
||
{
|
||
DWORD dwBytesWritten;
|
||
DWORD dwBytesRead;
|
||
HINTERNET hHttpFile;
|
||
|
||
while (i--)
|
||
{
|
||
//
|
||
// Open the remote file.
|
||
//
|
||
hHttpFile = HttpOpenRequest (hHttpSession,
|
||
TEXT("PUT"),
|
||
szHttpFilePath,
|
||
HTTP_VERSION,
|
||
NULL,
|
||
lpszAcceptTypes,
|
||
INTERNET_FLAG_RELOAD,
|
||
0);
|
||
if (NULL == hHttpFile)
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
|
||
return 0;
|
||
}
|
||
|
||
if (FALSE == HttpSendRequest (hHttpFile,
|
||
NULL,
|
||
0,
|
||
NULL,
|
||
0))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hHttpFile);
|
||
RemoteClose (&hRemoteFile, TRUE);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return 0;
|
||
}
|
||
|
||
//
|
||
// Reset the local file.
|
||
//
|
||
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
|
||
|
||
StartTime();
|
||
for (;;)
|
||
{
|
||
if (FALSE == ReadFile(hFile, p, ChunkSize, &dwBytesRead, NULL))
|
||
{
|
||
printf("%s: ReadFile failed.\n", szFuncName);
|
||
continue;
|
||
}
|
||
|
||
//
|
||
// Return value == TRUE and dwBytesRead == 0 means EOF
|
||
//
|
||
if (0 == dwBytesRead)
|
||
break;
|
||
|
||
if (FALSE == InternetWriteFile (hHttpFile,
|
||
p,
|
||
dwBytesRead,
|
||
&dwBytesWritten))
|
||
{
|
||
PrintInternetError (szFuncName);
|
||
|
||
InternetCloseHandle (hHttpFile);
|
||
RemoteClose (&hRemoteFile, FALSE);
|
||
CloseHandle(hFile);
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
Time += FinishTiming();
|
||
|
||
//
|
||
// Close and re-open the file after each write.
|
||
//
|
||
InternetCloseHandle (hHttpFile);
|
||
}
|
||
}
|
||
|
||
#ifdef DELETE_TEMP_FILES
|
||
RemoteClose (&hRemoteFile, TRUE); // Close and Delete remote file.
|
||
#else
|
||
RemoteClose (&hRemoteFile, FALSE); // Close Remote File but don't delete it.
|
||
#endif
|
||
|
||
InternetCloseHandle (hHttpSession);
|
||
|
||
CloseHandle(hFile);
|
||
DeleteFile(pFileName);
|
||
|
||
return Time;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
|
||
static const unsigned long (*TestTable[TEST_MAX])(handle_t __RPC_FAR *,long,long,long, char __RPC_FAR *) =
|
||
{
|
||
Do_S_to_C_NBytes,
|
||
Do_C_to_S_NBytes,
|
||
Do_S_to_C_Pipe,
|
||
Do_C_to_S_Pipe,
|
||
Do_S_to_C_Ftp1,
|
||
Do_C_to_S_Ftp1,
|
||
Do_S_to_C_Http,
|
||
Do_C_to_S_Http,
|
||
Do_S_to_C_NBytesWithFile,
|
||
Do_C_to_S_NBytesWithFile,
|
||
Do_S_to_C_PipeWithFile,
|
||
Do_C_to_S_PipeWithFile,
|
||
Do_S_to_C_FtpWithFile,
|
||
Do_C_to_S_FtpWithFile,
|
||
Do_S_to_C_Ftp1WithFile,
|
||
Do_C_to_S_Ftp1WithFile,
|
||
Do_S_to_C_HttpWithFile,
|
||
Do_C_to_S_HttpWithFile
|
||
};
|
||
|
||
|
||
//---------------------------------------------------------
|
||
//
|
||
// Worker calls the correct tests. Maybe multithreaded on NT
|
||
//
|
||
|
||
unsigned long Worker(unsigned long l)
|
||
{
|
||
unsigned long status;
|
||
unsigned long lTest;
|
||
long lIterations, lClientId;
|
||
unsigned long lTime;
|
||
long lLength, lChunkSize;
|
||
char __RPC_FAR *pBuffer;
|
||
char __RPC_FAR *stringBinding;
|
||
handle_t binding;
|
||
unsigned int i;
|
||
|
||
pBuffer = MIDL_user_allocate(ulBufferSize);
|
||
if (pBuffer == 0)
|
||
{
|
||
PrintToConsole("Out of memory!");
|
||
return 1;
|
||
}
|
||
|
||
for (i = 0; i< ulBufferSize;i++)
|
||
{
|
||
pBuffer[i] = (char) (i&0xff);
|
||
}
|
||
|
||
status = RpcStringBindingCompose(0,
|
||
Protseq,
|
||
NetworkAddr,
|
||
Endpoint,
|
||
0,
|
||
&stringBinding);
|
||
CHECK_RET(status, "RpcStringBindingCompose");
|
||
|
||
status = RpcBindingFromStringBinding(stringBinding, &binding);
|
||
CHECK_RET(status, "RpcBindingFromStringBinding");
|
||
|
||
status = DoRpcBindingSetAuthInfo(binding);
|
||
CHECK_RET(status, "RpcBindingSetAuthInfo");
|
||
|
||
RpcStringFree(&stringBinding);
|
||
|
||
RpcTryExcept
|
||
{
|
||
status = BeginTest(binding, &lClientId);
|
||
}
|
||
RpcExcept(1)
|
||
{
|
||
PrintToConsole("First call failed %ld (%08lx)\n",
|
||
(unsigned long)RpcExceptionCode(),
|
||
(unsigned long)RpcExceptionCode());
|
||
goto Cleanup;
|
||
}
|
||
RpcEndExcept
|
||
|
||
if (status == PERF_TOO_MANY_CLIENTS)
|
||
{
|
||
PrintToConsole("Too many clients, I'm exiting\n");
|
||
goto Cleanup ;
|
||
}
|
||
CHECK_RET(status, "ClientConnect");
|
||
|
||
PrintToConsole("Client %ld connected\n", lClientId);
|
||
|
||
do
|
||
{
|
||
status = NextTest(binding, &lTest, &lIterations, &lLength, &lChunkSize);
|
||
|
||
if (status == PERF_TESTS_DONE)
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
CHECK_RET(status, "NextTest");
|
||
|
||
PrintToConsole("(%4ld iterations of case %2ld, Length: %7ld, Chunk: %7ld: ",
|
||
lIterations,
|
||
lTest,
|
||
lLength,
|
||
lChunkSize);
|
||
|
||
RpcTryExcept
|
||
{
|
||
|
||
lTime = ( (TestTable[lTest])(&binding, lIterations, lLength, lChunkSize, pBuffer));
|
||
|
||
PrintToConsole("% 5ld mseconds)\n", lTime);
|
||
|
||
status = EndTest(binding, lTime);
|
||
|
||
CHECK_RET(status, "EndTest");
|
||
|
||
}
|
||
RpcExcept(1)
|
||
{
|
||
PrintToConsole("\nTest case %ld raised exception %lu (0x%08lX)\n",
|
||
lTest,
|
||
(unsigned long)RpcExceptionCode(),
|
||
(unsigned long)RpcExceptionCode());
|
||
status = RpcExceptionCode();
|
||
}
|
||
RpcEndExcept
|
||
|
||
}
|
||
while(status == 0);
|
||
|
||
Cleanup:
|
||
RpcBindingFree(&binding) ; //BUGBUG
|
||
return status;
|
||
}
|
||
|
||
|
||
//---------------------------------------------------------
|
||
//
|
||
// The Win32 main starts worker threads, otherwise we just call the worker.
|
||
//
|
||
|
||
#ifdef WIN32
|
||
int __cdecl
|
||
main (int argc, char **argv)
|
||
{
|
||
char option;
|
||
unsigned long status, i;
|
||
HANDLE *pClientThreads;
|
||
|
||
ParseArgv(argc, argv);
|
||
|
||
PrintToConsole("Authentication Level is: %s\n", AuthnLevelStr);
|
||
|
||
if (Options[0] < 0)
|
||
Options[0] = 1;
|
||
|
||
pClientThreads = MIDL_user_allocate(sizeof(HANDLE) * Options[0]);
|
||
|
||
//
|
||
// Setup for the use of the WinINet functions
|
||
//
|
||
hInternet = InternetOpen ("Data Transfer Test",
|
||
LOCAL_INTERNET_ACCESS,
|
||
NULL,
|
||
0,
|
||
(DWORD) 0);
|
||
|
||
for(i = 0; i < (unsigned long)Options[0]; i++)
|
||
{
|
||
pClientThreads[i] = CreateThread(0,
|
||
0,
|
||
(LPTHREAD_START_ROUTINE)Worker,
|
||
0,
|
||
0,
|
||
&status);
|
||
if (pClientThreads[i] == 0)
|
||
ApiError("CreateThread", GetLastError());
|
||
}
|
||
|
||
|
||
status = WaitForMultipleObjects(Options[0],
|
||
pClientThreads,
|
||
TRUE, // Wait for all client threads
|
||
INFINITE);
|
||
if (status == WAIT_FAILED)
|
||
{
|
||
ApiError("WaitForMultipleObjects", GetLastError());
|
||
}
|
||
|
||
if (NULL != hInternet)
|
||
{
|
||
InternetCloseHandle (hInternet);
|
||
}
|
||
|
||
PrintToConsole("TEST DONE\n");
|
||
return(0);
|
||
}
|
||
#else // !WIN32
|
||
#ifdef WIN
|
||
#define main c_main
|
||
|
||
// We need the following to force the linker to load WinMain from the
|
||
// Windows STDIO library
|
||
extern int PASCAL WinMain(HANDLE, HANDLE, LPSTR, int);
|
||
static int (PASCAL *wm_ptr)(HANDLE, HANDLE, LPSTR, int) = WinMain;
|
||
|
||
#endif
|
||
|
||
#ifndef MAC
|
||
#ifndef FAR
|
||
#define FAR __far
|
||
#endif
|
||
#else
|
||
#define FAR
|
||
#define main c_main
|
||
#endif
|
||
|
||
int main (int argc, char FAR * FAR * argv)
|
||
{
|
||
#ifndef MAC
|
||
ParseArgv(argc, argv);
|
||
#endif
|
||
Worker(0);
|
||
|
||
PrintToConsole("TEST DONE\n");
|
||
|
||
return(0);
|
||
}
|
||
#endif // NTENV
|
||
|