// --- AVP_dword DATA_PARAM PROP_Set_Val( HPROP prop, AVP_size_t val, AVP_dword size ) { if ( !prop ) { _RPT0( _CRT_ASSERT, "Property handle is zero" ); return 0; } if ( ((AVP_Property*)prop)->array ) { if ( val == 0 || size == 0 ) return PROP_Arr_Free( (AVP_Arr_Property*)prop ); else return PROP_Arr_Insert( prop, PROP_ARR_LAST, (void*)val, size ); } else { switch( ((AVP_Property*)prop)->type ) { case avpt_nothing : //_RPT0( _CRT_ASSERT, "Cannot set value for empty property" ); return 0; case avpt_char : if ( size == 0 || size == sizeof(AVP_char) ) { size = sizeof(AVP_char); ((AVP_CHAR_Property*)prop)->val = (AVP_char)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_wchar : if ( size == 0 || size == sizeof(AVP_wchar) ) { size = sizeof(AVP_wchar); ((AVP_WCHAR_Property*)prop)->val = (AVP_wchar)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_short : if ( size == 0 || size == sizeof(AVP_short) ) { size = sizeof(AVP_short); ((AVP_SHORT_Property*)prop)->val = (AVP_short)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_long : if ( size == 0 || size == sizeof(AVP_long) ) { size = sizeof(AVP_long); ((AVP_LONG_Property*)prop)->val = (AVP_long)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_byte : if ( size == 0 || size == sizeof(AVP_byte) ) { size = sizeof(AVP_byte); ((AVP_BYTE_Property*)prop)->val = (AVP_byte)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_group : if ( size == 0 || size == sizeof(AVP_group) ) { size = sizeof(AVP_group); ((AVP_GROUP_Property*)prop)->val = (AVP_group)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_word : if ( size == 0 || size == sizeof(AVP_word) ) { size = sizeof(AVP_word); ((AVP_WORD_Property*)prop)->val = (AVP_word)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_dword : if ( size == 0 || size == sizeof(AVP_dword) ) { size = sizeof(AVP_dword); ((AVP_DWORD_Property*)prop)->val = (AVP_dword)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_qword : case avpt_longlong : if ( val ) { if ( size == 0 || size == sizeof(AVP_qword) ) { size = sizeof(AVP_qword); memcpy( &((AVP_QWORD_Property*)prop)->val, (void*)val, sizeof(AVP_qword) ); break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } } else { memset( &((AVP_QWORD_Property*)prop)->val, 0, sizeof(AVP_qword) ); size = sizeof(AVP_qword); break; } case avpt_size_t : if ( size == 0 || size == sizeof(AVP_size_t) ) { size = sizeof(AVP_size_t); ((AVP_SIZE_T_Property*)prop)->val = (AVP_size_t)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_int : if ( size == 0 || size == sizeof(AVP_int) ) { size = sizeof(AVP_int); ((AVP_INT_Property*)prop)->val = (AVP_int)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_uint : if ( size == 0 || size == sizeof(AVP_uint) ) { size = sizeof(AVP_uint); ((AVP_UINT_Property*)prop)->val = (AVP_uint)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_bool : if ( size == 0 || size == sizeof(AVP_dword) ) { size = sizeof(AVP_bool); ((AVP_BOOL_Property*)prop)->val = (AVP_bool)val; break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } case avpt_date : if ( val ) { if ( size == 0 || size == sizeof(AVP_date) ) { size = sizeof(AVP_date); memcpy( ((AVP_DATE_Property*)prop)->val, (void*)val, sizeof(AVP_date) ); break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } } else { memset( ((AVP_DATE_Property*)prop)->val, 0, sizeof(AVP_date) ); size = sizeof(AVP_date); break; } case avpt_time : if ( val ) { if ( size == 0 || size == sizeof(AVP_time) ) { size = sizeof(AVP_time); memcpy( ((AVP_TIME_Property*)prop)->val, (void*)val, sizeof(AVP_time) ); break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } } else { memset( ((AVP_TIME_Property*)prop)->val, 0, sizeof(AVP_time) ); size = sizeof(AVP_time); break; } case avpt_datetime : if ( val ) { if ( size == 0 || size == sizeof(AVP_datetime) ) { size = sizeof(AVP_datetime); memcpy( ((AVP_DATETIME_Property*)prop)->val, (void*)val, sizeof(AVP_datetime) ); break; } else { _RPT0( _CRT_ASSERT, "Bad data size" ); return 0; } } else { memset( ((AVP_DATETIME_Property*)prop)->val, 0, sizeof(AVP_datetime) ); size = sizeof(AVP_datetime); break; } case avpt_str : _ASSERTE( allocator && liberator ); if ( val ) { if ( size == 0 ) size = (AVP_dword)strlen( (AVP_str)val ) + sizeof(AVP_char); if ( ((AVP_STR_Property*)prop)->val == 0 ) ((AVP_STR_Property*)prop)->val = allocator( size ); else { AVP_dword now = (AVP_dword)strlen( ((AVP_STR_Property*)prop)->val ) + sizeof(AVP_char); if ( now != size ) { liberator( ((AVP_STR_Property*)prop)->val ); ((AVP_STR_Property*)prop)->val = (AVP_str)allocator( size ); } } _ASSERT( ((AVP_STR_Property*)prop)->val ); memcpy( ((AVP_STR_Property*)prop)->val, (AVP_str)val, size-sizeof(AVP_char) ); ((AVP_STR_Property*)prop)->val[size-1] = 0; } else { size = 0; if ( ((AVP_STR_Property*)prop)->val != 0 ) { liberator( ((AVP_STR_Property*)prop)->val ); ((AVP_STR_Property*)prop)->val = 0; } } break; case avpt_wstr : _ASSERTE( allocator && liberator ); if ( val ) { if ( size == 0 ) size = (AVP_dword)wcslen( (wchar_t*)(AVP_wstr)val ) + 1; if ( ((AVP_WSTR_Property*)prop)->val == 0 ) ((AVP_WSTR_Property*)prop)->val = allocator( sizeof(AVP_wchar) * size ); else { AVP_dword now = (AVP_dword)wcslen( (wchar_t*)((AVP_WSTR_Property*)prop)->val ) + 1; if ( now != size ) { liberator( ((AVP_WSTR_Property*)prop)->val ); ((AVP_WSTR_Property*)prop)->val = (AVP_wstr)allocator( sizeof(AVP_wchar) * size ); } } _ASSERT( ((AVP_WSTR_Property*)prop)->val ); memcpy( ((AVP_WSTR_Property*)prop)->val, (AVP_wstr)val, (size-1)*sizeof(AVP_wchar) ); ((AVP_WSTR_Property*)prop)->val[size-1] = 0; } else { size = 0; if ( ((AVP_WSTR_Property*)prop)->val != 0 ) { liberator( ((AVP_WSTR_Property*)prop)->val ); ((AVP_WSTR_Property*)prop)->val = 0; } } break; case avpt_bin : _ASSERTE( allocator && liberator ); if ( val && size ) { if ( ((AVP_BIN_Property*)prop)->val.size != size ) { if ( ((AVP_BIN_Property*)prop)->val.data ) liberator( ((AVP_BIN_Property*)prop)->val.data ); ((AVP_BIN_Property*)prop)->val.data = (AVP_byte*)allocator( size ); _ASSERT( ((AVP_BIN_Property*)prop)->val.data ); ((AVP_BIN_Property*)prop)->val.size = size; } memcpy( ((AVP_BIN_Property*)prop)->val.data, (void*)val, size ); } else { if ( ((AVP_BIN_Property*)prop)->val.data ) liberator( ((AVP_BIN_Property*)prop)->val.data ); ((AVP_BIN_Property*)prop)->val.data = 0; ((AVP_BIN_Property*)prop)->val.size = 0; } break; default : _RPT0( _CRT_ASSERT, "Bad property type" ); return 0; }; return size; } }
// --- static AVP_dword DATA_PARAM PROP_Arr_Get( Serialize* sz, AVP_Arr_Property* prop ) { AVP_dword i, c; AVP_dword size; AVP_dword vsize; AVP_word tmpvsize; AVP_byte* s; AVP_byte arr[10]; AVP_bool res; if ( !prop || !prop->prop.array || !prop->prop.type == avpt_nothing ) { _RPT0( _CRT_ASSERT, "Property is not an array" ); return 0; } vsize = 0; if ( (sizeof( AVP_word ) == get_word( sz, &tmpvsize )) && (sizeof( prop->delta ) == get_word( sz, &prop->delta )) ) { vsize = tmpvsize; size = sizeof( prop->count ) + sizeof( prop->delta ); } else return 0; if ( !vsize ) return size; res = PROP_Arr_Catch_Mem( PROP_HANDLE(prop), vsize ); _ASSERT( res ); prop->count = vsize; switch( prop->prop.type ) { case avpt_bool : c = (vsize / 8) + ( (vsize % 8) > 0 ); if ( c > sizeof(arr) ) s = allocator( c ); else s = arr; if ( c == get_bytes(sz,s,c) ) { for( i=0; i<vsize; i++ ) { AVP_dword byte = i / 8; AVP_dword bit = i % 8; ((AVP_bool*)prop->val)[i] = (s[byte] & (1 << bit)) != 0; } } else size = 0; if ( c > sizeof(arr) ) liberator( s ); return size; case avpt_char : case avpt_wchar : case avpt_short : case avpt_long : case avpt_byte : case avpt_group : case avpt_word : case avpt_dword : case avpt_qword : case avpt_longlong: case avpt_size_t : case avpt_int : case avpt_uint : case avpt_date : case avpt_time : case avpt_datetime: case avpt_str : case avpt_wstr : case avpt_bin : break; case avpt_nothing : default : _RPT0( _CRT_ASSERT, "Bad property type" ); return 0; } for ( i = 0; i < prop->count; i++ ) { if ( (c = ReadPropertyItem( sz, prop->prop.type, ((char *) prop->val) + i * prop->isize)) == 0 ) { size = 0; break; } size += c; } return size; }
///////////////////////////////////////////// // CED2KFileLink implementation ///////////////////////////////////////////// CED2KFileLink::CED2KFileLink(const TCHAR* pszName, const TCHAR* pszSize, const TCHAR* pszHash, const CStringArray& astrParams, const TCHAR* pszSources) : m_size(pszSize) { // Here we have a little problem.. Actually the proper solution would be to decode from UTF8, // only if the string does contain escape sequences. But if user pastes a raw UTF8 encoded // string (for whatever reason), we would miss to decode that string. On the other side, // always decoding UTF8 can give flaws in case the string is valid for Unicode and UTF8 // at the same time. However, to avoid the pasting of raw UTF8 strings (which would lead // to a greater mess in the network) we always try to decode from UTF8, even if the string // did not contain escape sequences. m_name = OptUtf8ToStr(URLDecode(pszName)); m_name.Trim(); if (m_name.IsEmpty()) throw GetResString(IDS_ERR_NOTAFILELINK); SourcesList = NULL; m_hashset = NULL; m_bAICHHashValid = false; if (_tcslen(pszHash) != 32) throw GetResString(IDS_ERR_ILLFORMEDHASH); if (_tstoi64(pszSize)>=4294967295) throw GetResString(IDS_ERR_TOOLARGEFILE); if (_tstoi64(pszSize)<=0) throw GetResString(IDS_ERR_NOTAFILELINK); for (int idx = 0; idx < 16; ++idx) { m_hash[idx] = FromHexDigit(*pszHash++)*16; m_hash[idx] += FromHexDigit(*pszHash++); } bool bError = false; for (int i = 0; !bError && i < astrParams.GetCount(); i++) { const CString& strParam = astrParams.GetAt(i); ASSERT( !strParam.IsEmpty() ); CString strTok; int iPos = strParam.Find(_T('=')); if (iPos != -1) strTok = strParam.Left(iPos); if (strTok == _T("s")) { CString strURL = strParam.Mid(iPos + 1); if (!strURL.IsEmpty()) { TCHAR szScheme[INTERNET_MAX_SCHEME_LENGTH]; TCHAR szHostName[INTERNET_MAX_HOST_NAME_LENGTH]; TCHAR szUrlPath[INTERNET_MAX_PATH_LENGTH]; TCHAR szUserName[INTERNET_MAX_USER_NAME_LENGTH]; TCHAR szPassword[INTERNET_MAX_PASSWORD_LENGTH]; TCHAR szExtraInfo[INTERNET_MAX_URL_LENGTH]; URL_COMPONENTS Url = {0}; Url.dwStructSize = sizeof(Url); Url.lpszScheme = szScheme; Url.dwSchemeLength = ARRSIZE(szScheme); Url.lpszHostName = szHostName; Url.dwHostNameLength = ARRSIZE(szHostName); Url.lpszUserName = szUserName; Url.dwUserNameLength = ARRSIZE(szUserName); Url.lpszPassword = szPassword; Url.dwPasswordLength = ARRSIZE(szPassword); Url.lpszUrlPath = szUrlPath; Url.dwUrlPathLength = ARRSIZE(szUrlPath); Url.lpszExtraInfo = szExtraInfo; Url.dwExtraInfoLength = ARRSIZE(szExtraInfo); if (InternetCrackUrl(strURL, 0, 0, &Url) && Url.dwHostNameLength > 0) { SUnresolvedHostname* hostname = new SUnresolvedHostname; hostname->strURL = strURL; hostname->strHostname = szHostName; m_HostnameSourcesList.AddTail(hostname); } } else ASSERT(0); } else if (strTok == _T("p")) { CString strPartHashs = strParam.Tokenize(_T("="), iPos); if (m_hashset != NULL){ ASSERT(0); bError = true; break; } m_hashset = new CSafeMemFile(256); m_hashset->WriteHash16(m_hash); m_hashset->WriteUInt16(0); int iPartHashs = 0; int iPosPH = 0; CString strHash = strPartHashs.Tokenize(_T(":"), iPosPH); while (!strHash.IsEmpty()) { uchar aucPartHash[16]; if (!strmd4(strHash, aucPartHash)){ bError = true; break; } m_hashset->WriteHash16(aucPartHash); iPartHashs++; strHash = strPartHashs.Tokenize(_T(":"), iPosPH); } if (bError) break; m_hashset->Seek(16, CFile::begin); m_hashset->WriteUInt16(iPartHashs); m_hashset->Seek(0, CFile::begin); } else if (strTok == _T("h")) { CString strHash = strParam.Mid(iPos + 1); if (!strHash.IsEmpty()) { if (DecodeBase32(strHash, m_AICHHash.GetRawHash(), CAICHHash::GetHashSize()) == CAICHHash::GetHashSize()){ m_bAICHHashValid = true; ASSERT( m_AICHHash.GetString().CompareNoCase(strHash) == 0 ); } else ASSERT( false ); } else ASSERT( false ); } else ASSERT(0); } if (bError) { delete m_hashset; m_hashset = NULL; } if (pszSources) { TCHAR* pNewString = _tcsdup(pszSources); autoFree liberator(pNewString); TCHAR* pCh = pNewString; TCHAR* pEnd; TCHAR* pIP; TCHAR* pPort; bool bAllowSources; TCHAR date[3]; COleDateTime expirationDate; int nYear,nMonth,nDay; uint16 nCount = 0; uint32 dwID; uint16 nPort; uint32 dwServerIP = 0; uint16 nServerPort = 0; unsigned long ul; int nInvalid = 0; pCh = _tcsstr( pCh, _T("sources") ); if( pCh != NULL ) { pCh = pCh + 7; // point to char after "sources" pEnd = pCh; while( *pEnd ) pEnd++; // make pEnd point to the terminating NULL bAllowSources=true; // if there's an expiration date... if( *pCh == _T('@') && (pEnd-pCh) > 7 ) { pCh++; // after '@' date[2] = 0; // terminate the two character string date[0] = *(pCh++); date[1] = *(pCh++); nYear = _tcstol( date, 0, 10 ) + 2000; date[0] = *(pCh++); date[1] = *(pCh++); nMonth = _tcstol( date, 0, 10 ); date[0] = *(pCh++); date[1] = *(pCh++); nDay = _tcstol( date, 0, 10 ); bAllowSources = ( expirationDate.SetDate(nYear,nMonth,nDay) == 0 ); if (bAllowSources) bAllowSources=(COleDateTime::GetCurrentTime() < expirationDate); } // increment pCh to point to the first "ip:port" and check for sources if ( bAllowSources && ++pCh < pEnd ) { SourcesList = new CSafeMemFile(256); SourcesList->WriteUInt16(nCount); // init to 0, we'll fix this at the end. // for each "ip:port" source string until the end // limit to prevent overflow (uint16 due to CPartFile::AddClientSources) while( *pCh != 0 && nCount < MAXSHORT ) { pIP = pCh; // find the end of this ip:port string & start of next ip:port string. if( (pCh = _tcschr(pCh, _T(','))) != NULL ) { *pCh = 0; // terminate current "ip:port" pCh++; // point to next "ip:port" } else pCh = pEnd; // if port is not present for this ip, go to the next ip. if( (pPort = _tcschr(pIP, _T(':'))) == NULL ) { nInvalid++; continue; } *pPort = 0; // terminate ip string pPort++; // point pPort to port string. dwID = inet_addr(CStringA(pIP)); ul = _tcstoul( pPort, 0, 10 ); nPort = static_cast<uint16>(ul); // skip bad ips / ports if (ul > 0xFFFF || ul == 0 ) // port { nInvalid++; continue; } if( dwID == INADDR_NONE) { // hostname? if (_tcslen(pIP) > 512) { nInvalid++; continue; } SUnresolvedHostname* hostname = new SUnresolvedHostname; hostname->nPort = nPort; hostname->strHostname = pIP; m_HostnameSourcesList.AddTail(hostname); continue; } //TODO: This will filter out *.*.*.0 clients. Is there a nice way to fix? if( IsLowID(dwID) ) // ip { nInvalid++; continue; } SourcesList->WriteUInt32(dwID); SourcesList->WriteUInt16(nPort); SourcesList->WriteUInt32(dwServerIP); SourcesList->WriteUInt16(nServerPort); nCount++; } SourcesList->SeekToBegin(); SourcesList->WriteUInt16(nCount); SourcesList->SeekToBegin(); if (nCount==0) { delete SourcesList; SourcesList=NULL; } } } } }
// --- DATA_PROC AVP_dword DATA_PARAM PROP_Arr_Set_Items( HPROP prop, AVP_dword pos, void* from, AVP_dword count ) { AVP_dword size; AVP_dword c_count; if ( !prop || !((AVP_Property*)prop)->array || ((AVP_Property*)prop)->type == avpt_nothing ) { _RPT0( _CRT_ASSERT, "Property is not an array" ); return 0; } if ( !from || pos > ((AVP_Arr_Property*)prop)->count ) { _RPT0( _CRT_ASSERT, "Bad parameters" ); return 0; } switch( ((AVP_Property*)prop)->type ) { case avpt_char : case avpt_wchar : case avpt_short : case avpt_long : case avpt_byte : case avpt_group : case avpt_word : case avpt_dword : case avpt_qword : case avpt_longlong : case avpt_size_t : case avpt_int : case avpt_uint : case avpt_bool : case avpt_date : case avpt_time : case avpt_datetime : count /= ((AVP_Arr_Property*)prop)->isize; if ( count == 0 ) { _RPT0( _CRT_ASSERT, "Bad parameters" ); return 0; } size = 0; if ( pos + count > ((AVP_Arr_Property*)prop)->count ) { c_count = ((AVP_Arr_Property*)prop)->count - pos; count -= c_count; } else { c_count = count; count = 0; } if ( c_count ) { size += c_count * ((AVP_Arr_Property*)prop)->isize; memcpy( ((AVP_byte*)((AVP_Arr_Property*)prop)->val)+pos*((AVP_Arr_Property*)prop)->isize, from, size ); } if ( count ) size += PROP_Arr_Insert( prop, PROP_ARR_LAST, ((AVP_byte*)from)+c_count*((AVP_Arr_Property*)prop)->isize, count*((AVP_Arr_Property*)prop)->isize ); break; case avpt_str : if ( pos <= ((AVP_Arr_Property*)prop)->count ) { AVP_str* dst; if ( !count ) count = (AVP_dword)strlen( from ) + sizeof(AVP_char); dst = &((AVP_str*)((AVP_Arr_Property*)prop)->val)[ pos ]; if ( *dst ) { size = (AVP_dword)strlen( *dst ) + sizeof(AVP_char); if ( size != count ) { liberator( *dst ); *dst = allocator( count ); _ASSERT( *dst ); } } else *dst = allocator( count ); memcpy( *dst, from, count-sizeof(AVP_char) ); (*dst)[count-1] = 0; size = count; } else size = PROP_Arr_Insert( prop, PROP_ARR_LAST, from, count ); break; case avpt_wstr : if ( pos <= ((AVP_Arr_Property*)prop)->count ) { AVP_wstr* dst; if ( !count ) count = (AVP_dword)( wcslen( from ) + 1 ) * sizeof(AVP_wchar); dst = &((AVP_wstr*)((AVP_Arr_Property*)prop)->val)[ pos ]; if ( *dst ) { size = (AVP_dword)( wcslen( (wchar_t *)*dst ) + 1 ) * sizeof(AVP_wchar); if ( size != count ) { liberator( *dst ); *dst = allocator( count ); _ASSERT( *dst ); } } else *dst = allocator( count ); memcpy( *dst, from, count-sizeof(AVP_wchar) ); (*dst)[count/sizeof(AVP_wchar)-1] = 0; size = count; } else size = PROP_Arr_Insert( prop, PROP_ARR_LAST, from, count ); break; case avpt_bin : if ( pos <= ((AVP_Arr_Property*)prop)->count ) { AVP_Bin_Item* dst; if ( !count ) { _RPT0( _CRT_ASSERT, "Bad parameters" ); return 0; } dst = ((AVP_Bin_Item*)((AVP_Arr_Property*)prop)->val) + pos; if ( dst ) { if ( dst->size != count ) { dst->size = count; liberator( dst->data ); dst->data = allocator( count ); _ASSERT( dst->data ); } } else { dst->size = count; dst->data = allocator( count ); } memcpy( dst->data, from, count ); size = count; } else size = PROP_Arr_Insert( prop, PROP_ARR_LAST, from, count ); break; default : _RPT0( _CRT_ASSERT, "Bad property array type" ); return 0; } return size; }
// --- static AVP_dword DATA_PARAM PROP_Arr_Put( Serialize* sz, AVP_Arr_Property* prop ) { AVP_dword i, c; AVP_dword size; AVP_word wput; AVP_byte* s; AVP_byte arr[10]; if ( !prop || !prop->prop.array || prop->prop.type == avpt_nothing ) { _RPT0( _CRT_ASSERT, "Property is not an array" ); return 0; } if ( prop->count > USHRT_MAX ) { _RPT0( _CRT_ASSERT, "Property array is too large" ); return 0; } wput = (AVP_word)prop->count; if ( sizeof( AVP_Property ) == put_avp_property (sz, &prop->prop) && sizeof( AVP_word ) == put_word (sz, &wput) && sizeof( prop->delta ) == put_word (sz, &prop->delta) ) size = sizeof( AVP_Property ) + sizeof( AVP_word ) + sizeof( prop->delta ); else return 0; switch( prop->prop.type ) { case avpt_bool : c = (prop->count / 8) + ( (prop->count % 8) > 0 ); if ( c > sizeof(arr) ) s = allocator( c ); else s = arr; memset( s, 0, c ); for( i=0; i<prop->count; i++ ) { if ( ((AVP_bool*)prop->val)[i] ) { AVP_dword byte = i / 8; AVP_dword bit = i % 8; s[byte] |= 1 << bit; } } if ( c == put_bytes(sz,s,c) ) size += c; else size = 0; if ( c > sizeof(arr) ) liberator( s ); return size; case avpt_char : case avpt_wchar : case avpt_short : case avpt_long : case avpt_byte : case avpt_group : case avpt_word : case avpt_dword : case avpt_qword : case avpt_longlong: case avpt_size_t : case avpt_int : case avpt_uint : case avpt_date : case avpt_time : case avpt_datetime: case avpt_str : case avpt_wstr : case avpt_bin : break; case avpt_nothing : default : _RPT0( _CRT_ASSERT, "Bad array property type" ); return size; } for ( i = 0; i < prop->count; i++ ) { if ( (c = WritePropertyItem(sz,prop->prop.type,((char*)prop->val)+i*prop->isize)) == 0 ) { size = 0; break; } size += c; } return size; }