BOOL CVCAMetaParserMSXML::ParseCounts() { // Find all the events CComBSTR bsTag; MSXML2::IXMLDOMNodePtr pNode, pSubNode, pSubSubNode, pSubSubSubNode; // Great names eh ;~) MSXML2::IXMLDOMNodeListPtr pNodeList, pSubNodeList; // See if we have any objects this time round bsTag = CComBSTR( _XML_VCA ) += CComBSTR("/") += CComBSTR( _XML_COUNTS ); pNode = m_pDOMDoc->selectSingleNode( bsTag.operator BSTR() ); if( pNode ) { // There are some event specified in this packet... take a look... //m_vcaCounts.clear(); m_vcaCounts.ulTotalCounter = 0; // Select all events bsTag = CComBSTR( _XML_COUNT ); pNodeList = pNode->selectNodes( bsTag.operator BSTR() ); pNode = pNodeList->nextNode(); while( pNode ) { VCA5_PACKET_COUNT vcaCount; memset( &vcaCount, 0, sizeof( vcaCount ) ); bsTag = CComBSTR( _XML_ID ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaCount.ulId ); } bsTag = CComBSTR( _XML_VAL ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (long *)&vcaCount.iVal ); } pNode = pNodeList->nextNode(); //m_vcaCounts.ph_back( vcaCount ); m_vcaCounts.Counters[m_vcaCounts.ulTotalCounter] = vcaCount; m_vcaCounts.ulTotalCounter++; } } return TRUE; }
BOOL CVCAMetaParserMSXML::ParseHeader( ) { CComBSTR bsTag; MSXML2::IXMLDOMNodePtr pNode, pSubNode; // Find the header node bsTag = CComBSTR(_XML_VCA) += CComBSTR("/") += CComBSTR( _XML_VCA_HDR ); pNode = m_pDOMDoc->selectSingleNode( bsTag.operator BSTR() ); if( pNode ) { // Find the status header bsTag = _XML_VCA_STATUS; pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&m_vcaHdr.ulVCAStatus ); bsTag = _XML_FRAME_ID; pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&m_vcaHdr.ulFrameId ); } return TRUE; }
BOOL CVCAMetaParserMSXML::ParseBlobsImp(char* szTag, VCA5_PACKET_BLOBMAP *pBLOBMAP) { CComBSTR bsTag; MSXML2::IXMLDOMNodePtr pNode, pSubNode; // Great names eh ;~) MSXML2::IXMLDOMNodeListPtr pNodeList, pSubNodeList; unsigned int uiWidth = 0, uiHeight = 0; // See if we have any objects this time round bsTag = CComBSTR( _XML_VCA ) += CComBSTR("/") += CComBSTR( szTag ); pNode = m_pDOMDoc->selectSingleNode( bsTag.operator BSTR() ); if( pNode ) { // Tampermap is there bsTag = CComBSTR( _XML_W ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&uiWidth ); } bsTag = CComBSTR( _XML_H ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&uiHeight ); } if( uiWidth != pBLOBMAP->ulWidth || uiHeight != pBLOBMAP->ulHeight ) { if (pBLOBMAP->pBlobMap) delete [] pBLOBMAP->pBlobMap; pBLOBMAP->pBlobMap = new unsigned char[ uiWidth * (uiHeight+1) ]; pBLOBMAP->ulWidth = uiWidth; pBLOBMAP->ulHeight = uiHeight; } // Now look for the data bsTag = CComBSTR( _XML_DATA ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { unsigned char *pBlobMap = pBLOBMAP->pBlobMap; // Demunge the data CString s( (LPCWSTR) pSubNode->text ); TCHAR *pS = s.GetBuffer(0); int len = s.GetLength(); for( int i = 0; i < s.GetLength(); i++ ) { char cc = (char)pS[i]; unsigned char ucBits = m_base64[pS[i]]; *pBlobMap++ = ucBits & 0x01 ? 1 : 0; *pBlobMap++ = ucBits & 0x02 ? 1 : 0; *pBlobMap++ = ucBits & 0x04 ? 1 : 0; *pBlobMap++ = ucBits & 0x08 ? 1 : 0; *pBlobMap++ = ucBits & 0x10 ? 1 : 0; *pBlobMap++ = ucBits & 0x20 ? 1 : 0; } } pBLOBMAP->ulMapAge = 0; }else{ pBLOBMAP->ulMapAge++; // we shoud get map update every 2nd frame // if map is 2 frames old so clean it up or else we get old map hanging around if ( pBLOBMAP->ulMapAge == 2 && pBLOBMAP->pBlobMap ) { memset( pBLOBMAP->pBlobMap, 0, pBLOBMAP->ulWidth * pBLOBMAP->ulHeight ); } } return TRUE; }
//--------------------------------------------------------------------------- BOOL CVCAMetaParserMSXML::ParseCE( ) { CComBSTR bsTag; MSXML2::IXMLDOMNodePtr pNode, pSubNode, pSubSubNode; // Great names eh ;~) MSXML2::IXMLDOMNodeListPtr pNodeList; // See if we have any objects this time round bsTag = CComBSTR( _XML_VCA ) += CComBSTR("/") += CComBSTR( _XML_COUNTEVENTS ); pNode = m_pDOMDoc->selectSingleNode( bsTag.operator BSTR() ); if( pNode ) { // There are some event specified in this packet... take a look... memset(&m_vcaCountLineEvents, 0, sizeof(m_vcaCountLineEvents)); // Select all events bsTag = CComBSTR( _XML_CE ); pNodeList = pNode->selectNodes( bsTag.operator BSTR() ); // Iterate through all the nodes pNode = pNodeList->nextNode(); while( pNode ) { VCA5_COUNTLINE_EVENT clEvent; memset( &clEvent, 0, sizeof( VCA5_COUNTLINE_EVENT ) ); // pClEvent bsTag = CComBSTR( _XML_ID ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&clEvent.uiId ); } bsTag = CComBSTR( _XML_P ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI2FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned short *)&clEvent.usPos ); } bsTag = CComBSTR( _XML_W ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI2FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned short *)&clEvent.usWidth ); } bsTag = CComBSTR( _XML_N ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI2FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned short *)&clEvent.usNum ); } m_vcaCountLineEvents.CountLineEvents[m_vcaCountLineEvents.ulTotalCountLineEvents] = clEvent; m_vcaCountLineEvents.ulTotalCountLineEvents++; pNode = pNodeList->nextNode(); } } return TRUE; }
BOOL CVCAMetaParserMSXML::ParseEvents() { // Find all the events USES_CONVERSION; CComBSTR bsTag; MSXML2::IXMLDOMNodePtr pNode, pSubNode, pSubSubNode, pSubSubSubNode; // Great names eh ;~) MSXML2::IXMLDOMNodeListPtr pNodeList, pSubNodeList; // See if we have any objects this time round bsTag = CComBSTR( _XML_VCA ) += CComBSTR("/") += CComBSTR( _XML_EVENTS ); pNode = m_pDOMDoc->selectSingleNode( bsTag.operator BSTR() ); if( pNode ) { // There are some event specified in this packet... take a look... m_vcaEvents.ulTotalEvents = 0; // Select all events bsTag = CComBSTR( _XML_EVENT ); pNodeList = pNode->selectNodes( bsTag.operator BSTR() ); // Iterate through all the nodes pNode = pNodeList->nextNode(); while( pNode ) { VCA5_PACKET_EVENT vcaEvent; memset( &vcaEvent, 0, sizeof( VCA5_PACKET_EVENT ) ); // <type> bsTag = CComBSTR( _XML_TYPE ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { if( 0 == strcmp( pSubNode->text, "zone")) vcaEvent.ulEventType = VCA5_EVENT_TYPE_ZONE; else if( 0 == strcmp( pSubNode->text, "tamper")) vcaEvent.ulEventType = VCA5_EVENT_TYPE_TAMPER; } switch (vcaEvent.ulEventType) { case VCA5_EVENT_TYPE_TAMPER: m_uTamperAlarm = 300; strcpy( vcaEvent.szRuleName, "---" ); strcpy( vcaEvent.szZoneName, "---" ); break; // Deliberate fall-thru (durchfall :) case VCA5_EVENT_TYPE_ZONE: // <id> bsTag = CComBSTR( _XML_ID ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaEvent.ulId ); } // <rule_name> // TBD // <rule_id> bsTag = CComBSTR( _XML_RULE_ID ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaEvent.ulRuleId ); } // <rule_name> bsTag = CComBSTR( _XML_RULE_NAME ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { strcpy( vcaEvent.szRuleName, CT2A(pSubNode->text , CP_UTF8) ); } else { strcpy( vcaEvent.szRuleName, "---" ); } // <obj_id> (multiple) bsTag = CComBSTR( _XML_OBJ_ID ); pSubNodeList = pNode->selectNodes( bsTag.operator BSTR() ); if( pSubNodeList ) { pSubNode = pSubNodeList->nextNode(); if( pSubNode ) VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaEvent.ulObjId ); } // <zone_id> (multiple) bsTag = CComBSTR( _XML_ZONE_ID ); pSubNodeList = pNode->selectNodes( bsTag.operator BSTR() ); if( pSubNodeList ) { pSubNode = pSubNodeList->nextNode(); while( pSubNode ) { unsigned int uiZoneId; VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&uiZoneId ); vcaEvent.ulZoneId = uiZoneId; break; pSubNode = pSubNodeList->nextNode(); } } // <zone_name> (multiple) bsTag = CComBSTR( _XML_ZONE_NAME ); pSubNodeList = pNode->selectNodes( bsTag.operator BSTR() ); if( pSubNodeList ) { pSubNode = pSubNodeList->nextNode(); while( pSubNode ) { std::string szZoneName; szZoneName = pSubNode->text; strcpy( vcaEvent.szZoneName, szZoneName.c_str()); // Assume only 1 break; pSubNode = pSubNodeList->nextNode(); } } /* // <obj_id> (multiple) bsTag = CComBSTR( _XML_OBJ_ID ); pSubNodeList = pNode->selectNodes( bsTag.operator BSTR() ); if( pSubNodeList ) { pSubNode = pSubNodeList->nextNode(); while( pSubNode ) { unsigned int uiObjId; VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&uiObjId ); vcaEvent.vObjIds.push_back( uiObjId ); pSubNode = pSubNodeList->nextNode(); } } // <obj_cls_name> (multiple) bsTag = CComBSTR( _XML_OBJ_CLS_NAME ); pSubNodeList = pNode->selectNodes( bsTag.operator BSTR() ); if( pSubNodeList ) { pSubNode = pSubNodeList->nextNode(); while( pSubNode ) { std::string szObjClsName; szObjClsName = pSubNode->text; vcaEvent.vObjClsNames.push_back( szObjClsName ); pSubNode = pSubNodeList->nextNode(); } } */ // <status> bsTag = CComBSTR( _XML_STATUS ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaEvent.ulStatus ); } // <start_time> bsTag = CComBSTR( _XML_START_TIME ) += CComBSTR("/") += CComBSTR( _XML_S ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { //time_t tTime; VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaEvent.tStartTime.ulSec ); //vcaEvent.tStartTime = CTime( tTime ); } bsTag = CComBSTR( _XML_START_TIME ) += CComBSTR("/") += CComBSTR( _XML_MS ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { //time_t tTime; VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaEvent.tStartTime.ulMSec ); //vcaEvent.tStartTime = CTime( tTime ); } // <end_time> bsTag = CComBSTR( _XML_END_TIME ) += CComBSTR("/") += CComBSTR( _XML_S ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { //time_t tTime; VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaEvent.tStopTime.ulSec ); //vcaEvent.tStopTime = CTime( tTime ); } bsTag = CComBSTR( _XML_END_TIME ) += CComBSTR("/") += CComBSTR( _XML_MS ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { //time_t tTime; VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaEvent.tStopTime.ulMSec ); //vcaEvent.tStopTime = CTime( tTime ); } // Bounding box ParseBBox( pNode, &vcaEvent.bBox ); m_vcaEvents.Events[m_vcaEvents.ulTotalEvents] = vcaEvent; m_vcaEvents.ulTotalEvents++; break; default: break; } pNode = pNodeList->nextNode(); } } return TRUE; }
BOOL CVCAMetaParserMSXML::ParseObjects( ) { // Find all the objects CComBSTR bsTag; MSXML2::IXMLDOMNodePtr pNode, pSubNode, pSubSubNode, pSubSubSubNode; // Great names eh ;~) MSXML2::IXMLDOMNodeListPtr pNodeList, pSubNodeList; // See if we have any objects this time round bsTag = CComBSTR( _XML_VCA ) += CComBSTR("/") += CComBSTR( _XML_OBJECTS ); pNode = m_pDOMDoc->selectSingleNode( bsTag.operator BSTR() ); // ATLTRACE( "====================================================== \n" ); if( pNode ) { // There are some in this packet // Wipe out all exisiting m_vcaObjects.ulTotalObject = 0; // Select all objects bsTag = CComBSTR( _XML_OBJECT ); pNodeList = pNode->selectNodes( bsTag.operator BSTR() ); // Iterate through all the nodes pNode = pNodeList->nextNode(); while( pNode ) { VCA5_PACKET_OBJECT vcaObj; memset( &vcaObj, 0, sizeof( vcaObj ) ); // Id bsTag = CComBSTR( _XML_ID ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaObj.ulId ); } // Calibrated height and speed bsTag = CComBSTR( _XML_CH ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaObj.ulCalibHeight); } bsTag = CComBSTR( _XML_CS ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaObj.ulCalibSpeed); } bsTag = CComBSTR( _XML_CA ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaObj.ulCalibArea); } bsTag = CComBSTR( _XML_CLS ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (long *)&vcaObj.iClassificationId); } else { vcaObj.iClassificationId = -2; // unknown } bsTag = CComBSTR( _XML_COLSIG ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { std::string tempColSigs = pSubNode->text; for(int n=0; n<VCA5_APP_PALETTE_SIZE; n++) { vcaObj.colSigs[n] = (UCHAR)strtoul( tempColSigs.substr(n*2,2).c_str(), NULL, 16 ); } // ATLTRACE( "%s: %d %d %d %d %d %d %d %d %d %d \n", tempColSigs.c_str(), // vcaObj.colSigs[0], vcaObj.colSigs[1], vcaObj.colSigs[2], vcaObj.colSigs[3], vcaObj.colSigs[4], // vcaObj.colSigs[5], vcaObj.colSigs[6], vcaObj.colSigs[7], vcaObj.colSigs[8], vcaObj.colSigs[9] ); } else { for(int n=0; n<VCA5_APP_PALETTE_SIZE; n++) { vcaObj.colSigs[n] = 0; } } // Bounding box ParseBBox( pNode, &vcaObj.bBox ); // Trail bsTag = CComBSTR( _XML_TRAIL ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { bsTag = CComBSTR( _XML_PT ); pSubNodeList = pSubNode->selectNodes( bsTag.operator BSTR() ); pSubSubNode = pSubNodeList->nextNode(); vcaObj.trail.usNumTrailPoints = 0; while( pSubSubNode ) { VCA5_POINT vcaPoint; memset( &vcaPoint, 0, sizeof( vcaPoint ) ); bsTag = CComBSTR( _XML_X ); pSubSubSubNode = pSubSubNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubSubSubNode ) { VarUI2FromStr( pSubSubSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned short *)&vcaPoint.x ); } bsTag = CComBSTR( _XML_Y ); pSubSubSubNode = pSubSubNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubSubSubNode ) { VarUI2FromStr( pSubSubSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned short *)&vcaPoint.y); } // Ph it (like Salt 'n' Pepa) vcaObj.trail.trailPoints[vcaObj.trail.usNumTrailPoints] = vcaPoint; vcaObj.trail.usNumTrailPoints++; pSubSubNode = pSubNodeList->nextNode(); } } // Flags bsTag = CComBSTR( _XML_FLAGS ); pSubNode = pNode->selectSingleNode( bsTag.operator BSTR() ); if( pSubNode ) { VarUI4FromStr( pSubNode->text, LCID_ENGLISH, LOCALE_NOUSEROVERRIDE, (unsigned long *)&vcaObj.ulFlags ); } m_vcaObjects.Objects[m_vcaObjects.ulTotalObject] = vcaObj; //m_vcaObjects.ph_back( vcaObj ); m_vcaObjects.ulTotalObject++; pNode = pNodeList->nextNode(); } } return TRUE; }
static HRESULT WINAPI convert_DataConvert(IDataConvert* iface, DBTYPE src_type, DBTYPE dst_type, DBLENGTH src_len, DBLENGTH *dst_len, void *src, void *dst, DBLENGTH dst_max_len, DBSTATUS src_status, DBSTATUS *dst_status, BYTE precision, BYTE scale, DBDATACONVERT flags) { convert *This = impl_from_IDataConvert(iface); HRESULT hr; TRACE("(%p)->(%d, %d, %ld, %p, %p, %p, %ld, %d, %p, %d, %d, %x)\n", This, src_type, dst_type, src_len, dst_len, src, dst, dst_max_len, src_status, dst_status, precision, scale, flags); *dst_status = DBSTATUS_E_BADACCESSOR; if(IDataConvert_CanConvert(iface, src_type, dst_type) != S_OK) { return DB_E_UNSUPPORTEDCONVERSION; } if(src_type == DBTYPE_STR) { BSTR b; DWORD len; if(flags & DBDATACONVERT_LENGTHFROMNTS) len = MultiByteToWideChar(CP_ACP, 0, src, -1, NULL, 0) - 1; else len = MultiByteToWideChar(CP_ACP, 0, src, src_len, NULL, 0); b = SysAllocStringLen(NULL, len); if(!b) return E_OUTOFMEMORY; if(flags & DBDATACONVERT_LENGTHFROMNTS) MultiByteToWideChar(CP_ACP, 0, src, -1, b, len + 1); else MultiByteToWideChar(CP_ACP, 0, src, src_len, b, len); hr = IDataConvert_DataConvert(iface, DBTYPE_BSTR, dst_type, 0, dst_len, &b, dst, dst_max_len, src_status, dst_status, precision, scale, flags); SysFreeString(b); return hr; } if(src_type == DBTYPE_WSTR) { BSTR b; if(flags & DBDATACONVERT_LENGTHFROMNTS) b = SysAllocString(src); else b = SysAllocStringLen(src, src_len / 2); if(!b) return E_OUTOFMEMORY; hr = IDataConvert_DataConvert(iface, DBTYPE_BSTR, dst_type, 0, dst_len, &b, dst, dst_max_len, src_status, dst_status, precision, scale, flags); SysFreeString(b); return hr; } switch(dst_type) { case DBTYPE_I2: { signed short *d = dst; VARIANT tmp; switch(src_type) { case DBTYPE_EMPTY: *d = 0; hr = S_OK; break; case DBTYPE_I2: *d = *(signed short*)src; hr = S_OK; break; case DBTYPE_I4: hr = VarI2FromI4(*(signed int*)src, d); break; case DBTYPE_R4: hr = VarI2FromR4(*(FLOAT*)src, d); break; case DBTYPE_R8: hr = VarI2FromR8(*(double*)src, d); break; case DBTYPE_CY: hr = VarI2FromCy(*(CY*)src, d); break; case DBTYPE_DATE: hr = VarI2FromDate(*(DATE*)src, d); break; case DBTYPE_BSTR: hr = VarI2FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: hr = VarI2FromBool(*(VARIANT_BOOL*)src, d); break; case DBTYPE_DECIMAL: hr = VarI2FromDec((DECIMAL*)src, d); break; case DBTYPE_I1: hr = VarI2FromI1(*(signed char*)src, d); break; case DBTYPE_UI1: hr = VarI2FromUI1(*(BYTE*)src, d); break; case DBTYPE_UI2: hr = VarI2FromUI2(*(WORD*)src, d); break; case DBTYPE_UI4: hr = VarI2FromUI4(*(DWORD*)src, d); break; case DBTYPE_I8: hr = VarI2FromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI8: hr = VarI2FromUI8(*(ULONGLONG*)src, d); break; case DBTYPE_VARIANT: VariantInit(&tmp); if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_I2)) == S_OK) *d = V_I2(&tmp); break; default: FIXME("Unimplemented conversion %04x -> I2\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_I4: { signed int *d = dst; VARIANT tmp; switch(src_type) { case DBTYPE_EMPTY: *d = 0; hr = S_OK; break; case DBTYPE_I2: hr = VarI4FromI2(*(signed short*)src, d); break; case DBTYPE_I4: *d = *(signed int*)src; hr = S_OK; break; case DBTYPE_R4: hr = VarI4FromR4(*(FLOAT*)src, d); break; case DBTYPE_R8: hr = VarI4FromR8(*(double*)src, d); break; case DBTYPE_CY: hr = VarI4FromCy(*(CY*)src, d); break; case DBTYPE_DATE: hr = VarI4FromDate(*(DATE*)src, d); break; case DBTYPE_BSTR: hr = VarI4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: hr = VarI4FromBool(*(VARIANT_BOOL*)src, d); break; case DBTYPE_DECIMAL: hr = VarI4FromDec((DECIMAL*)src, d); break; case DBTYPE_I1: hr = VarI4FromI1(*(signed char*)src, d); break; case DBTYPE_UI1: hr = VarI4FromUI1(*(BYTE*)src, d); break; case DBTYPE_UI2: hr = VarI4FromUI2(*(WORD*)src, d); break; case DBTYPE_UI4: hr = VarI4FromUI4(*(DWORD*)src, d); break; case DBTYPE_I8: hr = VarI4FromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI8: hr = VarI4FromUI8(*(ULONGLONG*)src, d); break; case DBTYPE_VARIANT: VariantInit(&tmp); if ((hr = VariantChangeType(&tmp, (VARIANT*)src, 0, VT_I4)) == S_OK) *d = V_I4(&tmp); break; default: FIXME("Unimplemented conversion %04x -> I4\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_R4: { FLOAT *d = dst; switch(src_type) { case DBTYPE_EMPTY: *d = 0; hr = S_OK; break; case DBTYPE_I2: hr = VarR4FromI2(*(signed short*)src, d); break; case DBTYPE_I4: hr = VarR4FromI4(*(signed int*)src, d); break; case DBTYPE_R4: *d = *(FLOAT*)src; hr = S_OK; break; case DBTYPE_R8: hr = VarR4FromR8(*(double*)src, d); break; case DBTYPE_CY: hr = VarR4FromCy(*(CY*)src, d); break; case DBTYPE_DATE: hr = VarR4FromDate(*(DATE*)src, d); break; case DBTYPE_BSTR: hr = VarR4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: hr = VarR4FromBool(*(VARIANT_BOOL*)src, d); break; case DBTYPE_DECIMAL: hr = VarR4FromDec((DECIMAL*)src, d); break; case DBTYPE_I1: hr = VarR4FromI1(*(signed char*)src, d); break; case DBTYPE_UI1: hr = VarR4FromUI1(*(BYTE*)src, d); break; case DBTYPE_UI2: hr = VarR4FromUI2(*(WORD*)src, d); break; case DBTYPE_UI4: hr = VarR4FromUI4(*(DWORD*)src, d); break; case DBTYPE_I8: hr = VarR4FromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI8: hr = VarR4FromUI8(*(ULONGLONG*)src, d); break; default: FIXME("Unimplemented conversion %04x -> R4\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_R8: { DOUBLE *d=dst; switch (src_type) { case DBTYPE_EMPTY: *d = 0; hr = S_OK; break; case DBTYPE_I1: hr = VarR8FromI1(*(signed char*)src, d); break; case DBTYPE_I2: hr = VarR8FromI2(*(signed short*)src, d); break; case DBTYPE_I4: hr = VarR8FromI4(*(signed int*)src, d); break; case DBTYPE_I8: hr = VarR8FromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI1: hr = VarR8FromUI1(*(BYTE*)src, d); break; case DBTYPE_UI2: hr = VarR8FromUI2(*(WORD*)src, d); break; case DBTYPE_UI4: hr = VarR8FromUI4(*(DWORD*)src, d); break; case DBTYPE_UI8: hr = VarR8FromUI8(*(ULONGLONG*)src, d); break; case DBTYPE_R4: hr = VarR8FromR4(*(FLOAT*)src, d); break; case DBTYPE_R8: *d = *(DOUBLE*)src; hr = S_OK; break; case DBTYPE_CY: hr = VarR8FromCy(*(CY*)src, d); break; case DBTYPE_DATE: hr = VarR8FromDate(*(DATE*)src, d); break; case DBTYPE_BSTR: hr = VarR8FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: hr = VarR8FromBool(*(VARIANT_BOOL*)src, d); break; case DBTYPE_DECIMAL: hr = VarR8FromDec((DECIMAL*)src, d); break; default: FIXME("Unimplemented conversion %04x -> R8\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_BOOL: { VARIANT_BOOL *d=dst; switch (src_type) { case DBTYPE_EMPTY: *d = 0; hr = S_OK; break; case DBTYPE_I1: hr = VarBoolFromI1(*(signed char*)src, d); break; case DBTYPE_I2: hr = VarBoolFromI2(*(signed short*)src, d); break; case DBTYPE_I4: hr = VarBoolFromI4(*(signed int*)src, d); break; case DBTYPE_I8: hr = VarBoolFromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI1: hr = VarBoolFromUI1(*(BYTE*)src, d); break; case DBTYPE_UI2: hr = VarBoolFromUI2(*(WORD*)src, d); break; case DBTYPE_UI4: hr = VarBoolFromUI4(*(DWORD*)src, d); break; case DBTYPE_UI8: hr = VarBoolFromUI8(*(ULONGLONG*)src, d); break; case DBTYPE_R4: hr = VarBoolFromR4(*(FLOAT*)src, d); break; case DBTYPE_R8: hr = VarBoolFromR8(*(DOUBLE*)src, d); break; case DBTYPE_CY: hr = VarBoolFromCy(*(CY*)src, d); break; case DBTYPE_DATE: hr = VarBoolFromDate(*(DATE*)src, d); break; case DBTYPE_BSTR: hr = VarBoolFromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: *d = *(VARIANT_BOOL*)src; hr = S_OK; break; case DBTYPE_DECIMAL: hr = VarBoolFromDec((DECIMAL*)src, d); break; default: FIXME("Unimplemented conversion %04x -> BOOL\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_DATE: { DATE *d=dst; switch (src_type) { case DBTYPE_EMPTY: *d = 0; hr = S_OK; break; case DBTYPE_I1: hr = VarDateFromI1(*(signed char*)src, d); break; case DBTYPE_I2: hr = VarDateFromI2(*(signed short*)src, d); break; case DBTYPE_I4: hr = VarDateFromI4(*(signed int*)src, d); break; case DBTYPE_I8: hr = VarDateFromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI1: hr = VarDateFromUI1(*(BYTE*)src, d); break; case DBTYPE_UI2: hr = VarDateFromUI2(*(WORD*)src, d); break; case DBTYPE_UI4: hr = VarDateFromUI4(*(DWORD*)src, d); break; case DBTYPE_UI8: hr = VarDateFromUI8(*(ULONGLONG*)src, d); break; case DBTYPE_R4: hr = VarDateFromR4(*(FLOAT*)src, d); break; case DBTYPE_R8: hr = VarDateFromR8(*(DOUBLE*)src, d); break; case DBTYPE_CY: hr = VarDateFromCy(*(CY*)src, d); break; case DBTYPE_DATE: *d = *(DATE*)src; hr = S_OK; break; case DBTYPE_BSTR: hr = VarDateFromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: hr = VarDateFromBool(*(VARIANT_BOOL*)src, d); break; case DBTYPE_DECIMAL: hr = VarDateFromDec((DECIMAL*)src, d); break; case DBTYPE_DBTIMESTAMP: { SYSTEMTIME st; DBTIMESTAMP *ts=(DBTIMESTAMP*)src; st.wYear = ts->year; st.wMonth = ts->month; st.wDay = ts->day; st.wHour = ts->hour; st.wMinute = ts->minute; st.wSecond = ts->second; st.wMilliseconds = ts->fraction/1000000; hr = (SystemTimeToVariantTime(&st, d) ? S_OK : E_FAIL); break; } default: FIXME("Unimplemented conversion %04x -> DATE\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_DBTIMESTAMP: { DBTIMESTAMP *d=dst; switch (src_type) { case DBTYPE_EMPTY: memset(d, 0, sizeof(DBTIMESTAMP)); hr = S_OK; break; case DBTYPE_DBTIMESTAMP: memcpy(d, src, sizeof(DBTIMESTAMP)); hr = S_OK; break; case DBTYPE_DATE: { SYSTEMTIME st; hr = (VariantTimeToSystemTime(*(double*)src, &st) ? S_OK : E_FAIL); d->year = st.wYear; d->month = st.wMonth; d->day = st.wDay; d->hour = st.wHour; d->minute = st.wMinute; d->second = st.wSecond; d->fraction = st.wMilliseconds * 1000000; break; } default: FIXME("Unimplemented conversion %04x -> DBTIMESTAMP\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_CY: { CY *d = dst; switch(src_type) { case DBTYPE_EMPTY: d->int64 = 0; hr = S_OK; break; case DBTYPE_I2: hr = VarCyFromI2(*(signed short*)src, d); break; case DBTYPE_I4: hr = VarCyFromI4(*(signed int*)src, d); break; case DBTYPE_R4: hr = VarCyFromR4(*(FLOAT*)src, d); break; case DBTYPE_R8: hr = VarCyFromR8(*(double*)src, d); break; case DBTYPE_CY: *d = *(CY*)src; hr = S_OK; break; case DBTYPE_DATE: hr = VarCyFromDate(*(DATE*)src, d); break; case DBTYPE_BSTR: hr = VarCyFromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: hr = VarCyFromBool(*(VARIANT_BOOL*)src, d); break; case DBTYPE_DECIMAL: hr = VarCyFromDec((DECIMAL*)src, d); break; case DBTYPE_I1: hr = VarCyFromI1(*(signed char*)src, d); break; case DBTYPE_UI1: hr = VarCyFromUI1(*(BYTE*)src, d); break; case DBTYPE_UI2: hr = VarCyFromUI2(*(WORD*)src, d); break; case DBTYPE_UI4: hr = VarCyFromUI4(*(DWORD*)src, d); break; case DBTYPE_I8: hr = VarCyFromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI8: hr = VarCyFromUI8(*(ULONGLONG*)src, d); break; default: FIXME("Unimplemented conversion %04x -> CY\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_BSTR: { BSTR *d = dst; switch(src_type) { case DBTYPE_EMPTY: *d = SysAllocStringLen(NULL, 0); hr = *d ? S_OK : E_OUTOFMEMORY; break; case DBTYPE_I2: hr = VarBstrFromI2(*(signed short*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_I4: hr = VarBstrFromI4(*(signed int*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_R4: hr = VarBstrFromR4(*(FLOAT*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_R8: hr = VarBstrFromR8(*(double*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_CY: hr = VarBstrFromCy(*(CY*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_DATE: hr = VarBstrFromDate(*(DATE*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BSTR: *d = SysAllocStringLen(*(BSTR*)src, SysStringLen(*(BSTR*)src)); hr = *d ? S_OK : E_OUTOFMEMORY; break; case DBTYPE_BOOL: hr = VarBstrFromBool(*(VARIANT_BOOL*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_DECIMAL: hr = VarBstrFromDec((DECIMAL*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_I1: hr = VarBstrFromI1(*(signed char*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_UI1: hr = VarBstrFromUI1(*(BYTE*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_UI2: hr = VarBstrFromUI2(*(WORD*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_UI4: hr = VarBstrFromUI4(*(DWORD*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_I8: hr = VarBstrFromI8(*(LONGLONG*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_UI8: hr = VarBstrFromUI8(*(ULONGLONG*)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_GUID: { WCHAR szBuff[39]; const GUID *id = (const GUID *)src; WCHAR format[] = { '{','%','0','8','X','-','%','0','4','X','-','%','0','4','X','-', '%','0','2','X','%','0','2','X','-', '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X','}',0}; wsprintfW(szBuff, format, id->Data1, id->Data2, id->Data3, id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3], id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7] ); *d = SysAllocString(szBuff); hr = *d ? S_OK : E_OUTOFMEMORY; } break; case DBTYPE_BYTES: { *d = SysAllocStringLen(NULL, 2 * src_len); if (*d == NULL) hr = E_OUTOFMEMORY; else { const char hexchars[] = "0123456789ABCDEF"; WCHAR *s = *d; unsigned char *p = src; while (src_len > 0) { *s++ = hexchars[(*p >> 4) & 0x0F]; *s++ = hexchars[(*p) & 0x0F]; src_len--; p++; } hr = S_OK; } } break; default: FIXME("Unimplemented conversion %04x -> BSTR\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_UI1: { BYTE *d = dst; switch(src_type) { case DBTYPE_EMPTY: *d = 0; hr = S_OK; break; case DBTYPE_I2: hr = VarUI1FromI2(*(signed short*)src, d); break; case DBTYPE_I4: hr = VarUI1FromI4(*(signed int*)src, d); break; case DBTYPE_R4: hr = VarUI1FromR4(*(FLOAT*)src, d); break; case DBTYPE_R8: hr = VarUI1FromR8(*(double*)src, d); break; case DBTYPE_CY: hr = VarUI1FromCy(*(CY*)src, d); break; case DBTYPE_DATE: hr = VarUI1FromDate(*(DATE*)src, d); break; case DBTYPE_BSTR: hr = VarUI1FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: hr = VarUI1FromBool(*(VARIANT_BOOL*)src, d); break; case DBTYPE_DECIMAL: hr = VarUI1FromDec((DECIMAL*)src, d); break; case DBTYPE_I1: hr = VarUI1FromI1(*(signed char*)src, d); break; case DBTYPE_UI1: *d = *(BYTE*)src; hr = S_OK; break; case DBTYPE_UI2: hr = VarUI1FromUI2(*(WORD*)src, d); break; case DBTYPE_UI4: hr = VarUI1FromUI4(*(DWORD*)src, d); break; case DBTYPE_I8: hr = VarUI1FromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI8: hr = VarUI1FromUI8(*(ULONGLONG*)src, d); break; default: FIXME("Unimplemented conversion %04x -> UI1\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_UI2: { WORD *d = dst; switch(src_type) { case DBTYPE_EMPTY: *d = 0; hr = S_OK; break; case DBTYPE_I2: hr = VarUI2FromI2(*(signed short*)src, d); break; case DBTYPE_I4: hr = VarUI2FromI4(*(signed int*)src, d); break; case DBTYPE_R4: hr = VarUI2FromR4(*(FLOAT*)src, d); break; case DBTYPE_R8: hr = VarUI2FromR8(*(double*)src, d); break; case DBTYPE_CY: hr = VarUI2FromCy(*(CY*)src, d); break; case DBTYPE_DATE: hr = VarUI2FromDate(*(DATE*)src, d); break; case DBTYPE_BSTR: hr = VarUI2FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: hr = VarUI2FromBool(*(VARIANT_BOOL*)src, d); break; case DBTYPE_DECIMAL: hr = VarUI2FromDec((DECIMAL*)src, d); break; case DBTYPE_I1: hr = VarUI2FromI1(*(signed char*)src, d); break; case DBTYPE_UI1: hr = VarUI2FromUI1(*(BYTE*)src, d); break; case DBTYPE_UI2: *d = *(WORD*)src; hr = S_OK; break; case DBTYPE_UI4: hr = VarUI2FromUI4(*(DWORD*)src, d); break; case DBTYPE_I8: hr = VarUI2FromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI8: hr = VarUI2FromUI8(*(ULONGLONG*)src, d); break; default: FIXME("Unimplemented conversion %04x -> UI2\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_UI4: { DWORD *d = dst; switch(src_type) { case DBTYPE_EMPTY: *d = 0; hr = S_OK; break; case DBTYPE_I2: hr = VarUI4FromI2(*(signed short*)src, d); break; case DBTYPE_I4: hr = VarUI4FromI4(*(signed int*)src, d); break; case DBTYPE_R4: hr = VarUI4FromR4(*(FLOAT*)src, d); break; case DBTYPE_R8: hr = VarUI4FromR8(*(double*)src, d); break; case DBTYPE_CY: hr = VarUI4FromCy(*(CY*)src, d); break; case DBTYPE_DATE: hr = VarUI4FromDate(*(DATE*)src, d); break; case DBTYPE_BSTR: hr = VarUI4FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: hr = VarUI4FromBool(*(VARIANT_BOOL*)src, d); break; case DBTYPE_DECIMAL: hr = VarUI4FromDec((DECIMAL*)src, d); break; case DBTYPE_I1: hr = VarUI4FromI1(*(signed char*)src, d); break; case DBTYPE_UI1: hr = VarUI4FromUI1(*(BYTE*)src, d); break; case DBTYPE_UI2: hr = VarUI4FromUI2(*(WORD*)src, d); break; case DBTYPE_UI4: *d = *(DWORD*)src; hr = S_OK; break; case DBTYPE_I8: hr = VarUI4FromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI8: hr = VarUI4FromUI8(*(ULONGLONG*)src, d); break; default: FIXME("Unimplemented conversion %04x -> UI4\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_UI8: { ULONGLONG *d = dst; switch(src_type) { case DBTYPE_EMPTY: *d = 0; hr = S_OK; break; case DBTYPE_I2: hr = VarUI8FromI2(*(signed short*)src, d); break; case DBTYPE_I4: {LONGLONG s = *(signed int*)src; hr = VarUI8FromI8(s, d); break;} case DBTYPE_R4: hr = VarUI8FromR4(*(FLOAT*)src, d); break; case DBTYPE_R8: hr = VarUI8FromR8(*(double*)src, d); break; case DBTYPE_CY: hr = VarUI8FromCy(*(CY*)src, d); break; case DBTYPE_DATE: hr = VarUI8FromDate(*(DATE*)src, d); break; case DBTYPE_BSTR: hr = VarUI8FromStr(*(WCHAR**)src, LOCALE_USER_DEFAULT, 0, d); break; case DBTYPE_BOOL: hr = VarUI8FromBool(*(VARIANT_BOOL*)src, d); break; case DBTYPE_DECIMAL: hr = VarUI8FromDec((DECIMAL*)src, d); break; case DBTYPE_I1: hr = VarUI8FromI1(*(signed char*)src, d); break; case DBTYPE_UI1: hr = VarUI8FromUI1(*(BYTE*)src, d); break; case DBTYPE_UI2: hr = VarUI8FromUI2(*(WORD*)src, d); break; case DBTYPE_UI4: hr = VarUI8FromUI4(*(DWORD*)src, d); break; case DBTYPE_I8: hr = VarUI8FromI8(*(LONGLONG*)src, d); break; case DBTYPE_UI8: *d = *(ULONGLONG*)src; hr = S_OK; break; default: FIXME("Unimplemented conversion %04x -> UI8\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_FILETIME: { FILETIME *d = dst; switch(src_type) { case DBTYPE_EMPTY: d->dwLowDateTime = d->dwHighDateTime = 0; hr = S_OK; break; case DBTYPE_FILETIME: *d = *(FILETIME*)src; hr = S_OK; break; default: FIXME("Unimplemented conversion %04x -> FILETIME\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_GUID: { GUID *d = dst; switch(src_type) { case DBTYPE_EMPTY: *d = GUID_NULL; hr = S_OK; break; case DBTYPE_GUID: *d = *(GUID*)src; hr = S_OK; break; default: FIXME("Unimplemented conversion %04x -> GUID\n", src_type); return E_NOTIMPL; } break; } case DBTYPE_WSTR: { BSTR b; DBLENGTH bstr_len; INT bytes_to_copy; hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len, src, &b, sizeof(BSTR), src_status, dst_status, precision, scale, flags); if(hr != S_OK) return hr; bstr_len = SysStringLen(b); *dst_len = bstr_len * sizeof(WCHAR); /* Doesn't include size for '\0' */ *dst_status = DBSTATUS_S_OK; bytes_to_copy = min(*dst_len + sizeof(WCHAR), dst_max_len); if(dst) { if(bytes_to_copy >= sizeof(WCHAR)) { memcpy(dst, b, bytes_to_copy - sizeof(WCHAR)); *((WCHAR*)dst + bytes_to_copy / sizeof(WCHAR) - 1) = 0; if(bytes_to_copy < *dst_len + sizeof(WCHAR)) *dst_status = DBSTATUS_S_TRUNCATED; } else { *dst_status = DBSTATUS_E_DATAOVERFLOW; hr = DB_E_ERRORSOCCURRED; } } SysFreeString(b); return hr; } case DBTYPE_STR: { BSTR b; DBLENGTH bstr_len; INT bytes_to_copy; hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len, src, &b, sizeof(BSTR), src_status, dst_status, precision, scale, flags); if(hr != S_OK) return hr; bstr_len = SysStringLen(b); *dst_len = bstr_len * sizeof(char); /* Doesn't include size for '\0' */ *dst_status = DBSTATUS_S_OK; bytes_to_copy = min(*dst_len + sizeof(char), dst_max_len); if(dst) { if(bytes_to_copy >= sizeof(char)) { WideCharToMultiByte(CP_ACP, 0, b, bytes_to_copy - sizeof(char), dst, dst_max_len, NULL, NULL); *((char *)dst + bytes_to_copy / sizeof(char) - 1) = 0; if(bytes_to_copy < *dst_len + sizeof(char)) *dst_status = DBSTATUS_S_TRUNCATED; } else { *dst_status = DBSTATUS_E_DATAOVERFLOW; hr = DB_E_ERRORSOCCURRED; } } SysFreeString(b); return hr; } case DBTYPE_BYREF | DBTYPE_WSTR: { BSTR b; WCHAR **d = dst; DBLENGTH bstr_len; hr = IDataConvert_DataConvert(iface, src_type, DBTYPE_BSTR, src_len, &bstr_len, src, &b, sizeof(BSTR), src_status, dst_status, precision, scale, flags); if(hr != S_OK) return hr; bstr_len = SysStringLen(b) * sizeof(WCHAR); *dst_len = bstr_len; /* Doesn't include size for '\0' */ *d = CoTaskMemAlloc(bstr_len + sizeof(WCHAR)); if(*d) memcpy(*d, b, bstr_len + sizeof(WCHAR)); else hr = E_OUTOFMEMORY; SysFreeString(b); return hr; } default: FIXME("Unimplemented conversion %04x -> %04x\n", src_type, dst_type); return E_NOTIMPL; } if(hr == DISP_E_OVERFLOW) { *dst_status = DBSTATUS_E_DATAOVERFLOW; *dst_len = get_length(dst_type); hr = DB_E_ERRORSOCCURRED; } else if(hr == S_OK) { *dst_status = DBSTATUS_S_OK; *dst_len = get_length(dst_type); } return hr; }