Leaked source code of windows server 2003
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.
 
 
 
 
 
 

568 lines
14 KiB

#define __DEBUG_MODULE_IN_USE__ CIC_ACTIONS_CPP
#include "stdhdrs.h"
#include "actions.h"
// @doc
/**********************************************************************
*
* @module Actions.cpp |
*
* Implementation of accessor functions for action objects.
*
* History
* ----------------------------------------------------------
* Mitchell S. Dernis Original
*
* (c) 1986-1998 Microsoft Corporation. All right reserved.
*
* @topic Actions |
* Contains the implementation of the accessor functions for the
* EVENT, TIMED_EVENT, TIMED_MACRO, and related structures.
*
**********************************************************************/
/***********************************************************************************
**
** @mfunc Get an event in a TIMED_MACRO structure, given an index
**
** @rdesc Pointer to next event in TIMED_MACRO
** @rdesc NULL if index too big.
**
*************************************************************************************/
PTIMED_EVENT
TIMED_MACRO::GetEvent
(
ULONG uEventNum //@parm [in] One based index of event to get.
)
{
ASSERT( 0 != uEventNum && "GetEvent uses 1 based index of events!");
//
// Implement in terms of GetNextEvent
//
PTIMED_EVENT pResult = NULL;
ULONG uEventIndex=0;
do
{
pResult = GetNextEvent(pResult, uEventIndex);
}while(pResult && uEventIndex!=uEventNum);
return pResult;
}
/***********************************************************************************
**
** @mfunc Get next TIMED_EVENT in a TIMED_MACRO structure.
**
** @rdesc Pointer to next TIMED_EVENT in TIMED_MACRO
**
*************************************************************************************/
PTIMED_EVENT
TIMED_MACRO::GetNextEvent
(
PTIMED_EVENT pCurrentEvent, // @parm [in] Pointer to current event.
ULONG& rulCurrentEvent // @parm [in\out] Current event before and after call.
)
{
//
// Range check, is there even a next event.
//
if( ++rulCurrentEvent > ulEventCount )
{
return NULL;
}
//
// Check if this is the first
//
if(rulCurrentEvent == 1)
{
return rgEvents;
}
//
// Otherwise skip to next
//
PCHAR pcBytePointer = reinterpret_cast<PCHAR>(pCurrentEvent);
pcBytePointer += TIMED_EVENT::RequiredByteSize(pCurrentEvent->Event.ulNumXfers);
//
// Sanity check on debug to make sure we haven't stepped over the edge.
//
ASSERT(pcBytePointer <= (reinterpret_cast<PCHAR>(this)+this->AssignmentBlock.CommandHeader.ulByteSize));
//
// Cast back to proper type
//
return reinterpret_cast<PTIMED_EVENT>(pcBytePointer);
}
/***********************************************************************************
**
** @mfunc Creates a TIMED_MACRO in an empty buffer.
**
** @rdesc Pointer to TIMED_MACRO (start of buffer), or NULL if buffer is too small
**
*************************************************************************************/
PTIMED_MACRO TIMED_MACRO::Init
(
ULONG ulVidPid, // @parm [in] Vid/Pid for macro
ULONG ulFlagsParm, // @parm [in] Flags for macro.
PCHAR pcBuffer, // @parm [in] Pointer to raw buffer
ULONG& rulRemainingBuffer // @parm [in\out] Size of buffer on entry, remaining buffer on exit
)
{
//
// Make sure buffer is large enough
//
if( rulRemainingBuffer < sizeof(TIMED_MACRO))
{
return NULL;
}
PTIMED_MACRO pThis = reinterpret_cast<PTIMED_MACRO>(pcBuffer);
//
// Copy flags
//
pThis->ulFlags = ulFlagsParm;
//
// Calculate remaining buffer
//
rulRemainingBuffer -= (sizeof(TIMED_MACRO) - sizeof(TIMED_EVENT));
//
// Fill out AssignmentBlock
//
pThis->AssignmentBlock.CommandHeader.eID = eTimedMacro;
pThis->AssignmentBlock.CommandHeader.ulByteSize = (sizeof(TIMED_MACRO) - sizeof(TIMED_EVENT));
pThis->AssignmentBlock.ulVidPid = ulVidPid;
// Set no events as of yet
pThis->ulEventCount=0;
return pThis;
}
/***********************************************************************************
**
** HRESULT AddEvent(PTIMED_EVENT pTimedEvent, PTIMED_MACRO pTimedMacro, ULONG& rulRemainingBuffer)
**
** @mfunc Adds an event to a TIMED_MACRO and recalulates remaining buffer.
**
** @rdesc S_OK on Success, E_OUTOFMEMORY if buffer is too small
**
*************************************************************************************/
HRESULT TIMED_MACRO::AddEvent
(
PTIMED_EVENT pTimedEvent, // @parm [in] Pointer to TIMED_EVENT to add
ULONG& rulRemainingBuffer // @parm [in\out] Remaining buffer before and after call.
)
{
//
// Make sure buffer is large enough
//
ULONG ulEventLength = TIMED_EVENT::RequiredByteSize(pTimedEvent->Event.ulNumXfers);
if( ulEventLength > rulRemainingBuffer)
{
return E_OUTOFMEMORY;
}
//
// Skip to end of TIMED_MACRO as is.
//
PCHAR pcBuffer = reinterpret_cast<PCHAR>(this) + AssignmentBlock.CommandHeader.ulByteSize;
//
// Copy event
//
DualMode::BufferCopy
(
reinterpret_cast<PVOID>(pcBuffer),
reinterpret_cast<PVOID>(pTimedEvent),
ulEventLength
);
//
// Fix up size in COMMAND_HEADER
//
AssignmentBlock.CommandHeader.ulByteSize += ulEventLength;
//
// Increment number of Events
//
ulEventCount++;
//
// Recalculate remaining buffer
//
rulRemainingBuffer -= ulEventLength;
return S_OK;
}
/************************* MULTI_MACRO Functions **************************/
/***********************************************************************************
**
** @mfunc Get an event in a MULTI_MACRO structure, given an index
**
** @rdesc Pointer to next event in MULTI_MACRO
** @rdesc NULL if index too big.
**
*************************************************************************************/
EVENT*
MULTI_MACRO::GetEvent
(
ULONG uEventNum //@parm [in] One based index of event to get.
)
{
ASSERT( 0 != uEventNum && "GetEvent uses 1 based index of events!");
//
// Implement in terms of GetNextEvent
//
EVENT* pResult = NULL;
ULONG uEventIndex=0;
do
{
pResult = GetNextEvent(pResult, uEventIndex);
}while(pResult && uEventIndex!=uEventNum);
return pResult;
}
/***********************************************************************************
**
** @mfunc Get next EVENT in a MULTI_MACRO structure.
**
** @rdesc Pointer to next EVENT in MULTI_MACRO
**
*************************************************************************************/
EVENT*
MULTI_MACRO::GetNextEvent
(
EVENT* pCurrentEvent, // @parm [in] Pointer to current event.
ULONG& rulCurrentEvent // @parm [in\out] Current event before and after call.
)
{
//
// Range check, is there even a next event.
//
if( ++rulCurrentEvent > ulEventCount )
{
return NULL;
}
//
// Check if this is the first
//
if(rulCurrentEvent == 1)
{
return rgEvents;
}
//
// Otherwise skip to next
//
PCHAR pcBytePointer = reinterpret_cast<PCHAR>(pCurrentEvent);
pcBytePointer += EVENT::RequiredByteSize(pCurrentEvent->ulNumXfers);
//
// Sanity check on debug to make sure we haven't stepped over the edge.
//
ASSERT(pcBytePointer <= (reinterpret_cast<PCHAR>(this)+this->AssignmentBlock.CommandHeader.ulByteSize));
//
// Cast back to proper type
//
return reinterpret_cast<EVENT*>(pcBytePointer);
}
/***********************************************************************************
**
** @mfunc Creates a MULTI_MACRO in an empty buffer.
**
** @rdesc Pointer to MULTI_MACRO (start of buffer), or NULL if buffer is too small
**
*************************************************************************************/
MULTI_MACRO* MULTI_MACRO::Init
(
ULONG ulVidPid, // @parm [in] Vid/Pid for macro
ULONG ulFlagsParm, // @parm [in] Flags for macro.
PCHAR pcBuffer, // @parm [in] Pointer to raw buffer
ULONG& rulRemainingBuffer // @parm [in\out] Size of buffer on entry, remaining buffer on exit
)
{
//
// Make sure buffer is large enough
//
if( rulRemainingBuffer < sizeof(MULTI_MACRO))
{
return NULL;
}
MULTI_MACRO* pThis = reinterpret_cast<MULTI_MACRO*>(pcBuffer);
//
// Copy flags
//
pThis->ulFlags = ulFlagsParm;
//
// Calculate remaining buffer
//
rulRemainingBuffer -= (sizeof(MULTI_MACRO) - sizeof(EVENT));
//
// Fill out AssignmentBlock
//
pThis->AssignmentBlock.CommandHeader.eID = eTimedMacro;
pThis->AssignmentBlock.CommandHeader.ulByteSize = (sizeof(MULTI_MACRO) - sizeof(EVENT));
pThis->AssignmentBlock.ulVidPid = ulVidPid;
// Set no events as of yet
pThis->ulEventCount=0;
return pThis;
}
/***********************************************************************************
**
** HRESULT AddEvent(EVENT* pTimedEvent, MULTI_MACRO* pTimedMacro, ULONG& rulRemainingBuffer)
**
** @mfunc Adds an event to a MULTI_MACRO and recalulates remaining buffer.
**
** @rdesc S_OK on Success, E_OUTOFMEMORY if buffer is too small
**
*************************************************************************************/
HRESULT MULTI_MACRO::AddEvent
(
EVENT* pEvent, // @parm [in] Pointer to EVENT to add
ULONG& rulRemainingBuffer // @parm [in\out] Remaining buffer before and after call.
)
{
//
// Make sure buffer is large enough
//
ULONG ulEventLength = EVENT::RequiredByteSize(pEvent->ulNumXfers);
if( ulEventLength > rulRemainingBuffer)
{
return E_OUTOFMEMORY;
}
//
// Skip to end of TIMED_MACRO as is.
//
PCHAR pcBuffer = reinterpret_cast<PCHAR>(this) + AssignmentBlock.CommandHeader.ulByteSize;
//
// Copy event
//
DualMode::BufferCopy
(
reinterpret_cast<PVOID>(pcBuffer),
reinterpret_cast<PVOID>(pEvent),
ulEventLength
);
//
// Fix up size in COMMAND_HEADER
//
AssignmentBlock.CommandHeader.ulByteSize += ulEventLength;
//
// Increment number of Events
//
ulEventCount++;
//
// Recalculate remaining buffer
//
rulRemainingBuffer -= ulEventLength;
return S_OK;
}
/************************* MAP_LIST Functions (also CYCLE_MAP, KEYSTRING_MAP) **************************/
/***********************************************************************************
**
** @mfunc Creates a MAP_LIST in an empty buffer. The assignment block will be set
** as eKeyString be sure to change it if you have other preferences
**
** @rdesc Pointer to MAP_LIST (start of buffer), or NULL if buffer is too small
**
*************************************************************************************/
MAP_LIST* MAP_LIST::Init
(
ULONG ulVidPid, // @parm [in] Vid/Pid for macro
ULONG ulFlagsParm, // @parm [in] Flags for macro.
PCHAR pcBuffer, // @parm [in] Pointer to raw buffer
ULONG& rulRemainingBuffer // @parm [in\out] Size of buffer on entry, remaining buffer on exit
)
{
//
// Make sure buffer is large enough
//
if( rulRemainingBuffer < sizeof(MAP_LIST))
{
return NULL;
}
MAP_LIST* pThis = reinterpret_cast<MAP_LIST*>(pcBuffer);
//
// Copy flags
//
pThis->ulFlags = ulFlagsParm;
//
// Calculate remaining buffer
//
rulRemainingBuffer -= (sizeof(MAP_LIST) - sizeof(EVENT));
//
// Fill out AssignmentBlock
//
pThis->AssignmentBlock.CommandHeader.eID = eKeyString;
pThis->AssignmentBlock.CommandHeader.ulByteSize = (sizeof(MAP_LIST) - sizeof(EVENT));
pThis->AssignmentBlock.ulVidPid = ulVidPid;
//Init event count to zero
pThis->ulEventCount=0;
return pThis;
}
/***********************************************************************************
**
** @mfunc Get next EVENT in a MAP_LIST structure.
**
** @rdesc Pointer to requested EVENT in MAP_LIST, or NULL if index too big
**
*************************************************************************************/
PEVENT MAP_LIST::GetEvent
(
ULONG uEventNum //@parm [in] One based index of event to get.
)
{
ASSERT( 0 != uEventNum && "GetEvent uses 1 based index of events!");
//
// Implement in terms of GetNextEvent
//
PEVENT pResult = NULL;
ULONG uEventIndex=0;
do
{
pResult = GetNextEvent(pResult, uEventIndex);
}while(pResult && uEventIndex!=uEventNum);
return pResult;
}
/***********************************************************************************
**
** PEVENT MAP_LIST::GetNextEvent(PEVENT pCurrentEvent, ULONG& rulCurrentEvent)
**
** @mfunc Gets the next event in a MAP_LIST
**
** @rdesc Pointer to next EVENT on success, NULL if no more EVENTs
**
*************************************************************************************/
PEVENT MAP_LIST::GetNextEvent
(
PEVENT pCurrentEvent, // @parm Pointer to current EVENT
ULONG& rulCurrentEvent // @parm [in/out] Event number before and after call.
)
{
//
// Range check, is there even a next event.
//
if( ++rulCurrentEvent > ulEventCount )
{
return NULL;
}
//
// Check if this is the first
//
if(rulCurrentEvent == 1)
{
return rgEvents;
}
//
// Otherwise skip to next
//
PCHAR pcBytePointer = reinterpret_cast<PCHAR>(pCurrentEvent);
pcBytePointer += EVENT::RequiredByteSize(pCurrentEvent->ulNumXfers);
//
// Sanity check on debug to make sure we haven't stepped over the edge.
//
ASSERT(pcBytePointer <= (reinterpret_cast<PCHAR>(this)+this->AssignmentBlock.CommandHeader.ulByteSize));
//
// Cast back to proper type
//
return reinterpret_cast<PEVENT>(pcBytePointer);
}
/***********************************************************************************
**
** HRESULT AddEvent(PTIMED_EVENT pTimedEvent, PTIMED_MACRO pTimedMacro, ULONG& rulRemainingBuffer)
**
** @mfunc Adds an event to a TIMED_MACRO and recalulates remaining buffer.
**
** @rdesc S_OK on Success, E_OUTOFMEMORY if buffer is too small
**
*************************************************************************************/
HRESULT MAP_LIST::AddEvent
(
EVENT* pEvent, // @parm [in] Pointer to EVENT to add
ULONG& rulRemainingBuffer // @parm [in\out] Remaining buffer before and after call.
)
{
//
// Make sure buffer is large enough
//
ULONG ulEventLength = EVENT::RequiredByteSize(pEvent->ulNumXfers);
if( ulEventLength > rulRemainingBuffer)
{
return E_OUTOFMEMORY;
}
//
// Skip to end of MAP_LIST as is.
//
PCHAR pcBuffer = reinterpret_cast<PCHAR>(this) + AssignmentBlock.CommandHeader.ulByteSize;
//
// Copy event
//
DualMode::BufferCopy
(
reinterpret_cast<PVOID>(pcBuffer),
reinterpret_cast<PVOID>(pEvent),
ulEventLength
);
//
// Fix up size in COMMAND_HEADER
//
AssignmentBlock.CommandHeader.ulByteSize += ulEventLength;
//
// Increment number of Events
//
ulEventCount++;
//
// Recalculate remaining buffer
//
rulRemainingBuffer -= ulEventLength;
return S_OK;
}