int _UPNP_SERVER_AddNotifyInfo(UPNP_SSDP_HANDLE_ITEM* handle, const char* uuid, const char* urn, int locationPort, const char* locationUri ) { int ret = 0; UPNP_SSDP_NOTIFY_DEVICE_INFO* devInfo = NULL; char* urnFind = NULL; devInfo = (UPNP_SSDP_NOTIFY_DEVICE_INFO*)SORT_LIST_FindItem(handle->notifyDeviceList, (void*)uuid); if( devInfo != NULL ){ urnFind = (char*)SORT_LIST_FindItem(devInfo->urnList, (void*)urn); if( urnFind != NULL ){ //登録済み return 2; }else{ urnFind = (char*)malloc(strlen(urn)+1); #ifdef _WIN32 strcpy_s(urnFind, strlen(urn)+1, urn); #else strcpy(urnFind, urn); #endif SORT_LIST_AddItem(devInfo->urnList, urnFind, urnFind); } }else{ //新規登録 devInfo = UPNP_SSDP_NOTIFY_DEVICE_INFO_New(); devInfo->uuid = (char*)malloc(strlen(uuid)+1); devInfo->locationUri = (char*)malloc(strlen(locationUri)+1); devInfo->locationPort = locationPort; urnFind = (char*)malloc(strlen(urn)+1); #ifdef _WIN32 strcpy_s(devInfo->uuid, strlen(uuid)+1, uuid); strcpy_s(devInfo->locationUri, strlen(locationUri)+1, locationUri); strcpy_s(urnFind, strlen(urn)+1, urn); #else strcpy(devInfo->uuid, uuid); strcpy(devInfo->locationUri, locationUri); strcpy(urnFind, urn); #endif SORT_LIST_AddItem(devInfo->urnList, urnFind, urnFind); SORT_LIST_AddItem(handle->notifyDeviceList, devInfo->uuid, devInfo); } UPNP_SERVER_SendNotifyAlive(handle, devInfo); ret = 1; return ret; }
int MP_HTTP_RequestHeaderParse(char* src, HTTP_REQUEST_HEADER* header) { char* leftBuff = NULL; char* rightBuff = NULL; char* tempBuff = NULL; int srcLength = 0; HTTP_HEADER_FIELD_INFO* headerItem = NULL; if( src == NULL || header == NULL ){ return -1; } srcLength = (int)strlen(src); leftBuff = (char*)malloc(srcLength+1); rightBuff = (char*)malloc(srcLength+1); tempBuff = (char*)malloc(srcLength+1); if( leftBuff == NULL || rightBuff == NULL || tempBuff == NULL ){ return -1; } #ifdef _WIN32 strcpy_s(rightBuff, srcLength+1, src); #else strcpy(rightBuff, src); #endif //Request-Line MP_STR_Separate(rightBuff, "\r\n", leftBuff, srcLength+1, rightBuff, srcLength+1); MP_STR_Separate(leftBuff, " ", tempBuff, srcLength+1, leftBuff, srcLength+1); header->method = (char*)malloc(strlen(tempBuff)+1); #ifdef _WIN32 strcpy_s(header->method, strlen(tempBuff)+1, tempBuff); #else strcpy(header->method, tempBuff); #endif MP_STR_Separate(leftBuff, " ", tempBuff, srcLength+1, leftBuff, srcLength+1); header->uri = (char*)malloc(strlen(tempBuff)+1); #ifdef _WIN32 strcpy_s(header->uri, strlen(tempBuff)+1, tempBuff); #else strcpy(header->uri, tempBuff); #endif header->version = (char*)malloc(strlen(leftBuff)+1); #ifdef _WIN32 strcpy_s(header->version, strlen(leftBuff)+1, leftBuff); #else strcpy(header->version, leftBuff); #endif //Header while(strlen(rightBuff) > 0 ){ MP_STR_Separate(rightBuff, "\r\n", leftBuff, srcLength+1, rightBuff, srcLength+1); if( strlen(leftBuff) > 0 ){ headerItem = HTTP_HEADER_FIELD_INFO_New(); MP_STR_Separate(leftBuff, ":", tempBuff, srcLength+1, leftBuff, srcLength+1); MP_STR_Trim(tempBuff); MP_STR_Trim(leftBuff); headerItem->name = (char*)malloc(strlen(tempBuff)+1); #ifdef _WIN32 strcpy_s(headerItem->name, strlen(tempBuff)+1, tempBuff); #else strcpy(headerItem->name, tempBuff); #endif headerItem->value = (char*)malloc(strlen(leftBuff)+1); #ifdef _WIN32 strcpy_s(headerItem->value, strlen(leftBuff)+1, leftBuff); #else strcpy(headerItem->value, leftBuff); #endif SORT_LIST_AddItem(header->headerList, headerItem->name, headerItem); } } free(leftBuff); free(rightBuff); free(tempBuff); return 0; }
int UPNP_SERVER_SendNotifyAlive(UPNP_SSDP_HANDLE_ITEM* handle, UPNP_SSDP_NOTIFY_DEVICE_INFO* devInfo) { int ret = 0; int urnCount = 0; char* urn = NULL; int i=0; int j=0; char sendMsg[2048] = ""; SORT_LIST_HANDLE nicList = NULL; int nicCount = 0; MP_NIC_INFO* nicInfo = NULL; SOCKET sock; struct sockaddr_in addr; struct sockaddr_in send_addr; int opt = 1; unsigned long ipAdrr = 0; int ttl = 3; char sendMsgFormat[] = "NOTIFY * HTTP/1.1\r\nHOST: 239.255.255.250:1900\r\nCACHE-CONTROL: max-age = 1800\r\nLOCATION: http://%s:%d%s\r\nNT: %s\r\nNTS: ssdp:alive\r\nSERVER: %s\r\nUSN: %s\r\n\r\n"; char nt[512] = ""; char usn[512] = ""; char ua[128] = ""; if( handle == NULL || devInfo == NULL){ ret = -1; goto Err_End; } nicList = MP_NIC_GetNICInfo(); if( nicList == NULL ){ ret = -3; goto Err_End; } UPNP_UTIL_GetUserAgent(ua, sizeof(ua)); nicInfo = MP_NIC_INFO_New(); nicInfo->ipv4 = (char*)malloc(strlen("127.0.0.1")+1); nicInfo->name = (char*)malloc(strlen("Loop Back")+1); nicInfo->macAddress = (char*)malloc(strlen("00-00-00-00-00-00")+1); #ifdef _WIN32 strcpy_s(nicInfo->ipv4 , strlen("127.0.0.1")+1, "127.0.0.1"); strcpy_s(nicInfo->name , strlen("Loop Back")+1, "Loop Back"); strcpy_s(nicInfo->macAddress, strlen("00-00-00-00-00-00")+1, "00-00-00-00-00-00"); #else strcpy(nicInfo->ipv4 , "127.0.0.1"); strcpy(nicInfo->name , "Loop Back"); strcpy(nicInfo->macAddress , "00-00-00-00-00-00"); #endif memset(nicInfo->macAddressValue, 0, 6); SORT_LIST_AddItem(nicList, nicInfo->name, nicInfo); nicCount = SORT_LIST_GetCount(nicList); if( nicCount <= 0 ){ ret = -4; goto Err_End; } memset((char*)&send_addr, 0, sizeof(struct sockaddr_in)); send_addr.sin_family = AF_INET; send_addr.sin_addr.s_addr = inet_addr("239.255.255.250"); send_addr.sin_port = htons(1900); //見つかったNIC全てで送信 for( i=0; i<nicCount; i++ ){ nicInfo = (MP_NIC_INFO*)SORT_LIST_GetItemByIndex(nicList, i); ipAdrr = inet_addr(nicInfo->ipv4); memset((char*)&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_port = 0; addr.sin_addr.S_un.S_addr = ipAdrr; sock = socket(AF_INET, SOCK_DGRAM, 0); if( sock < 0 ){ continue; } if( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) < 0 ){ closesocket(sock); continue; } if(setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&ipAdrr, sizeof(ipAdrr)) < 0){ closesocket(sock); continue; } if(setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl)) < 0){ closesocket(sock); continue; } //upnp:rootdevice memset(sendMsg, 0, 2048); #ifdef _WIN32 sprintf_s(usn, sizeof(usn), "uuid:%s::upnp:rootdevice", devInfo->uuid); sprintf_s(sendMsg, sizeof(sendMsg), sendMsgFormat, nicInfo->ipv4, devInfo->locationPort, devInfo->locationUri, "upnp:rootdevice", ua, usn ); #else sprintf(usn, "uuid:%s::upnp:rootdevice", devInfo->uuid); sprintf(sendMsg, sendMsgFormat, nicInfo->ipv4, devInfo->locationPort, devInfo->locationUri, "upnp:rootdevice", ua, usn ); #endif if( sendto(sock, sendMsg, (int)strlen(sendMsg), 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0 ){ closesocket(sock); continue; } //uuid:device-UUID memset(sendMsg, 0, 2048); #ifdef _WIN32 sprintf_s(nt, sizeof(usn), "uuid:%s", devInfo->uuid); sprintf_s(usn, sizeof(usn), "uuid:%s", devInfo->uuid); sprintf_s(sendMsg, sizeof(sendMsg), sendMsgFormat, nicInfo->ipv4, devInfo->locationPort, devInfo->locationUri, nt, ua, usn ); #else sprintf(nt, "uuid:%s", devInfo->uuid); sprintf(usn, "uuid:%s", devInfo->uuid); sprintf(sendMsg, sendMsgFormat, nicInfo->ipv4, devInfo->locationPort, devInfo->locationUri, nt, ua, usn ); #endif if( sendto(sock, sendMsg, (int)strlen(sendMsg), 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0 ){ closesocket(sock); continue; } //urn:schemas-upnp-org:device:deviceType:ver //urn:schemas-upnp-org:service:serviceType:ver urnCount = SORT_LIST_GetCount(devInfo->urnList); for( j=0; j<urnCount; j++ ){ urn = (char*)SORT_LIST_GetItemByIndex(devInfo->urnList, j); memset(sendMsg, 0, 2048); #ifdef _WIN32 sprintf_s(nt, sizeof(usn), "%s", urn); sprintf_s(usn, sizeof(usn), "uuid:%s::%s", devInfo->uuid, urn); sprintf_s(sendMsg, sizeof(sendMsg), sendMsgFormat, nicInfo->ipv4, devInfo->locationPort, devInfo->locationUri, nt, ua, usn ); #else sprintf(nt, "%s", urn); sprintf(usn, "uuid:%s::%s", devInfo->uuid, urn); sprintf(sendMsg, sendMsgFormat, nicInfo->ipv4, devInfo->locationPort, devInfo->locationUri, nt, ua, usn ); #endif if( sendto(sock, sendMsg, (int)strlen(sendMsg), 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0 ){ break; } } closesocket(sock); } Err_End: if( nicList != NULL){ SORT_LIST_CloseHandle(&nicList); } return ret; }
//Linux系 void* UPNP_SERVER_SSDPThread(void* param) #endif { UPNP_SSDP_HANDLE_ITEM* handle = NULL; fd_set ready; struct timeval to; SOCKET sockClient = -1; UPNP_SSDP_SOCKET_ITEM* sockItem = NULL; UPNP_SSDP_RECV_PARAM* recvParam = NULL; int recv_len = 0; int threadCount = 0; int i=0; int j=0; int ssdpSockMax = 0; handle = (UPNP_SSDP_HANDLE_ITEM*)param; if( handle == NULL ){ return -1; } while(1){ if( handle->ssdpSrvStopFlag == 1 ){ break; } to.tv_sec = 1; to.tv_usec = 0; FD_ZERO(&ready); ssdpSockMax = 0; for( i=0; i<SORT_LIST_GetCount(handle->ssdpSockList); i++ ){ sockItem = (UPNP_SSDP_SOCKET_ITEM*)SORT_LIST_GetItemByIndex(handle->ssdpSockList, i); FD_SET(sockItem->ssdpSock, &ready); #ifdef _WIN32 #else if( ssdpSockMax < sockItem->ssdpSock){ ssdpSockMax = sockItem->ssdpSock; } #endif } #ifdef _WIN32 if( select(0, &ready, NULL, NULL, &to ) == SOCKET_ERROR ){ #else if( select(ssdpSockMax+1, &ready, NULL, NULL, &to ) == SOCKET_ERROR ){ #endif break; } for( i=0; i<SORT_LIST_GetCount(handle->ssdpSockList); i++ ){ sockItem = (UPNP_SSDP_SOCKET_ITEM*)SORT_LIST_GetItemByIndex(handle->ssdpSockList, i); if ( FD_ISSET(sockItem->ssdpSock, &ready) ){ recvParam = UPNP_SSDP_RECV_PARAM_New(); if( recvParam == NULL ){ break; } recvParam->nicInfo = MP_NIC_INFO_Clone(sockItem->nicInfo); recv_len = recvfrom(sockItem->ssdpSock, recvParam->recvData, UPNP_SSDP_RECV_BUFF_SIZE-1, 0, (sockaddr*)&recvParam->client, &recvParam->addr_len); if( recv_len < 0 ){ UPNP_SSDP_RECV_PARAM_Delete(recvParam); break; }else if( recv_len == 0 ){ UPNP_SSDP_RECV_PARAM_Delete(recvParam); continue; }else{ #ifdef _WIN32 sprintf_s(recvParam->key, sizeof(recvParam->key), "%s:%u", inet_ntoa(recvParam->client.sin_addr), ntohs(recvParam->client.sin_port)); #else sprintf(recvParam->key, "%s:%u", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); #endif recvParam->ssdpHandle = handle; recvParam->threadHandle = MP_THREAD_BegineThread(UPNP_SERVER_SSDPRecvThread, recvParam); SORT_LIST_AddItem(handle->recvThreadList, (void*)recvParam->key, (void*)recvParam); } }else{ threadCount = SORT_LIST_GetCount(handle->recvThreadList); for( j=threadCount-1; j>=0; j-- ){ recvParam = (UPNP_SSDP_RECV_PARAM*)SORT_LIST_GetItemByIndex(handle->recvThreadList, j); if( recvParam->endFlag == 1 ){ MP_THREAD_WaitEndThread(&recvParam->threadHandle); SORT_LIST_DeleteItemByIndex(handle->recvThreadList, j); } } } } } SORT_LIST_Clear(handle->recvThreadList); return 0; } #ifdef _WIN32 unsigned int WINAPI UPNP_SERVER_SSDPRecvThread(void* param) #else //Linux系 void* UPNP_SERVER_SSDPRecvThread(void* param) #endif { HTTP_REQUEST_HEADER* httpReqHeader = NULL; UPNP_SSDP_RECV_PARAM* info = NULL; info = (UPNP_SSDP_RECV_PARAM*)param; if( info == NULL ){ return -1; } httpReqHeader = HTTP_REQUEST_HEADER_New(); #ifdef _WIN32 //OutputDebugStringA(info->recvData); #else printf(info->recvData); #endif if( MP_HTTP_RequestHeaderParse(info->recvData, httpReqHeader) < 0 ){ HTTP_REQUEST_HEADER_Delete(&httpReqHeader); return -1; } if( MP_STR_CompNoCase(httpReqHeader->method, "NOTIFY") == 0 ){ UPNP_SERVER_SSDPNotifyMsg((UPNP_SSDP_RECV_PARAM*)info, httpReqHeader, info->recvData); }else if( MP_STR_CompNoCase(httpReqHeader->method, "M-SEARCH") == 0 ){ UPNP_SERVER_SSDPMSearchMsg((UPNP_SSDP_RECV_PARAM*)info, httpReqHeader, info->recvData); }else{ goto END_THREAD; } END_THREAD: HTTP_REQUEST_HEADER_Delete(httpReqHeader); info->endFlag = 1; return 0; }
int _UPNP_SERVER_StartSSDP(UPNP_SSDP_HANDLE_ITEM* handle) { int ret = 0; struct sockaddr_in addr; struct ip_mreq_source mreq; int opt = 1; SORT_LIST_HANDLE nicList = NULL; int listCount = 0; MP_NIC_INFO* nicInfo = NULL; int success = 0; int i=0; UPNP_SSDP_SOCKET_ITEM* sockItem = NULL; if( handle == NULL ){ return -1; } if( handle->ssdpSrvThread != NULL ){ return -2; } nicList = MP_NIC_GetNICInfo(); if( nicList == NULL ){ ret = -3; goto Err_End; } nicInfo = MP_NIC_INFO_New(); nicInfo->ipv4 = (char*)malloc(strlen("127.0.0.1")+1); nicInfo->name = (char*)malloc(strlen("Loop Back")+1); nicInfo->macAddress = (char*)malloc(strlen("00-00-00-00-00-00")+1); #ifdef _WIN32 strcpy_s(nicInfo->ipv4 , strlen("127.0.0.1")+1, "127.0.0.1"); strcpy_s(nicInfo->name , strlen("Loop Back")+1, "Loop Back"); strcpy_s(nicInfo->macAddress, strlen("00-00-00-00-00-00")+1, "00-00-00-00-00-00"); #else strcpy(nicInfo->ipv4 , "127.0.0.1"); strcpy(nicInfo->name , "Loop Back"); strcpy(nicInfo->macAddress , "00-00-00-00-00-00"); #endif memset(nicInfo->macAddressValue, 0, 6); SORT_LIST_AddItem(nicList, nicInfo->name, nicInfo); listCount = SORT_LIST_GetCount(nicList); if( listCount <= 0 ){ ret = -4; goto Err_End; } //見つかったNIC全てで受信できるようにする for( i=0; i<listCount; i++ ){ nicInfo = (MP_NIC_INFO*)SORT_LIST_GetItemByIndex(nicList, i); sockItem = UPNP_SSDP_SOCKET_ITEM_New(); sockItem->nicInfo = MP_NIC_INFO_Clone(nicInfo); //SSDP待ち受けポート(UDP 1900)の作成 sockItem->ssdpSock = socket(AF_INET, SOCK_DGRAM, 0); if( sockItem->ssdpSock < 0 ){ ret = -5; UPNP_SSDP_SOCKET_ITEM_Delete(sockItem); goto Err_End; } memset((char*)&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(1900); if( setsockopt(sockItem->ssdpSock, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt)) < 0 ){ ret = -6; UPNP_SSDP_SOCKET_ITEM_Delete(sockItem); goto Err_End; } if( bind(sockItem->ssdpSock, (struct sockaddr *)&addr, sizeof(addr)) < 0 ){ ret = -7; UPNP_SSDP_SOCKET_ITEM_Delete(sockItem); goto Err_End; } memset(&mreq, 0, sizeof(mreq)); mreq.imr_interface.S_un.S_addr = INADDR_ANY; mreq.imr_sourceaddr.S_un.S_addr = inet_addr(nicInfo->ipv4); mreq.imr_multiaddr.S_un.S_addr = inet_addr("239.255.255.250"); if(setsockopt(sockItem->ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0){ UPNP_SSDP_SOCKET_ITEM_Delete(sockItem); }else{ SORT_LIST_AddItem(handle->ssdpSockList, sockItem->nicInfo->name, sockItem); } } if( SORT_LIST_GetCount(handle->ssdpSockList) <= 0 ){ ret = -8; goto Err_End; } handle->ssdpSrvStopFlag = 0; handle->ssdpSrvThread = MP_THREAD_BegineThread(UPNP_SERVER_SSDPThread, handle); if( nicList != NULL){ SORT_LIST_CloseHandle(&nicList); } return 0; Err_End: if( nicList != NULL){ SORT_LIST_CloseHandle(&nicList); } SORT_LIST_Clear(handle->ssdpSockList); return ret; }
int CDLNAManager::UpnpMSearchReqCallback( UPNP_MSEARCH_REQUEST_INFO* requestParam, void* param, SORT_LIST_HANDLE resDeviceList) { int ret = -1; CDLNAManager* sys = (CDLNAManager*)param; UPNP_MSEARCH_RES_DEV_INFO* resDevInfo = NULL; vector<string> urnList; string buff = ""; string uuid = ""; string server = "Windows/5.1 UPnP/1.1 EpgTimerSrv/1.0"; if(requestParam == NULL || sys == NULL ){ return ret; } if( CompareNoCase(requestParam->man, "\"ssdp:discover\"") != 0 ){ return ret; } if( CompareNoCase(requestParam->st, "upnp:rootdevice") == 0 || CompareNoCase(requestParam->st, "ssdp:all") == 0){ if( sys->startDMS == TRUE ){ sys->dms.GetDevicesType(&urnList); sys->dms.GetUuid(uuid); for( size_t i=0; i<urnList.size(); i++ ){ resDevInfo = UPNP_MSEARCH_RES_DEV_INFO_New(); resDevInfo->max_age = 1800; resDevInfo->port = sys->httpPort; sys->dms.GetDDDUri(uuid, buff); resDevInfo->uri = (char*)malloc(buff.size()+1); strcpy_s(resDevInfo->uri, buff.size()+1, buff.c_str()); resDevInfo->uuid = (char*)malloc(uuid.size()+1); strcpy_s(resDevInfo->uuid, uuid.size()+1, uuid.c_str()); resDevInfo->usn = (char*)malloc(strlen("uuid:::urn:rootdevice")+uuid.size()+1); sprintf_s(resDevInfo->usn, strlen("uuid:::urn:rootdevice")+uuid.size()+1, "uuid:%s::urn:rootdevice", uuid.c_str()); resDevInfo->server = (char*)malloc(server.size()+1); strcpy_s(resDevInfo->server, server.size()+1, server.c_str()); SORT_LIST_AddItem(resDeviceList, resDevInfo->uuid, resDevInfo); } } } string st = requestParam->st; if( st.find("uuid:") == 0 || CompareNoCase(requestParam->st, "ssdp:all") == 0){ if( sys->startDMS == TRUE ){ sys->dms.GetUuid(uuid); if( st.find(uuid) != string::npos ){ resDevInfo = UPNP_MSEARCH_RES_DEV_INFO_New(); resDevInfo->max_age = 1800; resDevInfo->port = sys->httpPort; sys->dms.GetDDDUri(uuid, buff); resDevInfo->uri = (char*)malloc(buff.size()+1); strcpy_s(resDevInfo->uri, buff.size()+1, buff.c_str()); resDevInfo->uuid = (char*)malloc(uuid.size()+1); strcpy_s(resDevInfo->uuid, uuid.size()+1, uuid.c_str()); resDevInfo->usn = (char*)malloc(strlen("uuid:")+uuid.size()+1); sprintf_s(resDevInfo->usn, strlen("uuid:")+uuid.size()+1, "uuid:%s", uuid.c_str()); resDevInfo->server = (char*)malloc(server.size()+1); strcpy_s(resDevInfo->server, server.size()+1, server.c_str()); SORT_LIST_AddItem(resDeviceList, resDevInfo->uuid, resDevInfo); } } } if(st.find("urn:") == 0 || CompareNoCase(requestParam->st, "ssdp:all") == 0){ if( sys->startDMS == TRUE ){ sys->dms.GetUuid(uuid); if( sys->dms.IsSupportUrn(st) >0){ resDevInfo = UPNP_MSEARCH_RES_DEV_INFO_New(); resDevInfo->max_age = 1800; resDevInfo->port = sys->httpPort; sys->dms.GetDDDUri(uuid, buff); resDevInfo->uri = (char*)malloc(buff.size()+1); strcpy_s(resDevInfo->uri, buff.size()+1, buff.c_str()); resDevInfo->uuid = (char*)malloc(uuid.size()+1); strcpy_s(resDevInfo->uuid, uuid.size()+1, uuid.c_str()); resDevInfo->usn = (char*)malloc(strlen("uuid:::")+uuid.size()+st.size()+1); sprintf_s(resDevInfo->usn, strlen("uuid:::")+uuid.size()+st.size()+1, "uuid:%s::%s", uuid.c_str(), st.c_str()); resDevInfo->server = (char*)malloc(server.size()+1); strcpy_s(resDevInfo->server, server.size()+1, server.c_str()); SORT_LIST_AddItem(resDeviceList, resDevInfo->uuid, resDevInfo); } } } return ret; }