You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
351 lines
6.2 KiB
351 lines
6.2 KiB
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sacio.cpp
|
|
|
|
Abstract:
|
|
|
|
This module implements the SAC IoHandler functionality.
|
|
|
|
The SAC IoHandler implements a write buffer so that the
|
|
# of calls to teh SAC driver are reduced.
|
|
|
|
Author:
|
|
|
|
Brian Guarraci (briangu), 2001
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#include "sacio.h"
|
|
|
|
//
|
|
// Enable the write buffer
|
|
//
|
|
#define USE_SEND_BUFFER 1
|
|
|
|
//
|
|
// The size of the write buffer
|
|
//
|
|
#define SEND_BUFFER_SIZE 8192
|
|
|
|
CSacIoHandler::CSacIoHandler(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Constructor
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
N/A
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// We don't yet have a SAC channel object
|
|
//
|
|
mySacChannel = NULL;
|
|
|
|
//
|
|
// Create a send buffer
|
|
//
|
|
mySendBufferIndex = 0;
|
|
mySendBuffer = new BYTE[SEND_BUFFER_SIZE];
|
|
|
|
}
|
|
|
|
CSacIoHandler::~CSacIoHandler(
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Destructor
|
|
|
|
Arguments:
|
|
|
|
N/A
|
|
|
|
Return Value:
|
|
|
|
N/A
|
|
|
|
--*/
|
|
{
|
|
if (mySacChannel) {
|
|
delete mySacChannel;
|
|
}
|
|
|
|
delete [] mySendBuffer;
|
|
}
|
|
|
|
CSacIoHandler*
|
|
CSacIoHandler::Construct(
|
|
IN SAC_CHANNEL_OPEN_ATTRIBUTES Attributes
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
static constructor - this does the real construction
|
|
|
|
Arguments:
|
|
|
|
Attributes - attributes of the SAC channel to create
|
|
|
|
Return Value:
|
|
|
|
On success, a pointer to the new IoHandler
|
|
On failure, NULL
|
|
|
|
--*/
|
|
{
|
|
CSacIoHandler *IoHandler;
|
|
|
|
//
|
|
// Create a new SAC IoHandler
|
|
//
|
|
IoHandler = new CSacIoHandler();
|
|
|
|
//
|
|
// Attempt to open a SAC channel
|
|
//
|
|
IoHandler->mySacChannel = EMSCmdChannel::Construct(Attributes);
|
|
|
|
//
|
|
// If we failed to open the SAC channel,
|
|
// then destroy the IoHandler and notify the caller
|
|
// that we failed by returning null
|
|
//
|
|
if (IoHandler->mySacChannel == NULL) {
|
|
delete IoHandler;
|
|
return NULL;
|
|
}
|
|
|
|
return IoHandler;
|
|
}
|
|
|
|
BOOL
|
|
CSacIoHandler::Write(
|
|
IN PBYTE Buffer,
|
|
IN ULONG BufferSize
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine impelements a buffered write IoHandler operation.
|
|
|
|
Arguments:
|
|
|
|
Buffer - the data to send
|
|
BufferSize - the size of the buffer in bytes
|
|
|
|
Return Value:
|
|
|
|
TRUE - success
|
|
FALSE - otherwise
|
|
|
|
--*/
|
|
{
|
|
#if USE_SEND_BUFFER
|
|
|
|
//
|
|
// If the requested buffer to send is bigger than the
|
|
// remaining local buffer, send the local buffer.
|
|
//
|
|
if (mySendBufferIndex + BufferSize > SEND_BUFFER_SIZE) {
|
|
|
|
if (! Flush()) {
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
// ASSERT(mySendBufferIndex + BufferSize <= SEND_BUFFER_SIZE);
|
|
|
|
//
|
|
// Copy the incoming buffer into our local buffer
|
|
//
|
|
RtlCopyMemory(
|
|
&mySendBuffer[mySendBufferIndex],
|
|
Buffer,
|
|
BufferSize
|
|
);
|
|
|
|
//
|
|
// Account for the added buffer contents
|
|
//
|
|
mySendBufferIndex += BufferSize;
|
|
|
|
// ASSERT(mySendBufferIndex % sizeof(WCHAR) == 0);
|
|
|
|
//
|
|
// we succeeded
|
|
//
|
|
return TRUE;
|
|
|
|
#else
|
|
|
|
|
|
//
|
|
// Send the local buffer to the SAC channel
|
|
//
|
|
bSuccess = mySacChannel->Write(
|
|
(PCWCHAR)Buffer,
|
|
BufferSize
|
|
);
|
|
|
|
//
|
|
// Reset the local buffer index
|
|
//
|
|
mySendBufferIndex = 0;
|
|
|
|
return bSuccess;
|
|
|
|
#endif
|
|
}
|
|
|
|
BOOL
|
|
CSacIoHandler::Flush(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine implements the Flush IoHandler method.
|
|
|
|
If there is any data stored in the write buffer, it
|
|
is flushed to the SAC channel.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
TRUE - success
|
|
FALSE - otherwise
|
|
|
|
--*/
|
|
{
|
|
#if USE_SEND_BUFFER
|
|
|
|
BOOL bSuccess;
|
|
|
|
//
|
|
// default: we succeeded
|
|
//
|
|
bSuccess = TRUE;
|
|
|
|
#if 0
|
|
TCHAR Buffer[1024];
|
|
|
|
wsprintf(Buffer, TEXT("buffsize=%d\r\n"), mySendBufferIndex);
|
|
OutputDebugString(Buffer);
|
|
#endif
|
|
|
|
//
|
|
// Send the local buffer to the SAC channel
|
|
//
|
|
if (mySendBufferIndex > 0) {
|
|
|
|
bSuccess = mySacChannel->Write(
|
|
mySendBuffer,
|
|
mySendBufferIndex
|
|
);
|
|
|
|
//
|
|
// Reset the local buffer index
|
|
//
|
|
mySendBufferIndex = 0;
|
|
|
|
}
|
|
|
|
return bSuccess;
|
|
#else
|
|
return TRUE;
|
|
#endif
|
|
}
|
|
|
|
BOOL
|
|
CSacIoHandler::Read(
|
|
OUT PBYTE Buffer,
|
|
IN ULONG BufferSize,
|
|
OUT PULONG ByteCount
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine implements the Read IoHandler method.
|
|
|
|
Arguments:
|
|
|
|
Buffer - on success, contains the read data
|
|
BufferSize - the size of the read buffer in bytes
|
|
ByteCount - on success, contains the # of bytes read
|
|
|
|
Return Value:
|
|
|
|
TRUE - success
|
|
FALSE - otherwise
|
|
|
|
--*/
|
|
{
|
|
if (!mySacChannel) {
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Read data from the channel
|
|
//
|
|
return mySacChannel->Read(
|
|
Buffer,
|
|
BufferSize,
|
|
ByteCount
|
|
);
|
|
}
|
|
|
|
//
|
|
// Determine if the ioHandler has new data to read
|
|
//
|
|
BOOL
|
|
CSacIoHandler::HasNewData(
|
|
OUT PBOOL InputWaiting
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine impelements the HasNewData IoHandler method.
|
|
|
|
Arguments:
|
|
|
|
InputWaiting - on success, contains the status of the channel's
|
|
input buffer.
|
|
|
|
Return Value:
|
|
|
|
TRUE - success
|
|
FALSE - otherwise
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// Determine if the channel has new data
|
|
//
|
|
return mySacChannel->HasNewData(InputWaiting);
|
|
}
|
|
|