2 * FreeRDP: A Remote Desktop Protocol Implementation
5 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
28 #include <winpr/crt.h>
29 #include <winpr/path.h>
30 #include <winpr/library.h>
32 #include <freerdp/addin.h>
34 LPCSTR gAddinPath = FREERDP_ADDIN_PATH;
35 LPCSTR gLibraryPath = FREERDP_LIBRARY_PATH;
36 LPCSTR gInstallPrefix = FREERDP_INSTALL_PREFIX;
38 LPSTR freerdp_get_library_install_path()
42 size_t cchLibraryPath;
43 size_t cchInstallPrefix;
45 cchLibraryPath = strlen(gLibraryPath);
46 cchInstallPrefix = strlen(gInstallPrefix);
48 cchPath = cchInstallPrefix + cchLibraryPath + 2;
49 pszPath = (LPSTR) malloc(cchPath + 1);
51 CopyMemory(pszPath, gInstallPrefix, cchInstallPrefix);
52 pszPath[cchInstallPrefix] = '\0';
54 NativePathCchAppendA(pszPath, cchPath + 1, gLibraryPath);
59 LPSTR freerdp_get_dynamic_addin_install_path()
64 size_t cchInstallPrefix;
66 cchAddinPath = strlen(gAddinPath);
67 cchInstallPrefix = strlen(gInstallPrefix);
69 cchPath = cchInstallPrefix + cchAddinPath + 2;
70 pszPath = (LPSTR) malloc(cchPath + 1);
72 CopyMemory(pszPath, gInstallPrefix, cchInstallPrefix);
73 pszPath[cchInstallPrefix] = '\0';
75 NativePathCchAppendA(pszPath, cchPath + 1, gAddinPath);
80 void* freerdp_load_dynamic_addin(LPCSTR pszFileName, LPCSTR pszPath, LPCSTR pszEntryName)
92 LPSTR pszAddinInstallPath;
93 size_t cchAddinInstallPath;
98 cchFileName = strlen(pszFileName);
100 if (PathCchFindExtensionA(pszFileName, cchFileName + 1, &pszExt) != S_OK)
102 pszExt = PathGetSharedLibraryExtensionA(PATH_SHARED_LIB_EXT_WITH_DOT);
103 cchExt = strlen(pszExt);
107 pszAddinInstallPath = freerdp_get_dynamic_addin_install_path();
108 cchAddinInstallPath = strlen(pszAddinInstallPath);
110 cchFilePath = cchAddinInstallPath + cchFileName + 32;
111 pszFilePath = (LPSTR) malloc(cchFilePath + 1);
115 pszAddinFile = _strdup(pszFileName);
116 cchAddinFile = strlen(pszAddinFile);
120 cchAddinFile = cchFileName + cchExt + 2;
121 pszAddinFile = (LPSTR) malloc(cchAddinFile + 1);
122 sprintf_s(pszAddinFile, cchAddinFile, "%s%s", pszFileName, pszExt);
123 cchAddinFile = strlen(pszAddinFile);
126 CopyMemory(pszFilePath, pszAddinInstallPath, cchAddinInstallPath);
127 pszFilePath[cchAddinInstallPath] = '\0';
129 NativePathCchAppendA((LPSTR) pszFilePath, cchFilePath + 1, pszAddinFile);
131 library = LoadLibraryA(pszFilePath);
133 free(pszAddinInstallPath);
140 entry = GetProcAddress(library, pszEntryName);
148 void* freerdp_load_dynamic_channel_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
155 pszExtension = PathGetSharedLibraryExtensionA(0);
157 if (pszName && pszSubsystem && pszType)
159 cchFileName = strlen(pszName) + strlen(pszSubsystem) + strlen(pszType) + strlen(pszExtension) + 32;
160 pszFileName = (LPSTR) malloc(cchFileName);
161 sprintf_s(pszFileName, cchFileName, "%s-client-%s-%s.%s", pszName, pszSubsystem, pszType, pszExtension);
162 cchFileName = strlen(pszFileName);
164 else if (pszName && pszSubsystem)
166 cchFileName = strlen(pszName) + strlen(pszSubsystem) + strlen(pszExtension) + 32;
167 pszFileName = (LPSTR) malloc(cchFileName);
168 sprintf_s(pszFileName, cchFileName, "%s-client-%s.%s", pszName, pszSubsystem, pszExtension);
169 cchFileName = strlen(pszFileName);
173 cchFileName = strlen(pszName) + strlen(pszExtension) + 32;
174 pszFileName = (LPSTR) malloc(cchFileName);
175 sprintf_s(pszFileName, cchFileName, "%s-client.%s", pszName, pszExtension);
176 cchFileName = strlen(pszFileName);
188 /* subsystem add-in */
190 cchEntryName = 64 + strlen(pszName);
191 pszEntryName = (LPSTR) malloc(cchEntryName + 1);
192 sprintf_s(pszEntryName, cchEntryName + 1, "freerdp_%s_client_subsystem_entry", pszName);
194 entry = freerdp_load_dynamic_addin(pszFileName, NULL, pszEntryName);
203 if (dwFlags & FREERDP_ADDIN_CHANNEL_STATIC)
204 entry = freerdp_load_dynamic_addin(pszFileName, NULL, "VirtualChannelEntry");
205 else if (dwFlags & FREERDP_ADDIN_CHANNEL_DYNAMIC)
206 entry = freerdp_load_dynamic_addin(pszFileName, NULL, "DVCPluginEntry");
207 else if (dwFlags & FREERDP_ADDIN_CHANNEL_DEVICE)
208 entry = freerdp_load_dynamic_addin(pszFileName, NULL, "DeviceServiceEntry");
210 entry = freerdp_load_dynamic_addin(pszFileName, NULL, pszType);
219 static FREERDP_LOAD_CHANNEL_ADDIN_ENTRY_FN freerdp_load_static_channel_addin_entry = NULL;
221 int freerdp_register_addin_provider(FREERDP_LOAD_CHANNEL_ADDIN_ENTRY_FN provider, DWORD dwFlags)
223 freerdp_load_static_channel_addin_entry = provider;
227 void* freerdp_load_channel_addin_entry(LPCSTR pszName, LPSTR pszSubsystem, LPSTR pszType, DWORD dwFlags)
231 if (freerdp_load_static_channel_addin_entry)
232 entry = freerdp_load_static_channel_addin_entry(pszName, pszSubsystem, pszType, dwFlags);
235 entry = freerdp_load_dynamic_channel_addin_entry(pszName, pszSubsystem, pszType, dwFlags);