Return NOT_SUPPORTED error when block module is disabled
[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
25 #include "common.h"
26 #include "list.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 dd_list *st_int_head; /* Internal storage list */
44
45 static dd_list *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         DD_LIST_APPEND(st_int_head, st);
54 }
55
56 void remove_device(const struct storage_ops *st)
57 {
58         DD_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         dd_list *elem;
65         int ret;
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         DD_LIST_FOREACH(st_int_head, elem, st) {
77                 if (user) {
78                         ret = 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)
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 = storage_ext_foreach_device_list(callback, user_data);
92         if (ret < 0) {
93                 _E("Failed to iterate external devices (%d)", ret); //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         dd_list *elem;
104         char root[PATH_MAX];
105         int ret;
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         DD_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 = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
147         if (ret < 0) {
148                 _E("Failed to get root path of external storage(%d, %d", storage_id, ret); //LCOV_EXCL_LINE
149                 if (ret == -ENODEV || ret == -EINVAL)
150                         return STORAGE_ERROR_INVALID_PARAMETER;
151                 else if (ret == -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;
173         dd_list *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         DD_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                         snprintf(temp, PATH_MAX, "%s/%s", root, dir_path[type]);
223
224                 goto out;
225         }
226
227         /* external storage */
228         if (!storage_ext_is_supported()) {
229                 _D("Block module is not enabled");
230                 return STORAGE_ERROR_NOT_SUPPORTED;
231         }
232
233         if (type == STORAGE_DIRECTORY_SYSTEM_RINGTONES) {
234                 _E("Not support directory : id(%d) type(%d)", storage_id, type); //LCOV_EXCL_LINE
235                 return STORAGE_ERROR_INVALID_PARAMETER;
236         }
237
238         ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
239         if (ret < 0) {
240                 _E("Failed to get root dir for external storage(id:%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
241                 if (ret == -ENODEV || ret == -EINVAL)
242                         return STORAGE_ERROR_INVALID_PARAMETER;
243                 else if (ret == -ENOMEM)
244                         return STORAGE_ERROR_OUT_OF_MEMORY;
245                 else
246                         return STORAGE_ERROR_OPERATION_FAILED;
247         }
248         /* The operation is not decided */
249         if (extendedint)
250                 return STORAGE_ERROR_INVALID_PARAMETER;
251
252         snprintf(temp, sizeof(temp), "%s/%s", root, dir_path[type]);
253
254 out:
255         *path = strdup(temp);
256         if (!*path) {
257                 _E("Failed to copy the directory(%d) string : %d", type, errno); //LCOV_EXCL_LINE
258                 return STORAGE_ERROR_OUT_OF_MEMORY;
259         }
260
261         return STORAGE_ERROR_NONE;
262 }
263
264 API int storage_get_type(int storage_id, storage_type_e *type)
265 {
266         const struct storage_ops *st;
267         dd_list *elem;
268         char root[PATH_MAX];
269         int ret;
270         bool extendedint;
271
272         if (storage_id < 0)
273                 return STORAGE_ERROR_INVALID_PARAMETER;
274
275         if (!type) {
276                 _E("Invalid parameger");
277                 return STORAGE_ERROR_INVALID_PARAMETER;
278         }
279
280         /* internal storage */
281         DD_LIST_FOREACH(st_int_head, elem, st) {
282                 if (st->storage_id != storage_id)
283                         continue;
284                 *type = st->type;
285                 return STORAGE_ERROR_NONE;
286         }
287
288         /* external storage */
289         if (!storage_ext_is_supported()) {
290                 _D("Block module is not enabled");
291                 return STORAGE_ERROR_NOT_SUPPORTED;
292         }
293
294         ret = storage_ext_get_root(storage_id, root, sizeof(root), &extendedint);
295         if (ret < 0) {
296                 _E("Failed to get type of external storage");
297                 if (ret == -ENODEV || ret == -EINVAL)
298                         return STORAGE_ERROR_INVALID_PARAMETER;
299                 else if (ret == -ENOMEM)
300                         return STORAGE_ERROR_OUT_OF_MEMORY;
301                 else
302                         return STORAGE_ERROR_OPERATION_FAILED;
303         }
304         if (extendedint)
305                 *type = STORAGE_TYPE_EXTENDED_INTERNAL;
306         else
307                 *type = STORAGE_TYPE_EXTERNAL;
308
309         return STORAGE_ERROR_NONE;
310 }
311
312 API int storage_get_state(int storage_id, storage_state_e *state)
313 {
314         const struct storage_ops *ops;
315         storage_state_e st;
316         dd_list *elem;
317         int ret;
318
319         if (storage_id < 0)
320                 return STORAGE_ERROR_INVALID_PARAMETER;
321
322         if (!state) {
323                 _E("Invalid parameger");
324                 return STORAGE_ERROR_INVALID_PARAMETER;
325         }
326
327         /* internal storage */
328         DD_LIST_FOREACH(st_int_head, elem, ops) {
329                 if (ops->storage_id != storage_id)
330                         continue;
331                 *state = ops->get_state();
332                 return STORAGE_ERROR_NONE;
333         }
334
335         /* external storage */
336         if (!storage_ext_is_supported()) {
337                 _D("Block module is not enabled");
338                 return STORAGE_ERROR_NOT_SUPPORTED;
339         }
340
341         ret = storage_ext_get_state(storage_id, &st);
342         if (ret < 0) {
343                 _E("Failed to get state (storage id(%d), ret(%d))", storage_id, ret); //LCOV_EXCL_LINE
344                 if (ret == -ENODEV || ret == -EINVAL)
345                         return STORAGE_ERROR_INVALID_PARAMETER;
346                 else if (ret == -ENOMEM)
347                         return STORAGE_ERROR_OUT_OF_MEMORY;
348                 else
349                         return STORAGE_ERROR_OPERATION_FAILED;
350         }
351
352         *state = st;
353         return STORAGE_ERROR_NONE;
354 }
355
356 //LCOV_EXCL_START Not called Callback
357 static void compat_cb(int storage_id,
358                 storage_dev_e dev, storage_state_e state,
359                 const char *fstype, const char *fsuuid, const char *mountpath,
360                 bool primary, int flags, void *user_data)
361 {
362         struct compat_cb_info* ccb_info;
363         dd_list *elem;
364
365         if (storage_id == STORAGE_TYPE_EXTERNAL && dev == STORAGE_DEV_EXT_SDCARD)
366                 DD_LIST_FOREACH(compat_cb_list, elem, ccb_info)
367                         ccb_info->user_cb(storage_id, state, ccb_info->user_data);
368 }
369 //LCOV_EXCL_STOP
370
371 API int storage_set_state_changed_cb(int storage_id, storage_state_changed_cb callback, void *user_data)
372 {
373         const struct storage_ops *st;
374         struct storage_cb_info info;
375         int ret;
376         dd_list *elem;
377
378         struct compat_cb_info* ccb_info;
379         static int compat_cb_init = 0;
380
381         if (storage_id < 0)
382                 return STORAGE_ERROR_INVALID_PARAMETER;
383
384         if (!callback) {
385                 _E("Invalid parameger");
386                 return STORAGE_ERROR_INVALID_PARAMETER;
387         }
388
389         /* For backward compatability */
390         if (storage_id == STORAGE_TYPE_EXTERNAL) {
391                 if (!storage_ext_is_supported()) {
392                         _D("Block module is not enabled");
393                         return STORAGE_ERROR_NOT_SUPPORTED;
394                 }
395
396                 if (!compat_cb_init) {
397                         ret = storage_set_changed_cb(STORAGE_TYPE_EXTERNAL, compat_cb, NULL);
398                         if (ret == STORAGE_ERROR_NONE)
399                                 compat_cb_init = 1;
400                         else
401                                 return ret;
402                 }
403
404                 ccb_info = malloc(sizeof(struct compat_cb_info));
405                 if (ccb_info == NULL)
406                         return STORAGE_ERROR_OPERATION_FAILED;
407                 ccb_info->user_cb = callback;
408                 ccb_info->user_data = user_data;
409                 DD_LIST_APPEND(compat_cb_list, ccb_info);
410
411                 return STORAGE_ERROR_NONE;
412         }
413
414         /* Internal storage does not support registering changed callback */
415         DD_LIST_FOREACH(st_int_head, elem, st)
416                 if (st->storage_id == storage_id)
417                         return STORAGE_ERROR_NONE;
418
419         /* external storage */
420         if (!storage_ext_is_supported()) {
421                 _D("Block module is not enabled");
422                 return STORAGE_ERROR_NOT_SUPPORTED;
423         }
424
425         info.id = storage_id;
426         info.state_cb = callback;
427         info.user_data = user_data;
428
429         ret = storage_ext_register_cb(STORAGE_CALLBACK_ID, &info);
430         if (ret < 0) {
431                 _E("Failed to register callback : id(%d)", storage_id); //LCOV_EXCL_LINE
432                 return STORAGE_ERROR_OPERATION_FAILED;
433         }
434
435         return STORAGE_ERROR_NONE;
436 }
437
438 API int storage_unset_state_changed_cb(int storage_id, storage_state_changed_cb callback)
439 {
440         const struct storage_ops *st;
441         struct storage_cb_info info;
442         int ret;
443         dd_list *elem;
444
445         if (storage_id < 0)
446                 return STORAGE_ERROR_INVALID_PARAMETER;
447
448         if (!callback) {
449                 _E("Invalid parameger");
450                 return STORAGE_ERROR_INVALID_PARAMETER;
451         }
452
453         /* For backward compatability */
454         if (storage_id == STORAGE_TYPE_EXTERNAL) {
455                 if (!storage_ext_is_supported()) {
456                         _D("Block module is not enabled");
457                         return STORAGE_ERROR_NOT_SUPPORTED;
458                 }
459
460                 dd_list *elem_n;
461                 struct compat_cb_info* ccb_info;
462
463                 DD_LIST_FOREACH_SAFE(compat_cb_list, elem, elem_n, ccb_info) {
464                         if (ccb_info->user_cb == callback) {
465                                 DD_LIST_REMOVE(compat_cb_list, ccb_info);
466                                 free(ccb_info);
467                                 return STORAGE_ERROR_NONE;
468                         }
469                 }
470                 return STORAGE_ERROR_OPERATION_FAILED;
471         }
472
473         /* Internal storage does not support registering changed callback */
474         DD_LIST_FOREACH(st_int_head, elem, st)
475                 if (st->storage_id == storage_id)
476                         return STORAGE_ERROR_NONE;
477
478         /* external storage */
479         if (!storage_ext_is_supported()) {
480                 _D("Block module is not enabled");
481                 return STORAGE_ERROR_NOT_SUPPORTED;
482         }
483
484         info.id = storage_id;
485         info.state_cb = callback;
486
487         ret = storage_ext_unregister_cb(STORAGE_CALLBACK_ID, &info);
488         if (ret < 0) {
489                 _E("Failed to unregister callback : id(%d)", storage_id); //LCOV_EXCL_LINE
490                 return STORAGE_ERROR_OPERATION_FAILED;
491         }
492
493         return STORAGE_ERROR_NONE;
494 }
495
496 API int storage_get_total_space(int storage_id, unsigned long long *bytes)
497 {
498         const struct storage_ops *st;
499         unsigned long long total;
500         int ret;
501         dd_list *elem;
502
503         if (storage_id < 0)
504                 return STORAGE_ERROR_INVALID_PARAMETER;
505
506         if (!bytes) {
507                 _E("Invalid parameger");
508                 return STORAGE_ERROR_INVALID_PARAMETER;
509         }
510
511         /* internal storage */
512         DD_LIST_FOREACH(st_int_head, elem, st) {
513                 if (st->storage_id != storage_id)
514                         continue;
515                 ret = st->get_space(&total, NULL);
516                 goto out;
517         }
518
519         /* external storage */
520         if (!storage_ext_is_supported()) {
521                 _D("Block module is not enabled");
522                 return STORAGE_ERROR_NOT_SUPPORTED;
523         }
524
525         ret = storage_ext_get_space(storage_id, &total, NULL);
526
527 out:
528         if (ret < 0) {
529                 _E("Failed to get total memory : id(%d)", storage_id); //LCOV_EXCL_LINE
530                 if (ret == -ENODEV || ret == -EINVAL)
531                         return STORAGE_ERROR_INVALID_PARAMETER;
532                 else if (ret == -ENOMEM)
533                         return STORAGE_ERROR_OUT_OF_MEMORY;
534                 else
535                         return STORAGE_ERROR_OPERATION_FAILED;
536         }
537
538         *bytes = total;
539         return STORAGE_ERROR_NONE;
540 }
541
542 API int storage_get_available_space(int storage_id, unsigned long long *bytes)
543 {
544         const struct storage_ops *st;
545         unsigned long long avail;
546         int ret;
547         dd_list *elem;
548
549         if (storage_id < 0)
550                 return STORAGE_ERROR_INVALID_PARAMETER;
551
552         if (!bytes) {
553                 _E("Invalid parameger");
554                 return STORAGE_ERROR_INVALID_PARAMETER;
555         }
556
557         /* internal storage */
558         DD_LIST_FOREACH(st_int_head, elem, st) {
559                 if (st->storage_id != storage_id)
560                         continue;
561                 ret = st->get_space(NULL, &avail);
562                 goto out;
563         }
564
565         /* external storage */
566         if (!storage_ext_is_supported()) {
567                 _D("Block module is not enabled");
568                 return STORAGE_ERROR_NOT_SUPPORTED;
569         }
570
571         ret = storage_ext_get_space(storage_id, NULL, &avail);
572
573 out:
574         if (ret < 0) {
575                 _E("Failed to get available memory : id(%d)", storage_id); //LCOV_EXCL_LINE
576                 if (ret == -ENODEV || ret == -EINVAL)
577                         return STORAGE_ERROR_INVALID_PARAMETER;
578                 else if (ret == -ENOMEM)
579                         return STORAGE_ERROR_OUT_OF_MEMORY;
580                 else
581                         return STORAGE_ERROR_OPERATION_FAILED;
582         }
583
584         *bytes = avail;
585         return STORAGE_ERROR_NONE;
586 }
587
588 API int storage_set_changed_cb(storage_type_e type, storage_changed_cb callback, void *user_data)
589 {
590         int ret;
591         struct storage_cb_info info;
592
593         if (type == STORAGE_TYPE_INTERNAL) {
594                 _E("Internal storage is not supported");
595                 return STORAGE_ERROR_INVALID_PARAMETER;
596         }
597
598         if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
599                 _E("Invalid type (%d)", type);
600                 return STORAGE_ERROR_INVALID_PARAMETER;
601         }
602
603         if (!callback) {
604                 _E("Callback is NULL");
605                 return STORAGE_ERROR_INVALID_PARAMETER;
606         }
607
608         if (!storage_ext_is_supported()) {
609                 _E("Block module is not enabled");
610                 return STORAGE_ERROR_NOT_SUPPORTED;
611         }
612
613         /* external storage */
614         info.type = type;
615         info.type_cb = callback;
616         info.user_data = user_data;
617
618         ret = storage_ext_register_cb(STORAGE_CALLBACK_TYPE, &info);
619         if (ret < 0) {
620                 _E("Failed to register storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
621                 return STORAGE_ERROR_OPERATION_FAILED;
622         }
623
624         return STORAGE_ERROR_NONE;
625 }
626
627 API int storage_unset_changed_cb(storage_type_e type, storage_changed_cb callback)
628 {
629         struct storage_cb_info info;
630         int ret;
631
632         if (type == STORAGE_TYPE_INTERNAL) {
633                 _E("Internal storage is not supported");
634                 return STORAGE_ERROR_INVALID_PARAMETER;
635         }
636
637         if (type != STORAGE_TYPE_EXTERNAL && type != STORAGE_TYPE_EXTENDED_INTERNAL) {
638                 _E("Invalid type (%d)", type);
639                 return STORAGE_ERROR_INVALID_PARAMETER;
640         }
641
642         if (!callback) {
643                 _E("Callback is NULL");
644                 return STORAGE_ERROR_INVALID_PARAMETER;
645         }
646
647         if (!storage_ext_is_supported()) {
648                 _E("Block module is not enabled");
649                 return STORAGE_ERROR_NOT_SUPPORTED;
650         }
651
652         /* external storage */
653         info.type = type;
654         info.type_cb = callback;
655
656         ret = storage_ext_unregister_cb(STORAGE_CALLBACK_TYPE, &info);
657         if (ret < 0) {
658                 _E("Failed to unregister storage callback(ret:%d)", ret); //LCOV_EXCL_LINE
659                 return STORAGE_ERROR_OPERATION_FAILED;
660         }
661
662         return STORAGE_ERROR_NONE;
663 }
664
665 API int storage_get_type_dev(int storage_id, storage_type_e *type, storage_dev_e *dev)
666 {
667         storage_ext_device *ext_dev;
668         int ret;
669
670         if (storage_id < 0 || !type || !dev) {
671                 _E("Invalid parameter");
672                 return STORAGE_ERROR_INVALID_PARAMETER;
673         }
674
675         ret = storage_get_type(storage_id, type);
676         if (ret != STORAGE_ERROR_NONE) {
677                 _E("Failed to get storage type: %d", ret);
678                 return ret;
679         }
680         if (*type == STORAGE_TYPE_INTERNAL || *type == STORAGE_TYPE_EXTENDED_INTERNAL)
681                 return STORAGE_ERROR_INVALID_PARAMETER;
682
683         if (!storage_ext_is_supported()) {
684                 _D("Block module is not enabled");
685                 return STORAGE_ERROR_NOT_SUPPORTED;
686         }
687
688         ext_dev = calloc(1, sizeof(storage_ext_device));
689         if (!ext_dev) {
690                 //LCOV_EXCL_START System Error
691                 _E("calloc failed");
692                 return STORAGE_ERROR_OUT_OF_MEMORY;
693                 //LCOV_EXCL_STOP
694         }
695
696         ret = storage_ext_get_device_info(storage_id, ext_dev);
697         if (ret < 0) {
698                 _E("Cannot get the storage with id (%d, ret:%d)", storage_id, ret); //LCOV_EXCL_LINE
699                 if (ret == -ENODEV) {
700                         ret =  STORAGE_ERROR_INVALID_PARAMETER;
701                         goto out;
702                 }
703                 ret = STORAGE_ERROR_OPERATION_FAILED;
704                 goto out;
705         }
706
707         if (ext_dev->type == STORAGE_EXT_SCSI)
708                 *dev = STORAGE_DEV_EXT_USB_MASS_STORAGE;
709         else if (ext_dev->type == STORAGE_EXT_MMC)
710                 *dev = STORAGE_DEV_EXT_SDCARD;
711         ret = STORAGE_ERROR_NONE;
712         _I("type: %d(internal:0, external:1) dev: %d(sdcard: 1001, usb: 1002)", *type, *dev);
713
714 out:
715         storage_ext_release_device(&ext_dev);
716         return ret;
717 }
718
719 static void __CONSTRUCTOR__ init(void)
720 {
721         const char *tmp;
722         char *token;
723         int i;
724
725         for (i = 0 ; i <= STORAGE_DIRECTORY_OTHERS ; i++) {
726                 tmp = tzplatform_getenv(tz_id[i]);
727                 if (tmp != NULL) {
728                         token = rindex(tmp, '/');
729                         if (token != NULL) {
730                                 token++;
731                                 dir_path[i] = strdup(token);
732                         }
733                 }
734         }
735 }