• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include <dlfcn.h>
10 #include <unistd.h>
11 #include "hdf_log.h"
12 #include "osal_mem.h"
13 #include "securec.h"
14 #include "hdf_load_vdi.h"
15 
16 #define HDF_LOG_TAG dev_load_vdi
17 
18 #ifdef __ARCH64__
19 #define VDI_PATH HDF_LIBRARY_DIR"64/"
20 #else
21 #define VDI_PATH HDF_LIBRARY_DIR"/"
22 #endif
23 
HdfLoadVdi(const char * libName)24 struct HdfVdiObject *HdfLoadVdi(const char *libName)
25 {
26     char path[PATH_MAX + 1] = {0};
27     char resolvedPath[PATH_MAX + 1] = {0};
28 
29     if (libName == NULL) {
30         HDF_LOGE("%{public}s libName is NULL", __func__);
31         return NULL;
32     }
33 
34     if (snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s/%s", VDI_PATH, libName) < 0) {
35         HDF_LOGE("%{public}s %{public}s snprintf_s failed", __func__, libName);
36         return NULL;
37     }
38 
39     if (realpath(path, resolvedPath) == NULL || strncmp(resolvedPath, VDI_PATH, strlen(VDI_PATH)) != 0) {
40         HDF_LOGE("%{public}s %{public}s %{public}s realpath file name failed %{public}d",
41             __func__, path, resolvedPath, errno);
42         return NULL;
43     }
44 
45     struct HdfVdiObject *vdiObj = (struct HdfVdiObject *)OsalMemCalloc(sizeof(*vdiObj));
46     if (vdiObj == NULL) {
47         HDF_LOGE("%{public}s malloc failed", __func__);
48         return NULL;
49     }
50 
51     void *handler = dlopen(resolvedPath, RTLD_LAZY);
52     if (handler == NULL) {
53         HDF_LOGE("%{public}s dlopen failed %{public}s", __func__, dlerror());
54         OsalMemFree(vdiObj);
55         return NULL;
56     }
57 
58     struct HdfVdiBase **vdiBase = (struct HdfVdiBase **)dlsym(handler, "hdfVdiDesc");
59     if (vdiBase == NULL || *vdiBase == NULL) {
60         HDF_LOGE("%{public}s dlsym hdfVdiDesc failed %{public}s", __func__, dlerror());
61         dlclose(handler);
62         OsalMemFree(vdiObj);
63         return NULL;
64     }
65 
66     if ((*vdiBase)->CreateVdiInstance) {
67         (*vdiBase)->CreateVdiInstance(*vdiBase);
68     }
69 
70     vdiObj->dlHandler = (uintptr_t)handler;
71     vdiObj->vdiBase = *vdiBase;
72 
73     return vdiObj;
74 }
75 
HdfGetVdiVersion(const struct HdfVdiObject * vdiObj)76 uint32_t HdfGetVdiVersion(const struct HdfVdiObject *vdiObj)
77 {
78     if (vdiObj == NULL || vdiObj->vdiBase == NULL) {
79         HDF_LOGE("%{public}s para is invalid", __func__);
80         return HDF_INVALID_VERSION;
81     }
82 
83     return vdiObj->vdiBase->moduleVersion;
84 }
85 
HdfCloseVdi(struct HdfVdiObject * vdiObj)86 void HdfCloseVdi(struct HdfVdiObject *vdiObj)
87 {
88     if (vdiObj == NULL || vdiObj->dlHandler == 0 || vdiObj->vdiBase == NULL) {
89         HDF_LOGE("%{public}s para invalid", __func__);
90         return;
91     }
92 
93     struct HdfVdiBase *vdiBase = vdiObj->vdiBase;
94     if (vdiBase->DestoryVdiInstance) {
95         vdiBase->DestoryVdiInstance(vdiBase);
96     }
97 
98     dlclose((void *)vdiObj->dlHandler);
99     vdiObj->dlHandler = 0;
100     vdiObj->vdiBase = NULL;
101     OsalMemFree(vdiObj);
102 }
103 
104