Apply requirement for gcov automation
[platform/core/system/libstorage.git] / src / storage.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <errno.h>
22 #include <vconf.h>
23 #include <tzplatform_config.h>
24 #include <libsyscommon/list.h>
25
26 #include "common.h"
27 #include "log.h"
28 #include "storage-external.h"
29
30 const char *dir_path[STORAGE_DIRECTORY_MAX];
31
32 const int tz_id[STORAGE_DIRECTORY_MAX] = {
33         [STORAGE_DIRECTORY_IMAGES] = TZ_USER_IMAGES,
34         [STORAGE_DIRECTORY_SOUNDS] = TZ_USER_SOUNDS,
35         [STORAGE_DIRECTORY_VIDEOS] = TZ_USER_VIDEOS,
36         [STORAGE_DIRECTORY_CAMERA] = TZ_USER_CAMERA,
37         [STORAGE_DIRECTORY_DOWNLOADS] = TZ_USER_DOWNLOADS,
38         [STORAGE_DIRECTORY_MUSIC] = TZ_USER_MUSIC,
39         [STORAGE_DIRECTORY_DOCUMENTS] = TZ_USER_DOCUMENTS,
40         [STORAGE_DIRECTORY_OTHERS] = TZ_USER_OTHERS,
41 };
42
43 static GList *st_int_head; /* Internal storage list */
44
45 static GList *compat_cb_list;
46 struct compat_cb_info {
47         storage_state_changed_cb user_cb;
48         void *user_data;
49 };
50
51 void add_device(const struct storage_ops *st)
52 {
53         SYS_G_LIST_APPEND(st_int_head, st);
54 }
55
56 void remove_device(const struct storage_ops *st)
57 {
58         SYS_G_LIST_REMOVE(st_int_head, st);
59 }
60
61 API int storage_foreach_device_supported(storage_device_supported_cb callback, void *user_data)
62 {
63         const struct storage_ops *st;
64         GList *elem;
65         int ret_val;
66         bool user = true;
67
68         if (!callback) {
69                 _E("Invalid parameter");
70                 return STORAGE_ERROR_INVALID_PARAMETER;
71         }
72
73         if (getuid() <= USER_UID_START)
74                 user = false;
75
76         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
77                 if (user) {
78                         ret_val = callback(st->storage_id, st->type, st->get_state(),
79                                         st->root(), user_data);
80                         /* if the return value is false, will be stop to iterate */
81                         if (!ret_val)
82                                 break;
83                 }
84         }
85
86         if (!storage_ext_is_supported()) {
87                 _D("Block module is not enabled");
88                 return STORAGE_ERROR_NONE;
89         }
90
91         ret_val = storage_ext_foreach_device_list(callback, user_data);
92         if (ret_val < 0) {
93                 _E("Failed to iterate external devices (%d)", ret_val); //LCOV_EXCL_LINE
94                 return STORAGE_ERROR_OPERATION_FAILED;
95         }
96
97         return STORAGE_ERROR_NONE;
98 }
99
100 API int storage_get_root_directory(int storage_id, char **path)
101 {
102         const struct storage_ops *st;
103         GList *elem;
104         char root[PATH_MAX];
105         int ret_val;
106         bool extendedint;
107         bool user = true;
108
109         if (storage_id < 0)
110                 return STORAGE_ERROR_INVALID_PARAMETER;
111
112         if (!path) {
113                 _E("Invalid parameger");
114                 return STORAGE_ERROR_INVALID_PARAMETER;
115         }
116
117         if (getuid() <= USER_UID_START)
118                 user = false;
119
120         /* internal storage */
121         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
122                 if (st->storage_id != storage_id)
123                         continue;
124                 if (!user) {
125                         _E("Only apps and user session daemons are allowed "
126                                         "to use storage_get_root_directory(INTERNAL_STORAGE_ID, ...)");
127                         return STORAGE_ERROR_INVALID_PARAMETER;
128                 }
129
130                 *path = strdup(st->root());
131                 if (!*path) {
132 //LCOV_EXCL_START System Error
133                         _E("Failed to copy the root string : %d", errno);
134                         return STORAGE_ERROR_OUT_OF_MEMORY;
135 //LCOV_EXCL_STOP
136                 }
137                 return STORAGE_ERROR_NONE;
138         }
139
140         /* external storage */
141         if (!storage_ext_is_supported()) {
142                 _D("Block module is not enabled");
143                 return STORAGE_ERROR_NOT_SUPPORTED;
144         }
145
146         ret_val = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
147         if (ret_val < 0) {
148                 _E("Failed to get root path of external storage(%d, %d", storage_id, ret_val); //LCOV_EXCL_LINE
149                 if (ret_val == -ENODEV || ret_val == -EINVAL)
150                         return STORAGE_ERROR_INVALID_PARAMETER;
151                 else if (ret_val == -ENOMEM)
152                         return STORAGE_ERROR_OUT_OF_MEMORY;
153                 else
154                         return STORAGE_ERROR_OPERATION_FAILED;
155         }
156
157         *path = strdup(root);
158         if (!*path) {
159                 _E("Failed to copy the root string : %d", errno); //LCOV_EXCL_LINE System Error
160                 return STORAGE_ERROR_OUT_OF_MEMORY;
161         }
162
163         return STORAGE_ERROR_NONE;
164 }
165
166 API int storage_get_directory(int storage_id, storage_directory_e type, char **path)
167 {
168         const struct storage_ops *st;
169         char root[PATH_MAX];
170         char temp[PATH_MAX];
171         char *temp2, *end;
172         int ret_val;
173         GList *elem;
174         bool found;
175         bool extendedint;
176         bool user = true;
177
178         if (storage_id < 0)
179                 return STORAGE_ERROR_INVALID_PARAMETER;
180
181         if (!path) {
182                 _E("Invalid parameger");
183                 return STORAGE_ERROR_INVALID_PARAMETER;
184         }
185
186         if (type < 0 || type >= STORAGE_DIRECTORY_MAX) {
187                 _E("Invalid parameter");
188                 return STORAGE_ERROR_INVALID_PARAMETER;
189         }
190
191         /* internal storage */
192         found = false;
193         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
194                 if (st->storage_id != storage_id)
195                         continue;
196                 found = true;
197                 break;
198         }
199
200         if (getuid() <= USER_UID_START)
201                 user = false;
202
203         if (found && st) {
204                 if (!user) {
205                         _E("Only apps and user session daemons are allowed "
206                                         "to use storage_get_root_directory(INTERNAL_STORAGE_ID, ...)");
207
208                         return STORAGE_ERROR_INVALID_PARAMETER;
209                 }
210
211                 snprintf(root, sizeof(root), "%s", st->root());
212                 if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
213                         temp2 = vconf_get_str(VCONFKEY_SETAPPL_CALL_RINGTONE_PATH_STR);
214                         if (temp2 == NULL)
215                                 return STORAGE_ERROR_OPERATION_FAILED;
216                         end = strrchr(temp2, '/');
217                         if (end)
218                                 *end = '\0';
219                         snprintf(temp, PATH_MAX, "%s", temp2);
220                         free(temp2);
221                 } else {
222                         if ((ret_val = snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type])) > PATH_MAX - 1) {
223                                 _E("Path is longer than buffer. Need %d size of buffer.", ret_val + 1);
224                                 return STORAGE_ERROR_OUT_OF_MEMORY;
225                         }
226                 }
227
228                 goto out;
229         }
230
231         /* external storage */
232         if (!storage_ext_is_supported()) {
233                 _D("Block module is not enabled");
234                 return STORAGE_ERROR_NOT_SUPPORTED;
235         }
236
237         if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
238                 _E("Not support directory : id(%d) type(%d)", storage_id, type); //LCOV_EXCL_LINE
239                 return STORAGE_ERROR_INVALID_PARAMETER;
240         }
241
242         ret_val = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
243         if (ret_val < 0) {
244                 _E("Failed to get root dir for external storage(id:%d, ret:%d)", storage_id, ret_val); //LCOV_EXCL_LINE
245                 if (ret_val == -ENODEV || ret_val == -EINVAL)
246                         return STORAGE_ERROR_INVALID_PARAMETER;
247                 else if (ret_val == -ENOMEM)
248                         return STORAGE_ERROR_OUT_OF_MEMORY;
249                 else
250                         return STORAGE_ERROR_OPERATION_FAILED;
251         }
252         /* The operation is not decided */
253         if (extendedint)
254                 return STORAGE_ERROR_INVALID_PARAMETER;
255
256         if ((ret_val = snprintf(temp, sizeof(temp), "%s/%s", root, dir_path[type])) > sizeof(temp) - 1) {
257                 _E("Path is longer than buffer. Need %d size of buffer.", ret_val + 1);
258                 return STORAGE_ERROR_OUT_OF_MEMORY;
259         }
260
261 out:
262         *path = strdup(temp);
263         if (!*path) {
264                 _E("Failed to copy the directory(%d) string : %d", type, errno); //LCOV_EXCL_LINE
265                 return STORAGE_ERROR_OUT_OF_MEMORY;
266         }
267
268         return STORAGE_ERROR_NONE;
269 }
270
271 API int storage_get_type(int storage_id, storage_type_e *type)
272 {
273         const struct storage_ops *st;
274         GList *elem;
275         char root[PATH_MAX];
276         int ret_val;
277         bool extendedint;
278
279         if (storage_id < 0)
280                 return STORAGE_ERROR_INVALID_PARAMETER;
281
282         if (!type) {
283                 _E("Invalid parameger");
284                 return STORAGE_ERROR_INVALID_PARAMETER;
285         }
286
287         /* internal storage */
288         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
289                 if (st->storage_id != storage_id)
290                         continue;
291                 *type = st->type;
292                 return STORAGE_ERROR_NONE;
293         }
294
295         /* external storage */
296         if (!storage_ext_is_supported()) {
297                 _D("Block module is not enabled");
298                 return STORAGE_ERROR_NOT_SUPPORTED;
299         }
300
301         ret_val = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
302         if (ret_val < 0) {
303                 _E("Failed to get type of external storage");
304                 if (ret_val == -ENODEV || ret_val == -EINVAL)
305                         return STORAGE_ERROR_INVALID_PARAMETER;
306                 else if (ret_val == -ENOMEM)
307                         return STORAGE_ERROR_OUT_OF_MEMORY;
308                 else
309                         return STORAGE_ERROR_OPERATION_FAILED;
310         }
311         if (extendedint)
312                 *type = STORAGE_TYPE_EXTENDED_INTERNAL;
313         else
314                 *type = STORAGE_TYPE_EXTERNAL;
315
316         return STORAGE_ERROR_NONE;
317 }
318
319 API int storage_get_state(int storage_id, storage_state_e *state)
320 {
321         const struct storage_ops *ops;
322         storage_state_e st;
323         GList *elem;
324         int ret_val;
325
326         if (storage_id < 0)
327                 return STORAGE_ERROR_INVALID_PARAMETER;
328
329         if (!state) {
330                 _E("Invalid parameger");
331                 return STORAGE_ERROR_INVALID_PARAMETER;
332         }
333
334         /* internal storage */
335         SYS_G_LIST_FOREACH(st_int_head, elem, ops) {
336                 if (ops->storage_id != storage_id)
337                         continue;
338                 *state = ops->get_state();
339                 return STORAGE_ERROR_NONE;
340         }
341
342         /* external storage */
343         if (!storage_ext_is_supported()) {
344                 _D("Block module is not enabled");
345                 return STORAGE_ERROR_NOT_SUPPORTED;
346         }
347
348         ret_val = storage_ext_get_state(storage_id, &st);
349         if (ret_val < 0) {
350                 _E("Failed to get state (storage id(%d), ret_val(%d))", storage_id, ret_val); //LCOV_EXCL_LINE
351                 if (ret_val == -ENODEV || ret_val == -EINVAL)
352                         return STORAGE_ERROR_INVALID_PARAMETER;
353                 else if (ret_val == -ENOMEM)
354                         return STORAGE_ERROR_OUT_OF_MEMORY;
355                 else
356                         return STORAGE_ERROR_OPERATION_FAILED;
357         }
358
359         *state = st;
360         return STORAGE_ERROR_NONE;
361 }
362
363 //LCOV_EXCL_START Not called Callback
364 static void compat_cb(int storage_id,
365                 storage_dev_e dev, storage_state_e state,
366                 const char *fstype, const char *fsuuid, const char *mountpath,
367                 bool primary, int flags, void *user_data)
368 {
369         struct compat_cb_info* ccb_info;
370         GList *elem;
371
372         if (storage_id == STORAGE_TYPE_EXTERNAL && dev == STORAGE_DEV_EXT_SDCARD)
373                 SYS_G_LIST_FOREACH(compat_cb_list, elem, ccb_info)
374                         ccb_info->user_cb(storage_id, state, ccb_info->user_data);
375 }
376 //LCOV_EXCL_STOP
377
378 API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data)
379 {
380         const struct storage_ops *st;
381         struct storage_cb_info info;
382         int ret;
383         GList *elem;
384
385         struct compat_cb_info* ccb_info;
386         static int compat_cb_init = 0;
387
388         if (storage_id < 0)
389                 return STORAGE_ERROR_INVALID_PARAMETER;
390
391         if (!callback) {
392                 _E("Invalid parameger");
393                 return STORAGE_ERROR_INVALID_PARAMETER;
394         }
395
396         /* For backward compatability */
397         if (storage_id == STORAGE_TYPE_EXTERNAL) {
398                 if (!storage_ext_is_supported()) {
399                         _D("Block module is not enabled");
400                         return STORAGE_ERROR_NOT_SUPPORTED;
401                 }
402
403                 if (!compat_cb_init) {
404                         ret = storage_set_changed_cb(STORAGE_TYPE_EXTERNAL, compat_cb, NULL);
405                         if (ret == STORAGE_ERROR_NONE)
406                                 compat_cb_init = 1;
407                         else
408                                 return ret;
409                 }
410
411                 ccb_info = malloc(sizeof(struct compat_cb_info));
412                 if (ccb_info == NULL)
413                         return STORAGE_ERROR_OPERATION_FAILED;
414                 ccb_info->user_cb = callback;
415                 ccb_info->user_data = user_data;
416                 SYS_G_LIST_APPEND(compat_cb_list, ccb_info);
417
418                 return STORAGE_ERROR_NONE;
419         }
420
421         /* Internal storage does not support registering changed callback */
422         SYS_G_LIST_FOREACH(st_int_head, elem, st)
423                 if (st->storage_id == storage_id)
424                         return STORAGE_ERROR_NONE;
425
426         /* external storage */
427         if (!storage_ext_is_supported()) {
428                 _D("Block module is not enabled");
429                 return STORAGE_ERROR_NOT_SUPPORTED;
430         }
431
432         info.id = storage_id;
433         info.state_cb = callback;
434         info.user_data = user_data;
435
436         ret = storage_ext_register_cb(STORAGE_CALLBACK_ID, &info);
437         if (ret < 0) {
438                 _E("Failed to register callback : id(%d)", storage_id); //LCOV_EXCL_LINE
439                 return STORAGE_ERROR_OPERATION_FAILED;
440         }
441
442         return STORAGE_ERROR_NONE;
443 }
444
445 API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback)
446 {
447         const struct storage_ops *st;
448         struct storage_cb_info info;
449         int ret_val;
450         GList *elem;
451
452         if (storage_id < 0)
453                 return STORAGE_ERROR_INVALID_PARAMETER;
454
455         if (!callback) {
456                 _E("Invalid parameger");
457                 return STORAGE_ERROR_INVALID_PARAMETER;
458         }
459
460         /* For backward compatability */
461         if (storage_id == STORAGE_TYPE_EXTERNAL) {
462                 if (!storage_ext_is_supported()) {
463                         _D("Block module is not enabled");
464                         return STORAGE_ERROR_NOT_SUPPORTED;
465                 }
466
467                 GList *elem_n;
468                 struct compat_cb_info* ccb_info;
469
470                 SYS_G_LIST_FOREACH_SAFE(compat_cb_list, elem, elem_n, ccb_info) {
471                         if (ccb_info->user_cb == callback) {
472                                 SYS_G_LIST_REMOVE(compat_cb_list, ccb_info);
473                                 free(ccb_info);
474                                 return STORAGE_ERROR_NONE;
475                         }
476                 }
477                 return STORAGE_ERROR_OPERATION_FAILED;
478         }
479
480         /* Internal storage does not support registering changed callback */
481         SYS_G_LIST_FOREACH(st_int_head, elem, st)
482                 if (st->storage_id == storage_id)
483                         return STORAGE_ERROR_NONE;
484
485         /* external storage */
486         if (!storage_ext_is_supported()) {
487                 _D("Block module is not enabled");
488                 return STORAGE_ERROR_NOT_SUPPORTED;
489         }
490
491         info.id = storage_id;
492         info.state_cb = callback;
493
494         ret_val = storage_ext_unregister_cb(STORAGE_CALLBACK_ID, &info);
495         if (ret_val < 0) {
496                 _E("Failed to unregister callback : id(%d)", storage_id); //LCOV_EXCL_LINE
497                 return STORAGE_ERROR_OPERATION_FAILED;
498         }
499
500         return STORAGE_ERROR_NONE;
501 }
502
503 API int storage_get_total_space(int storage_id, unsigned long long *bytes)
504 {
505         const struct storage_ops *st;
506         unsigned long long total;
507         int ret_val;
508         GList *elem;
509
510         if (storage_id < 0)
511                 return STORAGE_ERROR_INVALID_PARAMETER;
512
513         if (!bytes) {
514                 _E("Invalid parameger");
515                 return STORAGE_ERROR_INVALID_PARAMETER;
516         }
517
518         /* internal storage */
519         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
520                 if (st->storage_id != storage_id)
521                         continue;
522                 ret_val = st->get_space(&total, NULL);
523                 goto out;
524         }
525
526         /* external storage */
527         if (!storage_ext_is_supported()) {
528                 _D("Block module is not enabled");
529                 return STORAGE_ERROR_NOT_SUPPORTED;
530         }
531
532         ret_val = storage_ext_get_space(storage_id, &total, NULL);
533
534 out:
535         if (ret_val < 0) {
536                 _E("Failed to get total memory : id(%d)", storage_id); //LCOV_EXCL_LINE
537                 if (ret_val == -ENODEV || ret_val == -EINVAL)
538                         return STORAGE_ERROR_INVALID_PARAMETER;
539                 else if (ret_val == -ENOMEM)
540                         return STORAGE_ERROR_OUT_OF_MEMORY;
541                 else
542                         return STORAGE_ERROR_OPERATION_FAILED;
543         }
544
545         *bytes = total;
546         return STORAGE_ERROR_NONE;
547 }
548
549 API int storage_get_available_space(int storage_id, unsigned long long *bytes)
550 {
551         const struct storage_ops *st;
552         unsigned long long avail;
553         int ret_val;
554         GList *elem;
555
556         if (storage_id < 0)
557                 return STORAGE_ERROR_INVALID_PARAMETER;
558
559         if (!bytes) {
560                 _E("Invalid parameger");
561                 return STORAGE_ERROR_INVALID_PARAMETER;
562         }
563
564         /* internal storage */
565         SYS_G_LIST_FOREACH(st_int_head, elem, st) {
566                 if (st->storage_id != storage_id)
567                         continue;
568                 ret_val = st->get_space(NULL, &avail);
569                 goto out;
570         }
571
572         /* external storage */
573         if (!storage_ext_is_supported()) {
574                 _D("Block module is not enabled");
575                 return STORAGE_ERROR_NOT_SUPPORTED;
576         }
577
578         ret_val = storage_ext_get_space(storage_id, NULL, &avail);
579
580 out:
581         if (ret_val < 0) {
582                 _E("Failed to get available memory : id(%d)", storage_id); //LCOV_EXCL_LINE
583                 if (ret_val == -ENODEV || ret_val == -EINVAL)
584                         return STORAGE_ERROR_INVALID_PARAMETER;
585                 else if (ret_val == -ENOMEM)
586                         return STORAGE_ERROR_OUT_OF_MEMORY;
587                 else
588                         return STORAGE_ERROR_OPERATION_FAILED;
589         }
590
591         *bytes = avail;
592         return STORAGE_ERROR_NONE;
593 }
594
595 API int storage_set_changed_cb(storage_type_e type, storage_changed_cb callback, void *user_data)
596 {
597         int ret_val;
598         struct storage_cb_info info;
599
600         if (type == STORAGE_TYPE_INTERNAL) {
601                 _E("Internal storage is not supported");
602                 return STORAGE_ERROR_INVALID_PARAMETER;
603         }
604
605         if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
606                 _E("Invalid type (%d)", type);
607                 return STORAGE_ERROR_INVALID_PARAMETER;
608         }
609
610         if (!callback) {
611                 _E("Callback is NULL");
612                 return STORAGE_ERROR_INVALID_PARAMETER;
613         }
614
615         if (!storage_ext_is_supported()) {
616                 _E("Block module is not enabled");
617                 return STORAGE_ERROR_NOT_SUPPORTED;
618         }
619
620         /* external storage */
621         info.type = type;
622         info.type_cb = callback;
623         info.user_data = user_data;
624
625         ret_val = storage_ext_register_cb(STORAGE_CALLBACK_TYPE, &info);
626         if (ret_val < 0) {
627                 _E("Failed to register storage callback(ret:%d)", ret_val); //LCOV_EXCL_LINE
628                 return STORAGE_ERROR_OPERATION_FAILED;
629         }
630
631         return STORAGE_ERROR_NONE;
632 }
633
634 API int storage_unset_changed_cb(storage_type_e type, storage_changed_cb callback)
635 {
636         struct storage_cb_info info;
637         int ret_val;
638
639         if (type == STORAGE_TYPE_INTERNAL) {
640                 _E("Internal storage is not supported");
641                 return STORAGE_ERROR_INVALID_PARAMETER;
642         }
643
644         if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
645                 _E("Invalid type (%d)", type);
646                 return STORAGE_ERROR_INVALID_PARAMETER;
647         }
648
649         if (!callback) {
650                 _E("Callback is NULL");
651                 return STORAGE_ERROR_INVALID_PARAMETER;
652         }
653
654         if (!storage_ext_is_supported()) {
655                 _E("Block module is not enabled");
656                 return STORAGE_ERROR_NOT_SUPPORTED;
657         }
658
659         /* external storage */
660         info.type = type;
661         info.type_cb = callback;
662
663         ret_val = storage_ext_unregister_cb(STORAGE_CALLBACK_TYPE, &info);
664         if (ret_val < 0) {
665                 _E("Failed to unregister storage callback(ret:%d)", ret_val); //LCOV_EXCL_LINE
666                 return STORAGE_ERROR_OPERATION_FAILED;
667         }
668
669         return STORAGE_ERROR_NONE;
670 }
671
672 API int storage_get_type_dev(int storage_id, storage_type_e *type, storage_dev_e *dev)
673 {
674         storage_ext_device *ext_dev;
675         int ret;
676
677         if (storage_id < 0 || !type || !dev) {
678                 _E("Invalid parameter");
679                 return STORAGE_ERROR_INVALID_PARAMETER;
680         }
681
682         ret = storage_get_type(storage_id, type);
683         if (ret != STORAGE_ERROR_NONE) {
684                 _E("Failed to get storage type: %d", ret);
685                 return ret;
686         }
687         if (*type == STORAGE_TYPE_INTERNAL || *type == STORAGE_TYPE_EXTENDED_INTERNAL)
688                 return STORAGE_ERROR_INVALID_PARAMETER;
689
690         if (!storage_ext_is_supported()) {
691                 _D("Block module is not enabled");
692                 return STORAGE_ERROR_NOT_SUPPORTED;
693         }
694
695         ext_dev = calloc(1, sizeof(storage_ext_device));
696         if (!ext_dev) {
697                 //LCOV_EXCL_START System Error
698                 _E("calloc failed");
699                 return STORAGE_ERROR_OUT_OF_MEMORY;
700                 //LCOV_EXCL_STOP
701         }
702
703         ret = storage_ext_get_device_info(storage_id, ext_dev);
704         if (ret < 0) {
705                 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
706                 if (ret == -ENODEV) {
707                         ret =  STORAGE_ERROR_INVALID_PARAMETER;
708                         goto out;
709                 }
710                 ret = STORAGE_ERROR_OPERATION_FAILED;
711                 goto out;
712         }
713
714         if (ext_dev->type == STORAGE_EXT_SCSI)
715                 *dev = STORAGE_DEV_EXT_USB_MASS_STORAGE;
716         else if (ext_dev->type == STORAGE_EXT_MMC)
717                 *dev = STORAGE_DEV_EXT_SDCARD;
718         ret = STORAGE_ERROR_NONE;
719         _I("type: %d(internal:0, external:1) dev: %d(sdcard: 1001, usb: 1002)", *type, *dev);
720
721 out:
722         storage_ext_release_device(&ext_dev);
723         return ret;
724 }
725
726 static void __CONSTRUCTOR__ init(void)
727 {
728         const char *tmp;
729         char *token;
730         int i;
731
732         for (i = 0 ; i <= STORAGE_DIRECTORY_OTHERS ; i++) {
733                 tmp = tzplatform_getenv(tz_id[i]);
734                 if (tmp != NULL) {
735                         token = rindex(tmp, '/');
736                         if (token != NULL) {
737                                 token++;
738                                 dir_path[i] = strdup(token);
739                         }
740                 }
741         }
742 }