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.
 
 
 
 
 
 

1077 lines
32 KiB

#include "precomp.h"
//
// This table translates a given TWTY code to it corresponding
// size in bytes. The table is indexed by TWTY code.
//
const TW_UINT16 TWTY_STRFIRST = TWTY_STR32;
const TW_UINT16 TWTY_STRLAST = TWTY_STR255;
const TW_UINT32 LAST_ITEMTYPE = TWTY_STR255;
const TW_UINT32 g_ItemSizeTable[LAST_ITEMTYPE + 1] =
{
sizeof(TW_INT8),
sizeof(TW_INT16),
sizeof(TW_INT32),
sizeof(TW_UINT8),
sizeof(TW_UINT16),
sizeof(TW_UINT32),
sizeof(TW_BOOL),
sizeof(TW_FIX32),
sizeof(TW_FRAME),
sizeof(TW_STR32),
sizeof(TW_STR64),
sizeof(TW_STR128),
sizeof(TW_STR255),
};
//
// TWAIN capabilty class implemenation
//
TW_UINT16 CCap::ICap(PCAPDATA pCapData)
{
if (!pCapData || pCapData->ItemType > LAST_ITEMTYPE)
return TWCC_BADVALUE;
m_ItemSize = g_ItemSizeTable[pCapData->ItemType];
if (m_ItemSize != pCapData->ItemSize)
return TWCC_BADVALUE;
//
// StrData only applies to TW_STRxxx
//
if (pCapData->pStrData &&
(pCapData->ItemSize < sizeof(TW_STR32) ||
pCapData->ItemType < TWTY_STRFIRST ||
pCapData->ItemType > TWTY_STRLAST)) {
return TWCC_BADVALUE;
}
//
// Itemlist only applies to TWON_ENUMERATION
//
if (pCapData->ItemList && TWON_ENUMERATION != pCapData->ConType)
return TWCC_BADVALUE;
m_ItemType = pCapData->ItemType;
m_CapId = pCapData->CapId;
m_ConType = pCapData->ConType;
m_StepSize = pCapData->StepSize;
m_CurrentValue = pCapData->Current;
m_DefaultValue = pCapData->Default;
m_BaseMinValue = m_CurMinValue = pCapData->MinValue;
m_BaseMaxValue = m_CurMaxValue = pCapData->MaxValue;
m_StepSize = pCapData->StepSize;
m_CurNumItems = 0;
m_ItemList = NULL;
if (pCapData->pStrData && TWON_ONEVALUE == pCapData->ConType) {
// string data
return Set(pCapData->ItemSize, (BYTE*)pCapData->pStrData);
}
if (TWON_ENUMERATION == pCapData->ConType) {
return Set(pCapData->Default, pCapData->Current,
pCapData->MaxValue - pCapData->MinValue + 1,
(BYTE *)pCapData->ItemList
);
}
return TWCC_SUCCESS;
}
TW_UINT16 CCap::Reset()
{
m_CurMinValue = m_BaseMinValue;
m_CurMaxValue = m_BaseMaxValue;
m_CurrentValue = m_DefaultValue;
if (TWON_ENUMERATION == m_ConType) {
if(m_ResetItemList){
::LocalFree(m_ItemList);
m_ItemList = NULL;
//
// restore original enumeration values
//
m_ItemList = m_ResetItemList;
m_CurNumItems = m_ResetNumItems;
m_CurrentValue = m_ResetCurIndex;
m_DefaultValue = m_ResetDefIndex;
m_BaseMinValue = 0;
m_BaseMaxValue = m_ResetNumItems - 1;
m_CurMinValue = m_BaseMinValue;
m_CurMaxValue = m_BaseMaxValue;
m_CurEnumMask = 0xFFFFFFFF >> (32 - m_ResetNumItems);
m_CurNumItems = m_ResetNumItems;
} else {
//
// re-establish the mask and the count
//
m_CurNumItems = m_BaseMaxValue - m_BaseMinValue + 1;
}
m_CurEnumMask = 0xFFFFFFFF >> (32 - m_CurNumItems);
}
return TWCC_SUCCESS;
}
#ifdef _USE_NONSPRINTF_CONVERSION
float CCap::Fix32ToFloat(TW_FIX32 fix32)
{
float ffloat = 0.0f;
int iexp = 1;
int frac = fix32.Frac;
while(frac/10 > 0){
iexp++;
frac = (frac/10);
}
ffloat = (float)fix32.Whole + (float) ( (float) fix32.Frac / (float) pow(10,iexp));
return ffloat;
}
TW_FIX32 CCap::FloatToFix32(float ffloat)
{
TW_FIX32 fix32;
memset(&fix32,0,sizeof(fix32));
fix32.Whole = (TW_INT16)ffloat;
float fVal = (ffloat - (float)fix32.Whole);
fVal = (fVal * 100000.0f);
fix32.Frac = (TW_UINT16)(fVal);
return fix32;
}
#else // _USE_NONSPRINTF_CONVERSION
TW_FIX32 CCap::FloatToFix32(float f)
{
char fstr[64];
char *p = NULL;
TW_FIX32 f32;
sprintf(fstr, "%f", f);
p = strchr(fstr, '.');
if (p != NULL) {
*p = '\0';
f32.Whole = (TW_INT16)atoi(fstr);
f32.Frac = (TW_UINT16)atoi(p + 1);
}
return f32;
}
float CCap::Fix32ToFloat(TW_FIX32 fix32)
{
return(float)fix32.Whole + (float)(fix32.Frac / 65536.0);
}
#endif // _USE_NONSPRINTF_CONVERSION
TW_UINT32 CCap::ExtractValue(BYTE *pData)
{
TW_UINT32 Value = 0;
if (pData) {
switch (m_ItemType) {
case TWTY_INT8:
Value = *((TW_INT8 *)pData);
break;
case TWTY_UINT8:
Value = *((TW_UINT8 *)pData);
break;
case TWTY_INT16:
Value = *((TW_INT16 *)pData);
break;
case TWTY_UINT16:
Value = *((TW_UINT16 *)pData);
break;
case TWTY_INT32:
Value = *((TW_INT32 *)pData);
break;
case TWTY_UINT32:
Value = *((TW_UINT32 *)pData);
break;
case TWTY_BOOL:
Value = *((TW_BOOL *)pData);
break;
case TWTY_FIX32:
Value = *((TW_UINT32 *)pData);
break;
default:
break;
}
}
return Value;
}
TW_UINT32 CCap::GetCurrent()
{
if (m_ItemSize > sizeof(TW_UINT32))
return 0;
if (TWON_ENUMERATION == m_ConType) {
DBG_TRC(("CCap::GetCurrent(), Extracting %d index from TWON_ENUMERATION",m_CurrentValue));
return ExtractValue(m_ItemList + m_CurrentValue * m_ItemSize);
}
return m_CurrentValue;
}
TW_UINT32 CCap::GetDefault()
{
if (m_ItemSize > sizeof(TW_UINT32))
return 0;
if (TWON_ENUMERATION == m_ConType) {
return ExtractValue(m_ItemList + m_DefaultValue * m_ItemSize);
}
return m_DefaultValue;
}
TW_UINT16 CCap::Set(TW_UINT32 StrDataSize,BYTE *pStrData)
{
if (m_ItemSize != StrDataSize || TWTY_STRFIRST < m_ItemType ||
TWTY_STRLAST < m_ItemType) {
//
// Only apply to string
//
return TWCC_BADVALUE;
}
if (!m_pStrData) {
m_pStrData = new BYTE[StrDataSize];
if (!m_pStrData)
return TWCC_LOWMEMORY;
}
memcpy(m_pStrData, pStrData, StrDataSize);
return TWCC_SUCCESS;
}
TW_UINT16 CCap::Set(TW_UINT32 DefValue,TW_UINT32 CurValue,TW_UINT32 MinValue,
TW_UINT32 MaxValue,TW_UINT32 StepSize)
{
//
// This is for TWON_ONEVALUE or TWON_RANGE container type only
//
if (TWON_ONEVALUE != m_ConType && TWON_RANGE != m_ConType)
return TWCC_BADVALUE;
m_BaseMinValue = m_CurMinValue = MinValue;
m_BaseMaxValue = m_CurMaxValue = MaxValue;
m_StepSize = StepSize;
m_CurrentValue = CurValue;
m_DefaultValue = DefValue;
return TWCC_SUCCESS;
}
TW_UINT16 CCap::Set(TW_UINT32 DefIndex,TW_UINT32 CurIndex,TW_UINT32 NumItems,
BYTE *ItemList,BOOL bForce)
{
//
// Total number of items must be less or equal to 32
// The container type must be TWON_ENUMERATION.
//
if(bForce){
m_ConType = TWON_ENUMERATION;
}
return Set(DefIndex,CurIndex,NumItems,ItemList);
}
TW_UINT16 CCap::Set(TW_UINT32 DefIndex,TW_UINT32 CurIndex,TW_UINT32 NumItems,
BYTE * ItemList)
{
//
// The container type must be TWON_ENUMERATION.
//
if (TWON_ENUMERATION != m_ConType)
return TWCC_BADVALUE;
//
// if we have an existing list, but not a backup
// make a backup..
//
if (m_ItemList) {
//
// make a backup if one does not exist
//
if (NULL == m_ResetItemList) {
//
// save backup list and set current list pointer
// to NULL
//
m_ResetItemList = m_ItemList;
m_ResetDefIndex = DefIndex;
m_ResetCurIndex = CurIndex;
m_ResetNumItems = NumItems;
m_ItemList = NULL;
} else {
::LocalFree(m_ItemList);
m_ItemList = NULL;
}
}
m_BaseMinValue =
m_BaseMaxValue =
m_CurMinValue =
m_CurMaxValue =
m_DefaultValue =
m_CurrentValue =
m_CurEnumMask = 0;
m_ItemList = NULL;
m_CurNumItems = 0;
if (NumItems && ItemList) {
m_ItemList = (BYTE*)LocalAlloc(LPTR,(NumItems * m_ItemSize));
if (!m_ItemList)
return TWCC_LOWMEMORY;
m_CurrentValue = CurIndex;
m_DefaultValue = DefIndex;
m_BaseMinValue = 0;
m_BaseMaxValue = NumItems - 1;
m_CurMinValue = m_BaseMinValue;
m_CurMaxValue = m_BaseMaxValue;
m_CurEnumMask = 0xFFFFFFFF >> (32 - NumItems);
m_CurNumItems = NumItems;
memcpy(m_ItemList, (BYTE*)ItemList, m_ItemSize * NumItems);
}
return TWCC_SUCCESS;
}
int CCap::CompareValue(TW_UINT32 valThis, TW_UINT32 valThat)
{
//
// When they are equal, they are equal no matter they are signed or not.
//
if (valThis == valThat)
return 0;
switch (m_ItemType) {
case TWTY_INT8:
case TWTY_INT16:
case TWTY_INT32:
//
// Signed.
//
return(TW_INT32)valThis > (TW_INT32)valThat ? 1 : -1;
break;
case TWTY_UINT8:
case TWTY_UINT16:
case TWTY_UINT32:
//
// Unsigned.
//
return valThis > valThat ? 1 : -1;
break;
case TWTY_FIX32:
{
TW_FIX32 fix32This;
TW_FIX32 fix32That;
memcpy(&fix32This, &valThis, sizeof(TW_UINT32));
memcpy(&fix32That, &valThat, sizeof(TW_UINT32));
return Fix32ToFloat(fix32This) > Fix32ToFloat(fix32That) ? 1 : -1;
break;
}
case TWTY_BOOL:
{
//
// eqaul or non-eqaul. Relational comparisons are meaningless
//
// valVal == valAgianst is handled up front.
//
if (valThis && valThat)
return 0;
//
// We know they are non-eqaul but we can not tell which one
// is larger.
//
return -2;
break;
}
default:
return -2;
}
}
TW_UINT32 CCap::GetClosestValue(TW_UINT32 Value)
{
if (TWON_RANGE != m_ConType)
return Value;
TW_UINT32 ClosestValue = Value;
if (TWON_RANGE == m_ConType) {
if (CompareValue(ClosestValue, m_CurMinValue) >= 0 &&
CompareValue(m_CurMaxValue, ClosestValue) >= 0) {
TW_UINT32 AlignedValue;
AlignedValue = m_CurMinValue;
while (CompareValue(m_CurMaxValue, AlignedValue) >= 0) {
if (CompareValue(AlignedValue, ClosestValue) >= 0) {
//
// either the values match or we found
// the closest one
//
ClosestValue = AlignedValue;
break;
}
AlignedValue += m_StepSize;
}
}
}
return ClosestValue;
}
TW_UINT16 CCap::SetCurrent(TW_UINT32 NewValue)
{
TW_UINT16 twCc = TWCC_SUCCESS;
switch (m_ConType) {
case TWON_ONEVALUE:
if(m_ItemType == TWTY_BOOL){
m_CurrentValue = NewValue;
} else {
if (m_CapId == CAP_XFERCOUNT){
//
// since we are dealing with unsigned values, just
// allow the setting for CAP_XFERCOUNT to fall through.
//
m_CurrentValue = NewValue;
} else {
// The value must be between m_CurMinValue and m_CurMaxValue
if (CompareValue(NewValue, m_CurMinValue) >= 0 &&
CompareValue(m_CurMaxValue, NewValue) >= 0) {
//
// The value is okay. Set it
//
m_CurrentValue = NewValue;
} else {
twCc = TWCC_BADVALUE;
}
}
}
break;
case TWON_RANGE:
//
// The value must be between m_CurMinValue and m_CurMaxValue.
//
if (CompareValue(NewValue, m_CurMinValue) >= 0 &&
CompareValue(m_CurMaxValue, NewValue) >= 0) {
m_CurrentValue = GetClosestValue(NewValue);
} else {
twCc = TWCC_BADVALUE;
}
break;
default:
twCc = TWCC_BADVALUE;
break;
}
return twCc;
}
TW_UINT16 CCap::SetCurrent(VOID *pNewValue)
{
if (!pNewValue)
return TWCC_BADVALUE;
TW_UINT16 twCc;
switch (m_ConType) {
case TWON_ONEVALUE:
if (m_ItemSize <= sizeof(TW_UINT32)) {
// simple case, do it the easy way
twCc = SetCurrent(*((TW_UINT32 *)pNewValue));
} else {
// this must be a string
memcpy(m_pStrData, pNewValue, m_ItemSize);
twCc = TWCC_SUCCESS;
}
break;
case TWON_RANGE:
twCc = SetCurrent(*((TW_UINT32 *)pNewValue));
break;
case TWON_ENUMERATION:
{
TW_UINT32 ui32;
TW_UINT32 Mask;
BYTE *ItemList;
//
// Presume guilty
//
twCc = TWCC_BADVALUE;
Mask = m_CurEnumMask >> m_CurMinValue;
//
// Have an alias so that we can save some calculations
//
ItemList = m_ItemList + m_CurMinValue * m_ItemSize;
for (ui32 = m_CurMinValue; ui32 <= m_CurMaxValue; ui32 ++) {
if (Mask & 1) {
//
// This item is one of the possible selections
//
if (!memcmp(ItemList, (BYTE*)pNewValue, m_ItemSize)) {
// The new value is within the selection and is
// one of the selection. We do not find the
// closes value for enumeration. Either they match or
// they do not.
m_CurrentValue = ui32;
twCc = TWCC_SUCCESS;
}
}
//
// Advance the item data pointer
//
Mask >>= 1;
ItemList += m_ItemSize;
}
break;
}
default:
twCc = TWCC_BADVALUE;
}
return twCc;
}
TW_UINT16 CCap::GetOneValue(BOOL bDefault,TW_CAPABILITY *ptwCap)
{
if (!ptwCap)
return TWCC_BADCAP;
TW_UINT32 TheValue;
TheValue = (bDefault) ? m_DefaultValue : m_CurrentValue;
HGLOBAL hContainer;
TW_UINT32 ExtraSize;
ExtraSize = m_ItemSize <= sizeof(TW_UINT32) ? 0 : m_ItemSize;
hContainer = GlobalAlloc(GHND, sizeof(TW_ONEVALUE) + ExtraSize);
if (hContainer) {
TW_ONEVALUE *pOneValue = (TW_ONEVALUE*)GlobalLock(hContainer);
if (pOneValue) {
pOneValue->ItemType = m_ItemType;
ptwCap->ConType = TWON_ONEVALUE;
if (!ExtraSize) {
// simple data
if (TWON_ENUMERATION == m_ConType) {
pOneValue->Item = ExtractValue(m_ItemList + TheValue * m_ItemSize);
} else
pOneValue->Item = TheValue;
} else {
BYTE *pData;
if (m_pStrData) {
pData = m_pStrData;
} else {
// string data in enumeration
pData = m_ItemList + TheValue * m_ItemSize;
}
memcpy(&pOneValue->Item, pData, m_ItemSize);
}
GlobalUnlock(hContainer);
ptwCap->hContainer = hContainer;
return TWCC_SUCCESS;
} else {
GlobalFree(hContainer);
}
}
return TWCC_LOWMEMORY;
}
TW_UINT16 CCap::Get(TW_CAPABILITY *ptwCap)
{
if (!ptwCap)
return TWCC_BADCAP;
HGLOBAL hContainer = NULL;
TW_UINT16 twCc = TWCC_SUCCESS;
TW_RANGE *ptwRange = NULL;
TW_ENUMERATION *ptwEnum = NULL;
ptwCap->ConType = m_ConType;
BYTE *pDst = NULL;
BYTE *pSrc = NULL;
TW_UINT32 Size = 0;
TW_UINT32 Mask = 0;
TW_UINT32 ui32 = 0;
switch (m_ConType) {
case TWON_ONEVALUE:
twCc = GetCurrent(ptwCap);
break;
case TWON_RANGE:
{
hContainer = GlobalAlloc(GHND, sizeof(TW_RANGE));
if (hContainer) {
ptwRange = (TW_RANGE *)GlobalLock(hContainer);
if (ptwRange) {
ptwRange->ItemType = m_ItemType;
ptwRange->MinValue = m_CurMinValue;
ptwRange->MaxValue = m_CurMaxValue;
ptwRange->StepSize = m_StepSize;
ptwRange->DefaultValue = m_DefaultValue;
ptwRange->CurrentValue = m_CurrentValue;
GlobalUnlock(hContainer);
ptwCap->hContainer = hContainer;
twCc = TWCC_SUCCESS;
} else {
//
// Unable to lock the memory.
//
GlobalFree(hContainer);
twCc = TWCC_LOWMEMORY;
}
} else {
//
// Unable to allocate memory for the container
//
twCc = TWCC_LOWMEMORY;
}
break;
}
case TWON_ENUMERATION:
{
Size = sizeof(TW_ENUMERATION) + (m_CurNumItems * m_ItemSize);
hContainer = GlobalAlloc(GHND, Size);
if (hContainer) {
ptwEnum = (TW_ENUMERATION *)GlobalLock(hContainer);
if (ptwEnum) {
ptwEnum->ItemType = m_ItemType;
ptwEnum->NumItems = m_CurNumItems;
ptwEnum->DefaultIndex = m_DefaultValue;
ptwEnum->CurrentIndex = m_CurrentValue;
pDst = &ptwEnum->ItemList[0];
pSrc = m_ItemList + m_CurMinValue * m_ItemSize;
Mask = m_CurEnumMask >> m_CurMinValue;
for (ui32 = m_CurMinValue; ui32 <= m_CurMaxValue; ui32++) {
if (Mask & 1) {
//
// got one to return. Copy it to the
// returning buffer
memcpy(pDst, pSrc, m_ItemSize);
pDst += m_ItemSize;
}
pSrc += m_ItemSize;
Mask >>= 1;
}
GlobalUnlock(ptwEnum);
ptwCap->hContainer = hContainer;
twCc = TWCC_SUCCESS;
} else {
twCc = TWCC_LOWMEMORY;
GlobalFree(hContainer);
}
} else {
twCc = TWCC_LOWMEMORY;
}
break;
}
default:
twCc = TWCC_BADVALUE;
break;
}
return twCc;
}
TW_UINT16 CCap::Set(TW_CAPABILITY *ptwCap)
{
if ((!ptwCap)||(NULL == ptwCap->hContainer)||(INVALID_HANDLE_VALUE == ptwCap->hContainer))
return TWCC_BADCAP;
TW_UINT16 twCc = TWCC_SUCCESS;
TW_ONEVALUE *pOneValue = NULL;
TW_RANGE *pRange = NULL;
TW_ENUMERATION *ptwEnum = NULL;
switch (ptwCap->ConType) {
case TWON_ONEVALUE:
{
DBG_TRC(("CCap::Set(TW_CAPABILITY *ptwCap) -> TWON_ONEVALUE"));
pOneValue = (TW_ONEVALUE*)GlobalLock(ptwCap->hContainer);
if (pOneValue != NULL) {
if (pOneValue->ItemType == m_ItemType) {
twCc = SetCurrent(&pOneValue->Item);
} else {
pOneValue->ItemType = m_ItemType;
twCc = SetCurrent(&pOneValue->Item);
//twCc = TWCC_BADVALUE;
}
DBG_TRC(("Application wanted to set (%d) as the value.",pOneValue->Item));
GlobalUnlock(ptwCap->hContainer);
} else {
twCc = TWCC_LOWMEMORY;
}
break;
}
case TWON_RANGE:
{
DBG_TRC(("CCap::Set(TW_CAPABILITY *ptwCap) -> TWON_RANGE"));
pRange = (TW_RANGE*)GlobalLock(ptwCap->hContainer);
if (pRange != NULL) {
if (CompareValue(pRange->MinValue, m_BaseMinValue) < 0 ||
CompareValue(pRange->MinValue, m_BaseMaxValue) > 0 ||
CompareValue(pRange->MaxValue, m_BaseMinValue) < 0 ||
CompareValue(pRange->MaxValue, m_BaseMaxValue) > 0 ||
CompareValue(pRange->CurrentValue, pRange->MinValue) < 0 ||
CompareValue(pRange->CurrentValue, pRange->MaxValue) > 0) {
twCc = TWCC_BADVALUE;
} else {
//
// Ignore StepSize since it does not make sense for
// the application to change it.
//
m_CurMinValue = GetClosestValue(pRange->MinValue);
m_CurMaxValue = GetClosestValue(pRange->MaxValue);
m_CurrentValue = GetClosestValue(pRange->CurrentValue);
twCc = TWCC_SUCCESS;
}
GlobalUnlock(ptwCap->hContainer);
} else {
twCc = TWCC_LOWMEMORY;
}
break;
}
case TWON_ENUMERATION:
{
DBG_TRC(("CCap::Set(TW_CAPABILITY *ptwCap) -> TWON_ENUMERATION"));
twCc = TWCC_SUCCESS;
ptwEnum = (TW_ENUMERATION *)GlobalLock(ptwCap->hContainer);
if (ptwEnum != NULL) {
DBG_TRC(("Application sent this Enumeration to be set:"));
Debug_DumpEnumerationValues(ptwEnum);
if (m_ConType == TWON_ENUMERATION) {
DBG_TRC(("We are a natural TWON_ENUMERATION"));
DBG_TRC(("Our List contains:"));
Debug_DumpEnumerationValues(NULL);
} else {
DBG_TRC(("We are not a natural TWON_ENUMERATION."));
//
// fail at the moment, because I need to look up, to see if we should
// construct an TWON_ENUMERATION to send back to the application.
//
twCc = TWCC_BADVALUE;
//
// "break" here to avoid accessing any bad list data, and to
// continue the flow of execution
//
break;
}
//
// assign the list pointers
//
BYTE *pDSList = m_ItemList;
BYTE *pAppList = ptwEnum->ItemList;
UINT ValueIndex = 0;
//
// Compare lists, if any value is requested that we don't support,
// fail them, because the application is trying alter the sources
// supported values..*smack* BAD APPLICATION!....fail them with
// TWRC_FAILURE, TWCC_BADVALUE. That way they know that some value
// in their enumeration list set was invalid.
//
BOOL bFoundItem = FALSE;
BOOL bBuildEnumeration = TRUE;
UINT NEWMaxValue = 0;
UINT NEWMinValue = 0;
UINT NEWEnumMask = 0;
for (UINT AppListIndex = 0;AppListIndex < ptwEnum->NumItems;AppListIndex++) {
//
// reset Data Source's List pointer for searching
//
pDSList = m_ItemList;
ValueIndex = 0;
while ((ValueIndex < m_BaseMaxValue + 1 /* m_CurNumItems */) && (!bFoundItem)) {
if(*pDSList == *pAppList){
DBG_TRC(("Found Item %d!",*pAppList));
bFoundItem = TRUE;
//
// set mask value
//
NEWEnumMask |= 1 << ValueIndex;
//
// update MIN/MAX values
//
if (ValueIndex > NEWMaxValue){
NEWMaxValue = ValueIndex;
}
if (ValueIndex < NEWMinValue) {
NEWMinValue = ValueIndex;
}
}
ValueIndex++;
pDSList += ValueSize(m_ItemType);
}
if(!bFoundItem) {
//
// we were not found, so break, and fail
//
DBG_TRC(("Could not find Item %d!",*pAppList));
twCc = TWCC_BADVALUE;
//
// set build enumeration flag to false, because we don't want to
// construct an enumeration with invalid entries
//
bBuildEnumeration = FALSE;
break;
} else {
//
// set found flag, and continue searching
//
bFoundItem = FALSE;
}
pAppList += ValueSize(ptwEnum->ItemType);
}
//
// set the enumeration, if all values were found, and accounted for
//
if(bBuildEnumeration) {
DBG_TRC(("Set the application's enumeration"));
Set(ptwEnum->DefaultIndex,ptwEnum->CurrentIndex,ptwEnum->NumItems,(BYTE*)ptwEnum->ItemList);
DBG_TRC(("What does our new enumeration look like?"));
Debug_DumpEnumerationValues(NULL);
}
GlobalUnlock(ptwCap->hContainer);
} else {
twCc = TWCC_LOWMEMORY;
}
break;
}
default:
DBG_TRC(("What is this container type [%X]???",ptwCap->ConType));
twCc = TWCC_BADVALUE;
break;
}
return twCc;
}
TW_UINT16 CCap::ValueSize(TW_UINT16 uTWAINType)
{
TW_UINT16 uSize = 0;
switch(uTWAINType) {
case TWTY_INT8:
uSize = sizeof(TW_INT8);
break;
case TWTY_INT16:
uSize = sizeof(TW_INT16);
break;
case TWTY_INT32:
uSize = sizeof(TW_INT32);
break;
case TWTY_UINT8:
uSize = sizeof(TW_UINT8);
break;
case TWTY_UINT16:
uSize = sizeof(TW_UINT16);
break;
case TWTY_UINT32:
uSize = sizeof(TW_UINT32);
break;
case TWTY_BOOL:
uSize = sizeof(TW_BOOL);
break;
case TWTY_FIX32:
uSize = sizeof(TW_FIX32);
break;
case TWTY_FRAME:
uSize = sizeof(TW_FRAME);
break;
case TWTY_STR32:
uSize = sizeof(TW_STR32);
break;
case TWTY_STR64:
uSize = sizeof(TW_STR64);
break;
case TWTY_STR128:
uSize = sizeof(TW_STR128);
break;
case TWTY_STR255:
uSize = sizeof(TW_STR255);
break;
default:
uSize = sizeof(TW_UINT16);
break;
}
return uSize;
}
TW_UINT16 CCap::CalcEnumBitMask(TW_ENUMERATION *pEnum)
{
TW_UINT32 nBitMask = 0x0;
TW_UINT16 twStatus = TWCC_SUCCESS;
for(unsigned int nIndex=0;nIndex<pEnum->NumItems;nIndex++)
{
switch(pEnum->ItemType)
{
case TWTY_UINT8:
{
pTW_UINT8 pBits = pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
case TWTY_INT8:
{
pTW_INT8 pBits = (pTW_INT8)pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
case TWTY_UINT16:
{
pTW_UINT16 pBits = (pTW_UINT16)pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
case TWTY_INT16:
{
pTW_INT16 pBits = (pTW_INT16)pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
case TWTY_UINT32:
{
pTW_UINT32 pBits = (pTW_UINT32)pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
case TWTY_INT32:
{
pTW_INT32 pBits = (pTW_INT32)pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
case TWTY_BOOL:
{
pTW_BOOL pBits = (pTW_BOOL)pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
/*case TWTY_FIX32:
{
pTW_FIX32 pBits = pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
*/
case TWTY_STR32:
{
pTW_STR32 pBits = (pTW_STR32)pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
case TWTY_STR64:
{
pTW_STR64 pBits = (pTW_STR64)pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
case TWTY_STR128:
{
pTW_STR128 pBits = (pTW_STR128)pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
case TWTY_STR255:
{
pTW_STR255 pBits = (pTW_STR255)pEnum->ItemList;
nBitMask |= 1<<pBits[nIndex];
}
break;
default:
twStatus = TWCC_BADVALUE;
break;
}
}
if(twStatus == TWCC_SUCCESS) {
m_CurEnumMask = nBitMask;
}
return twStatus;
}
//
// debug helpers
//
void CCap::Debug_DumpEnumerationValues(TW_ENUMERATION *ptwEnumeration)
{
BYTE *pList = NULL;
UINT ValueIndex = 0;
UINT iItemSize = 0;
UINT iNumItems = 0;
DBG_TRC(("CCap::Debug_DumpEnumerationValues(), Enumeration Value debug dump"));
if(ptwEnumeration){
pList = ptwEnumeration->ItemList;
DBG_TRC(("Enumeration Values:"));
DBG_TRC(("ItemType = %d",ptwEnumeration->ItemType));
DBG_TRC(("NumItems = %d",ptwEnumeration->NumItems));
DBG_TRC(("CurrentIndex = %d",ptwEnumeration->CurrentIndex));
DBG_TRC(("DefaultIndex = %d",ptwEnumeration->DefaultIndex));
iItemSize = ValueSize(ptwEnumeration->ItemType);
iNumItems = ptwEnumeration->NumItems;
} else {
pList = m_ItemList;
DBG_TRC(("Enumeration Values: (current internal settings)"));
DBG_TRC(("ItemType = %d",m_ItemType));
DBG_TRC(("NumItems = %d",m_CurNumItems));
DBG_TRC(("CurrentIndex = %d",m_CurrentValue));
DBG_TRC(("DefaultIndex = %d",m_DefaultValue));
iItemSize = ValueSize(m_ItemType);
iNumItems = m_CurNumItems;
}
#ifdef DEBUG
DBG_TRC(("Values:"));
for(ValueIndex = 0;ValueIndex < iNumItems;ValueIndex++) {
DBG_TRC(("ItemList[%d] = %d",ValueIndex,*pList));
pList += iItemSize;
}
#endif
}