2 * Copyright (c) 2012, 2013 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include <sys/types.h>
23 #include "mtp_support.h"
25 #include "mtp_device.h"
28 extern mtp_bool g_is_full_enum;
31 mtp_bool _entity_get_file_times(mtp_obj_t *obj, ptp_time_string_t *create_tm,
32 ptp_time_string_t *modify_tm)
34 file_attr_t attrs = {0};
35 system_time_t local_time = {0};
36 struct tm new_time = {0};
38 if (FALSE == _util_get_file_attrs(obj->file_path, &attrs)) {
39 ERR("_util_get_file_attrs Fail");
43 if (NULL != localtime_r((time_t*)&attrs.ctime, &new_time)) {
44 local_time.year = new_time.tm_year + 1900;
45 local_time.month = new_time.tm_mon + 1;
46 local_time.day = new_time.tm_mday;
47 local_time.hour = new_time.tm_hour;
48 local_time.minute = new_time.tm_min;
49 local_time.second = new_time.tm_sec;
50 local_time.day_of_week = 0;
51 local_time.millisecond = 0;
53 ERR("localtime_r returned NULL");
57 _prop_copy_time_to_ptptimestring(create_tm, &local_time);
59 if (NULL != localtime_r((time_t*)&attrs.mtime, &new_time)) {
60 local_time.year = new_time.tm_year + 1900;
61 local_time.month = new_time.tm_mon + 1;
62 local_time.day = new_time.tm_mday;
63 local_time.hour = new_time.tm_hour;
64 local_time.minute = new_time.tm_min;
65 local_time.second = new_time.tm_sec;
66 local_time.day_of_week = 0;
67 local_time.millisecond = 0;
69 ERR("localtime_r returned NULL");
73 _prop_copy_time_to_ptptimestring(modify_tm, &local_time);
78 obj_info_t *_entity_alloc_object_info(void)
80 obj_info_t *info = NULL;
82 info = (obj_info_t *)g_malloc(sizeof(obj_info_t));
84 ERR("Memory allocation Fail");
88 _entity_init_object_info(info);
93 void _entity_init_object_info(obj_info_t *info)
97 memset(info, 0, sizeof(obj_info_t));
100 mtp_uint32 _entity_get_object_info_size(mtp_obj_t *obj, ptp_string_t *file_name)
103 ptp_string_t keywords;
104 ptp_time_string_t create_time_str = {0};
105 ptp_time_string_t modify_time_str = {0};
106 mtp_uint32 size = FIXED_LENGTH_MEMBERS_SIZE;
108 retv_if(obj == NULL, 0);
110 ret = _entity_get_file_times(obj, &create_time_str, &modify_time_str);
112 ERR("_entity_get_file_times() Fail");
116 _prop_copy_char_to_ptpstring(&keywords, (mtp_wchar *)"", WCHAR_TYPE);
118 size += _prop_size_ptpstring(file_name);
119 size += _prop_size_ptptimestring(&create_time_str);
120 size += _prop_size_ptptimestring(&modify_time_str);
121 size += _prop_size_ptpstring(&keywords);
126 void _entity_init_object_info_params(obj_info_t *info, mtp_uint32 store_id,
127 mtp_uint32 parent_handle, mtp_char *file_name, dir_entry_t *dir)
129 mtp_char extn[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
131 _entity_init_object_info(info);
133 info->store_id = store_id;
134 info->h_parent = parent_handle;
136 _util_get_file_extn(file_name, extn);
138 if (dir->attrs.attribute == MTP_FILE_ATTR_INVALID) {
139 ERR("File attribute invalid");
142 #ifndef MTP_SUPPORT_SET_PROTECTION
143 info->protcn_status = PTP_PROTECTIONSTATUS_NOPROTECTION;
144 #else /* MTP_SUPPORT_SET_PROTECTION */
145 info->protcn_status = (dir->attrs.attribute &
146 MTP_FILE_ATTR_MODE_READ_ONLY) ?
147 PTP_PROTECTIONSTATUS_READONLY :
148 PTP_PROTECTIONSTATUS_NOPROTECTION;
149 #endif /* MTP_SUPPORT_SET_PROTECTION */
151 if (dir->attrs.attribute & MTP_FILE_ATTR_MODE_DIR) {
152 info->obj_fmt = PTP_FMT_ASSOCIATION;
153 info->association_type = PTP_ASSOCIATIONTYPE_FOLDER;
157 info->file_size = dir->attrs.fsize;
158 info->obj_fmt = _util_get_fmtcode(extn);
163 mtp_uint32 _entity_parse_raw_obj_info(mtp_uchar *buf, mtp_uint32 buf_sz,
164 obj_info_t *info, mtp_char *file_name, mtp_uint16 fname_len)
166 mtp_uchar *temp = buf;
167 ptp_string_t str = {0};
168 mtp_uint32 bytes_parsed = 0;
170 retv_if(buf == NULL, 0);
171 retvm_if(buf_sz < FIXED_LENGTH_MEMBERS_SIZE, 0, "buf_sz[%d] is less", buf_sz);
173 /* Copy Obj Props from store_id till file_size */
174 memcpy(&(info->store_id), temp, (sizeof(mtp_uint16) * 2 + sizeof(mtp_uint32) * 2));
175 temp += (sizeof(mtp_uint16) * 2 + sizeof(mtp_uint32) * 2);
177 /* Skip ObjProp:thumb format .No need to store ,the prop has
180 temp += sizeof(mtp_uint16);
182 memcpy(&(info->thumb_file_size), temp, sizeof(mtp_uint32));
183 temp += sizeof(mtp_uint32);
185 /* Skip ObjProps:ThumbPixWidth,ThumbPixHeight,ImagePixWidth,
186 * ImagePixHeight,ImageBitDepth.No need to store,they have default value
188 temp += sizeof(mtp_uint32) * 5;
190 memcpy(&(info->h_parent), temp, sizeof(mtp_uint32));
191 temp += sizeof(mtp_uint32);
193 memcpy(&(info->association_type), temp, sizeof(mtp_uint16));
194 temp += sizeof(mtp_uint16);
196 /* Skip ObjProps:association_desc, sequence_desc */
197 temp += sizeof(mtp_uint32) * 2;
199 #ifdef __BIG_ENDIAN__
200 /* Byte swap the structure elements if needed.
201 * This works since the data elements will have the same size,
202 * the only difference is the byte order.
204 _util_conv_byte_order(&(info->store_id), sizeof(info->store_id));
205 _util_conv_byte_order(&(info->obj_fmt), sizeof(info->obj_fmt));
206 _util_conv_byte_order(&(info->protcn_status),
207 sizeof(info->protcn_status));
208 _util_conv_byte_order(&(info->file_size), sizeof(info->file_size));
209 _util_conv_byte_order(&(info->thumb_file_size),
210 sizeof(info->thumb_file_size));
211 _util_conv_byte_order(&(info->h_parent), sizeof(info->h_parent));
212 _util_conv_byte_order(&(info->association_type),
213 sizeof(info->association_type));
214 #endif /*__BIG_ENDIAN__*/
216 ptp_string_t fname = { 0 };
217 bytes_parsed = _prop_parse_rawstring(&fname, temp, buf_sz);
218 temp += bytes_parsed;
220 _util_utf16_to_utf8(file_name, fname_len, fname.str);
222 /* Skip ObjProps: datecreated/datemodified/keywords.
223 * The values are retrieved using stat.
225 memcpy(&(str.num_chars), temp, sizeof(mtp_uchar));
226 temp += _prop_size_ptpstring(&str);
228 memcpy(&(str.num_chars), temp, sizeof(mtp_uchar));
229 temp += _prop_size_ptpstring(&str);
231 memcpy(&(str.num_chars), temp, sizeof(mtp_uchar));
232 temp += _prop_size_ptpstring(&str);
234 return (mtp_uint32)(temp - buf);
237 void _entity_copy_obj_info(obj_info_t *dst, obj_info_t *src)
239 memcpy(&(dst->store_id), &(src->store_id), (2 * sizeof(mtp_uint16) +
240 sizeof(mtp_uint32) + sizeof(mtp_uint64)));
242 /* Copy Object Props:thumb_file_size,h_parent, association_type */
243 memcpy(&(dst->thumb_file_size), &(src->thumb_file_size),
244 (2 * sizeof(mtp_uint32) + sizeof(mtp_uint16)));
249 mtp_uint32 _entity_pack_obj_info(mtp_obj_t *obj, ptp_string_t *file_name,
250 mtp_uchar *buf, mtp_uint32 buf_sz)
253 mtp_uint32 num_bytes = 0;
254 mtp_uint32 objSize = 0;
255 mtp_uint16 thumb_fmt = 0;
256 mtp_uint32 thumb_width = 0;
257 mtp_uint32 thumb_height = 0;
258 obj_info_t *info = obj->obj_info;
259 ptp_time_string_t create_time_str = { 0 };
260 ptp_time_string_t modify_time_str = { 0 };
261 ptp_string_t keywords;
263 retv_if(buf == NULL, 0);
264 retv_if(obj == NULL, 0);
266 ret = _entity_get_file_times(obj, &create_time_str, &modify_time_str);
268 ERR("_entity_get_file_times() Fail");
272 _prop_copy_char_to_ptpstring(&keywords, (mtp_wchar *)"", WCHAR_TYPE);
274 if (buf_sz < _entity_get_object_info_size(obj, file_name)) {
275 ERR("Buffer size is less than object info size");
279 /* As per Spec ObjectCompressedSize field in ObjectInfo dataset is
280 * 4 bytes. In case file size greater than 4Gb, value 0xFFFFFFFF is sent
282 objSize = (info->file_size >= MTP_FILESIZE_4GB) ?
283 0xFFFFFFFF : (mtp_uint32)info->file_size;
285 #ifdef __BIG_ENDIAN__
286 memcpy(&(buf[num_bytes]), &(info->store_id), sizeof(mtp_uint32));
287 _util_conv_byte_order(buf, sizeof(mtp_uint32));
288 num_bytes += sizeof(mtp_uint32);
290 memcpy(&(buf[num_bytes]), &(info->obj_fmt), sizeof(mtp_uint16));
291 _util_conv_byte_order(buf, sizeof(mtp_uint16));
292 num_bytes += sizeof(mtp_uint16);
294 memcpy(&(buf[num_bytes]), &(info->protcn_status), sizeof(mtp_uint16));
295 _util_conv_byte_order(buf, sizeof(mtp_uint16));
296 num_bytes += sizeof(mtp_uint16);
298 memcpy(&(buf[num_bytes]), &objSize, sizeof(mtp_uint32));
299 _util_conv_byte_order(buf, sizeof(mtp_uint32));
300 num_bytes += sizeof(mtp_uint32);
302 /* Thumb format has a constant value of 2 bytes */
303 memset(&(buf[num_bytes]), &thumb_fmt, sizeof(mtp_uint16));
304 _util_conv_byte_order(buf, sizeof(mtp_uint16));
305 num_bytes += sizeof(mtp_uint16);
307 memcpy(&(buf[num_bytes]), &(info->thumb_file_size), sizeof(mtp_uint32));
308 _util_conv_byte_order(buf, sizeof(mtp_uint32));
309 num_bytes += sizeof(mtp_uint32);
311 memcpy(&(buf[num_bytes]), &thumb_width, sizeof(mtp_uint32));
312 _util_conv_byte_order(buf, sizeof(mtp_uint32));
313 num_bytes += sizeof(mtp_uint32);
315 memcpy(&(buf[num_bytes]), &thumb_height, sizeof(mtp_uint32));
316 _util_conv_byte_order(buf, sizeof(mtp_uint32));
317 num_bytes += sizeof(mtp_uint32);
319 /* ObjProps:image_width, image_height, image_bit_depth values
320 * currently are always 0 for any type of FILE/FOLDER
322 memset(&(buf[num_bytes]), 0, sizeof(mtp_uint32) * 3);
323 _util_conv_byte_order(buf, sizeof(mtp_uint32) * 3);
324 num_bytes += (sizeof(mtp_uint32) * 3);
326 memcpy(&(buf[num_bytes]), &(info->h_parent), sizeof(mtp_uint32));
327 _util_conv_byte_order(buf, sizeof(mtp_uint32));
328 num_bytes += sizeof(mtp_uint32);
330 memcpy(&(buf[num_bytes]),
331 &(info->association_type), sizeof(mtp_uint16));
332 _util_conv_byte_order(buf, sizeof(mtp_uint16));
333 num_bytes += sizeof(mtp_uint16);
335 /* ObjProps:association desc,sequence number values are always 0 */
336 memset(&(buf[num_bytes]), 0, sizeof(mtp_uint32) * 2);
337 _util_conv_byte_order(buf, sizeof(mtp_uint32) * 2);
338 num_bytes += (sizeof(mtp_uint32) * 2);
340 #else /* __BIG_ENDIAN__ */
342 /* ObjProps:store_id, obj_format, protection status */
343 memcpy(buf, &(info->store_id),
344 (sizeof(mtp_uint32) + sizeof(mtp_uint16) * 2));
345 num_bytes += (sizeof(mtp_uint32) + sizeof(mtp_uint16) * 2);
347 memcpy(&buf[num_bytes], &objSize, sizeof(mtp_uint32));
348 num_bytes += sizeof(mtp_uint32);
350 /* ObjProp:thumb format */
351 memcpy(&buf[num_bytes], &thumb_fmt, sizeof(mtp_uint16));
352 num_bytes += sizeof(mtp_uint16);
354 /* ObjProp: thumb file size */
355 memcpy(&buf[num_bytes], &(info->thumb_file_size), sizeof(mtp_uint32));
356 num_bytes += sizeof(mtp_uint32);
358 /* ObjProp:thumb_width */
359 memcpy(&buf[num_bytes], &thumb_width, sizeof(mtp_uint32));
360 num_bytes += sizeof(mtp_uint32);
362 /* ObjProp:thumb_height */
363 memcpy(&buf[num_bytes], &thumb_height, sizeof(mtp_uint32));
364 num_bytes += sizeof(mtp_uint32);
366 /* ObjProp:image_width, image_height,
367 * image_bit_depth values currently are always 0
369 memset(&(buf[num_bytes]), 0, sizeof(mtp_uint32) * 3);
370 num_bytes += (sizeof(mtp_uint32) * 3);
372 /* ObjProp:parent_handle */
373 memcpy(&buf[num_bytes], &(info->h_parent), sizeof(mtp_uint32));
374 num_bytes += sizeof(mtp_uint32);
376 /* ObjProp:association_type */
377 memcpy(&buf[num_bytes], &(info->association_type), sizeof(mtp_uint16));
378 num_bytes += sizeof(mtp_uint16);
380 /* ObjProp:association_desc,sequence Number values are always 0 */
381 memset(&buf[num_bytes], 0, sizeof(mtp_uint32) * 2);
382 num_bytes += sizeof(mtp_uint32) * 2;
383 #endif /* __BIG_ENDIAN__ */
385 num_bytes += _prop_pack_ptpstring(file_name, buf + num_bytes,
386 _prop_size_ptpstring(file_name));
388 num_bytes += _prop_pack_ptptimestring(&create_time_str,
390 _prop_size_ptptimestring(&create_time_str));
392 num_bytes += _prop_pack_ptptimestring(&modify_time_str,
394 _prop_size_ptptimestring(&modify_time_str));
396 num_bytes += _prop_pack_ptpstring(&keywords,
398 _prop_size_ptpstring(&keywords));
400 DBG("number of bytes for objectinfo :[%d]\n", num_bytes);
404 void _entity_dealloc_obj_info(obj_info_t *info)
411 mtp_obj_t *_entity_alloc_mtp_object(void)
413 return ((mtp_obj_t *)g_malloc(sizeof(mtp_obj_t)));
416 mtp_bool _entity_init_mtp_object_params(
422 dir_entry_t *file_info)
424 retv_if(obj == NULL, FALSE);
427 obj->obj_info = NULL;
428 obj->file_path = NULL;
429 obj->obj_handle = _entity_generate_next_obj_handle();
430 _entity_set_object_file_path(obj, file_path, CHAR_TYPE);
431 obj->obj_info = _entity_alloc_object_info();
433 if (NULL == obj->obj_info) {
434 g_free(obj->file_path);
437 _entity_init_object_info_params(obj->obj_info, store_id, h_parent,
438 file_name, file_info);
440 _util_init_list(&(obj->propval_list));
441 memset(&(obj->child_array), 0, sizeof(ptp_array_t));
442 obj->child_array.type = UINT32_TYPE;
447 mtp_bool _entity_set_object_file_path(mtp_obj_t *obj, void *file_path,
448 char_mode_t char_type)
450 mtp_char temp[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
452 if (char_type == WCHAR_TYPE) {
453 _util_utf16_to_utf8(temp, sizeof(temp), (mtp_wchar *)file_path);
454 g_free(obj->file_path);
455 obj->file_path = g_strdup(temp);
457 g_free(obj->file_path);
458 obj->file_path = g_strdup((char *)file_path);
463 mtp_bool _entity_check_child_obj_path(mtp_obj_t *obj,
464 mtp_char *src_path, mtp_char *dest_path)
467 mtp_char *ptr = NULL;
468 mtp_obj_t *child_obj = NULL;
469 ptp_array_t child_arr = { 0 };
470 mtp_store_t *src_store = NULL;
471 mtp_char dest_chld_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
472 mtp_char temp_chld_path[MTP_MAX_PATHNAME_SIZE + 1] = { 0 };
473 mtp_wchar dest_chld_wpath[MTP_MAX_PATHNAME_SIZE * 2 + 1] = { 0 };
474 mtp_wchar temp_chld_wpath[MTP_MAX_PATHNAME_SIZE * 2 + 1] = { 0 };
476 retv_if(obj == NULL, FALSE);
478 if (strlen(dest_path) > MTP_MAX_PATHNAME_SIZE - 1) {
479 ERR("dest_path is too long[%d]\n", strlen(dest_path));
483 if (strlen(src_path) > MTP_MAX_PATHNAME_SIZE - 1) {
484 ERR("src_path is too long[%d]\n", strlen(src_path));
488 src_store = _device_get_store_containing_obj(obj->obj_handle);
489 if (NULL == src_store) {
490 ERR("Object not present in store");
494 _prop_init_ptparray(&child_arr, UINT32_TYPE);
495 _entity_get_child_handles(src_store, obj->obj_handle, &child_arr);
497 DBG("obj_handle[%d], src_path[%s], dest_path[%s], num elements[%ld]\n",
498 obj->obj_handle, src_path, dest_path, child_arr.num_ele);
500 for (idx = 0; idx < child_arr.num_ele; idx++) {
501 mtp_uint32 *ptr32 = child_arr.array_entry;
503 child_obj = _entity_get_object_from_store(src_store, ptr32[idx]);
504 if (NULL == child_obj)
507 if (_util_is_file_opened(child_obj->file_path) == TRUE) {
508 ERR_SECURE("File [%s] is already opened\n",
509 child_obj->file_path);
513 g_strlcpy(temp_chld_path, child_obj->file_path,
514 MTP_MAX_PATHNAME_SIZE + 1);
515 _util_utf8_to_utf16(temp_chld_wpath,
516 sizeof(temp_chld_wpath) / WCHAR_SIZ, temp_chld_path);
517 if (_util_wchar_len(temp_chld_wpath) >
518 MTP_MAX_PATHNAME_SIZE - 1) {
519 ERR("Child Object Full Path is too long[%d]\n",
520 strlen(child_obj->file_path));
521 _prop_deinit_ptparray(&child_arr);
525 ptr = strstr(child_obj->file_path, src_path);
529 _util_utf8_to_utf16(dest_chld_wpath,
530 sizeof(dest_chld_wpath) / WCHAR_SIZ, src_path);
532 if (_util_wchar_len(dest_chld_wpath) <
533 MTP_MAX_PATHNAME_SIZE - 1) {
534 g_strlcpy(dest_chld_path, dest_path,
535 MTP_MAX_PATHNAME_SIZE + 1);
537 ERR("dest_chld_wpath is too long[%d]\n",
539 _prop_deinit_ptparray(&child_arr);
543 ptr += strlen(src_path);
544 if ((strlen(dest_chld_path) + strlen(ptr)) <
545 MTP_MAX_PATHNAME_SIZE) {
546 g_strlcat(dest_chld_path, ptr,
547 MTP_MAX_PATHNAME_SIZE + 1);
549 ERR("dest_chld_path + ptr is too long[%d]\n",
550 (strlen(ptr) + strlen(ptr)));
551 _prop_deinit_ptparray(&child_arr);
554 DBG("dest_chld_path[%s], ptr[%s]\n", dest_chld_path, ptr);
556 if (_entity_check_child_obj_path(child_obj,
557 temp_chld_path, dest_chld_path) == FALSE) {
558 ERR("set full path Fail");
559 _prop_deinit_ptparray(&child_arr);
564 _prop_deinit_ptparray(&child_arr);
568 mtp_bool _entity_set_child_object_path(mtp_obj_t *obj, mtp_char *src_path,
572 mtp_char *ptr = NULL;
573 ptp_array_t child_arr = {0};
574 mtp_obj_t *child_obj = NULL;
575 mtp_store_t *src_store = NULL;
576 mtp_uint32 *child_handle_arr = NULL;
577 mtp_char dest_child_path[MTP_MAX_PATHNAME_SIZE + 1] = {0};
578 mtp_char temp_child_path[MTP_MAX_PATHNAME_SIZE + 1] = {0};
580 retv_if(NULL == obj, FALSE);
581 retv_if(NULL == src_path, FALSE);
582 retv_if(NULL == dest_path, FALSE);
584 src_store = _device_get_store_containing_obj(obj->obj_handle);
585 if (NULL == src_store) {
586 ERR("Object not present in store");
590 _prop_init_ptparray(&child_arr, UINT32_TYPE);
591 _entity_get_child_handles(src_store, obj->obj_handle, &child_arr);
592 DBG("Object handle[%ld], src_path[%s], dest_path[%s], Numchild[%ld]\n",
593 obj->obj_handle, src_path, dest_path, child_arr.num_ele);
595 for (idx = 0; idx < child_arr.num_ele; idx++) {
596 child_handle_arr = child_arr.array_entry;
597 child_obj = _entity_get_object_from_store(src_store, child_handle_arr[idx]);
598 if (NULL == child_obj)
600 DBG_SECURE("obj_handle[%ld], full path[%s]\n", child_obj->obj_handle,
601 child_obj->file_path);
602 g_strlcpy(temp_child_path, child_obj->file_path,
603 sizeof(temp_child_path));
605 ptr = strstr(child_obj->file_path, src_path);
609 g_strlcpy(dest_child_path, dest_path, sizeof(dest_child_path));
611 ptr += strlen(src_path);
612 if (g_strlcat(dest_child_path, ptr, sizeof(dest_child_path)) >=
613 sizeof(dest_child_path)) {
614 ERR("g_strlcat truncation occured,failed to create\
616 _entity_remove_reference_child_array(obj,
617 child_obj->obj_handle);
618 _entity_dealloc_mtp_obj(child_obj);
621 _util_delete_file_from_db(child_obj->file_path);
623 if (_entity_set_object_file_path(child_obj, dest_child_path,
624 CHAR_TYPE) == FALSE) {
625 ERR("Failed to set full path!!");
626 _entity_remove_reference_child_array(obj,
627 child_obj->obj_handle);
628 _entity_dealloc_mtp_obj(child_obj);
632 if (child_obj->obj_info == NULL) {
633 ERR("obj_info is NULL");
637 if ((child_obj->obj_info->obj_fmt == PTP_FMT_ASSOCIATION)) {
638 if (_entity_set_child_object_path(child_obj, temp_child_path,
639 dest_child_path) == FALSE) {
640 ERR("Fail to set the full path!!");
641 _entity_remove_reference_child_array(obj,
642 child_obj->obj_handle);
643 _entity_dealloc_mtp_obj(child_obj);
649 _prop_deinit_ptparray(&child_arr);
653 mtp_bool _entity_add_reference_child_array(mtp_obj_t *obj, mtp_uint32 handle)
655 if (_prop_find_ele_ptparray(&(obj->child_array), handle) ==
657 return (_prop_append_ele_ptparray(&(obj->child_array), handle));
663 ptp_array_t *_entity_get_reference_child_array(mtp_obj_t *obj)
665 return &(obj->child_array);
668 mtp_bool _entity_set_reference_child_array(mtp_obj_t *obj, mtp_uchar *buf,
672 mtp_uint32 no_ref = 0;
673 mtp_uint32 ref_handle = 0;
675 retv_if(NULL == buf, FALSE);
677 /*Retrieve the number of references*/
680 /*Clean up the reference array*/
681 _entity_remove_reference_child_array(obj, PTP_OBJECTHANDLE_ALL);
683 /* Grow the array to accommodate all references*/
684 if (_prop_grow_ptparray(&(obj->child_array), no_ref) == FALSE) {
685 ERR("grow ptp Array Fail");
690 for (i = 0; i < no_ref; i++) {
691 memcpy(&ref_handle, buf, sizeof(mtp_uint32));
692 buf += sizeof(mtp_uint32);
693 _prop_append_ele_ptparray(&(obj->child_array), ref_handle);
699 void _entity_copy_mtp_object(mtp_obj_t *dst, mtp_obj_t *src)
701 /*Copy same information*/
702 dst->obj_info = _entity_alloc_object_info();
703 if (dst->obj_info == NULL) {
704 ERR("Object info allocation Fail.");
707 _entity_copy_obj_info(dst->obj_info, src->obj_info);
709 dst->file_path = NULL;
711 #ifndef MTP_USE_RUNTIME_GETOBJECTPROPVALUE
712 _prop_update_property_values_list(dst);
713 #endif /* MTP_USE_RUNTIME_GETOBJECTPROPVALUE */
717 mtp_bool _entity_remove_reference_child_array(mtp_obj_t *obj, mtp_uint32 handle)
719 if (handle == PTP_OBJECTHANDLE_ALL) {
720 _prop_deinit_ptparray(&(obj->child_array));
723 return _prop_rem_elem_ptparray(&(obj->child_array), handle);
726 void _entity_dealloc_mtp_obj(mtp_obj_t *obj)
729 slist_node_t *node = NULL;
730 slist_node_t *next_node = NULL;
735 _entity_dealloc_obj_info(obj->obj_info);
736 obj->obj_info = NULL;
739 _entity_remove_reference_child_array(obj, PTP_OBJECTHANDLE_ALL);
741 for (ii = 0, next_node = obj->propval_list.start;
742 ii < obj->propval_list.nnodes; ii++) {
744 next_node = node->link;
745 _prop_destroy_obj_propval((obj_prop_val_t *)node->value);
749 g_free(obj->file_path);