iPlug2 - C++ Audio Plug-in Framework
Loading...
Searching...
No Matches
IPlugPaths.cpp
Go to the documentation of this file.
1/*
2 ==============================================================================
3
4 This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5
6 See LICENSE.txt for more info.
7
8 ==============================================================================
9*/
10
16#include "IPlugPlatform.h"
17#include "IPlugConstants.h"
18#include "IPlugPaths.h"
19
20#if defined OS_WEB
21#include <emscripten/val.h>
22#elif defined OS_WIN
23#include <windows.h>
24#include <Shlobj.h>
25#include <Shlwapi.h>
26#endif
27
28BEGIN_IPLUG_NAMESPACE
29
30#if defined OS_WIN
31#pragma mark - OS_WIN
32
33 // Helper for getting a known folder in UTF8
34void GetKnownFolder(WDL_String &path, int identifier, int flags = 0)
35{
36 wchar_t wideBuffer[1024];
37
38 SHGetFolderPathW(NULL, identifier, NULL, flags, wideBuffer);
39 UTF16ToUTF8(path, wideBuffer);
40}
41
42static void GetModulePath(HMODULE hModule, WDL_String& path)
43{
44 wchar_t pathCStrW[MAX_WIN32_PATH_LEN] = {'\0'};
45
46 path.Set("");
47
48 if (GetModuleFileNameW(hModule, pathCStrW, MAX_WIN32_PATH_LEN))
49 {
50 UTF16AsUTF8 pathTemp(pathCStrW);
51
52 int s = -1;
53 for (int i = 0; i < strlen(pathTemp.Get()); ++i)
54 {
55 if (pathTemp.Get()[i] == '\\')
56 {
57 s = i;
58 }
59 }
60 if (s >= 0 && s + 1 < strlen(pathTemp.Get()))
61 {
62 path.Set(pathTemp.Get(), s + 1);
63 }
64 }
65}
66
67void HostPath(WDL_String& path, const char* bundleID)
68{
69 GetModulePath(0, path);
70}
71
72void PluginPath(WDL_String& path, HMODULE pExtra)
73{
74 GetModulePath(pExtra, path);
75}
76
77void BundleResourcePath(WDL_String& path, HMODULE pExtra)
78{
79#ifdef VST3_API
80 GetModulePath(pExtra, path);
81#ifdef ARCH_64BIT
82 path.SetLen(path.GetLength() - strlen("x86_64-win/"));
83#else
84 path.SetLen(path.GetLength() - strlen("x86-win/"));
85#endif
86 path.Append("Resources\\");
87#endif
88}
89
90void DesktopPath(WDL_String& path)
91{
92 GetKnownFolder(path, CSIDL_DESKTOP);
93}
94
95void UserHomePath(WDL_String & path)
96{
97 GetKnownFolder(path, CSIDL_PROFILE);
98}
99
100void AppSupportPath(WDL_String& path, bool isSystem)
101{
102 GetKnownFolder(path, isSystem ? CSIDL_COMMON_APPDATA : CSIDL_LOCAL_APPDATA);
103}
104
105void VST3PresetsPath(WDL_String& path, const char* mfrName, const char* pluginName, bool isSystem)
106{
107 if (!isSystem)
108 GetKnownFolder(path, CSIDL_PERSONAL, SHGFP_TYPE_CURRENT);
109 else
110 AppSupportPath(path, true);
111
112 path.AppendFormatted(MAX_WIN32_PATH_LEN, "\\VST3 Presets\\%s\\%s", mfrName, pluginName);
113}
114
115void INIPath(WDL_String& path, const char * pluginName)
116{
117 GetKnownFolder(path, CSIDL_LOCAL_APPDATA);
118
119 path.AppendFormatted(MAX_WIN32_PATH_LEN, "\\%s", pluginName);
120}
121
122void WebViewCachePath(WDL_String& path)
123{
124 GetKnownFolder(path, CSIDL_APPDATA);
125 path.Append("\\iPlug2\\WebViewCache"); // tmp
126}
127
128struct WinResourceSearch
129{
130 WinResourceSearch(const char* name)
131 {
132 UTF16ToUTF8(mName, UTF8AsUTF16(name).ToLowerCase().Get());
133 }
134
135 WDL_String mName;
136 bool mFound = false;
137};
138
139static BOOL CALLBACK EnumResNameProc(HMODULE module, LPCWSTR type, LPWSTR name, LONG_PTR param)
140{
141 if (IS_INTRESOURCE(name))
142 return true; // integer resources not wanted
143 else
144 {
145 WinResourceSearch* search = reinterpret_cast<WinResourceSearch*>(param);
146
147 if (search != nullptr && name != nullptr)
148 {
149 WDL_String searchName(search->mName);
150
151 //strip off extra quotes
152 WDL_String strippedName((UTF16AsUTF8(name).Get() + 1));
153 strippedName.SetLen(strippedName.GetLength() - 1);
154
155 // convert the stripped name to lower case (the search is already lower case)
156 UTF16ToUTF8(strippedName, UTF8AsUTF16(strippedName).ToLowerCase().Get());
157
158 if (strcmp(searchName.Get(), strippedName.Get()) == 0) // if we are looking for a resource with this name
159 {
160 UTF16ToUTF8(search->mName, name);
161 search->mFound = true;
162 return false;
163 }
164 }
165 }
166
167 return true; // keep enumerating
168}
169
170static UTF8AsUTF16 TypeToUpper(const char* type)
171{
172 return UTF8AsUTF16(type).ToUpperCase();
173}
174
175EResourceLocation LocateResource(const char* name, const char* type, WDL_String& result, const char*, void* pHInstance, const char*)
176{
177 if (CStringHasContents(name))
178 {
179 WinResourceSearch search(name);
180 auto typeUpper = TypeToUpper(type);
181
182 HMODULE hInstance = static_cast<HMODULE>(pHInstance);
183
184 EnumResourceNamesW(hInstance, typeUpper.Get(), EnumResNameProc, (LONG_PTR) &search);
185
186 if (search.mFound)
187 {
188 result.Set(search.mName.Get());
189 return EResourceLocation::kWinBinary;
190 }
191 else
192 {
193 if (PathFileExistsW(UTF8AsUTF16(name).Get()))
194 {
195 result.Set(name);
196 return EResourceLocation::kAbsolutePath;
197 }
198 }
199 }
200 return EResourceLocation::kNotFound;
201}
202
203const void* LoadWinResource(const char* resid, const char* type, int& sizeInBytes, void* pHInstance)
204{
205 auto typeUpper = TypeToUpper(type);
206
207 HMODULE hInstance = static_cast<HMODULE>(pHInstance);
208
209 HRSRC hResource = FindResourceW(hInstance, UTF8AsUTF16(resid).Get(), typeUpper.Get());
210
211 if (!hResource)
212 return NULL;
213
214 DWORD size = SizeofResource(hInstance, hResource);
215
216 if (size < 8)
217 return NULL;
218
219 HGLOBAL res = LoadResource(hInstance, hResource);
220
221 const void* pResourceData = LockResource(res);
222
223 if (!pResourceData)
224 {
225 sizeInBytes = 0;
226 return NULL;
227 }
228 else
229 {
230 sizeInBytes = size;
231 return pResourceData;
232 }
233}
234
235#elif defined OS_WEB
236#pragma mark - OS_WEB
237
238void AppSupportPath(WDL_String& path, bool isSystem)
239{
240 path.Set("Settings");
241}
242
243void DesktopPath(WDL_String& path)
244{
245 path.Set("");
246}
247
248void VST3PresetsPath(WDL_String& path, const char* mfrName, const char* pluginName, bool isSystem)
249{
250 path.Set("Presets");
251}
252
253EResourceLocation LocateResource(const char* name, const char* type, WDL_String& result, const char*, void*, const char*)
254{
255 if (CStringHasContents(name))
256 {
257 WDL_String plusSlash;
258 WDL_String path(name);
259 const char* file = path.get_filepart();
260
261 bool foundResource = false;
262
263 //TODO: FindResource is not sufficient here
264
265 if(strcmp(type, "png") == 0) { //TODO: lowercase/uppercase png
266 plusSlash.SetFormatted(strlen("/resources/img/") + strlen(file) + 1, "/resources/img/%s", file);
267 foundResource = emscripten::val::global("preloadedImages").call<bool>("hasOwnProperty", std::string(plusSlash.Get()));
268 }
269 else if(strcmp(type, "ttf") == 0) { //TODO: lowercase/uppercase ttf
270 plusSlash.SetFormatted(strlen("/resources/fonts/") + strlen(file) + 1, "/resources/fonts/%s", file);
271 foundResource = true; // TODO: check ttf
272 }
273 else if(strcmp(type, "svg") == 0) { //TODO: lowercase/uppercase svg
274 plusSlash.SetFormatted(strlen("/resources/img/") + strlen(file) + 1, "/resources/img/%s", file);
275 foundResource = true; // TODO: check svg
276 }
277
278 if(foundResource)
279 {
280 result.Set(plusSlash.Get());
281 return EResourceLocation::kAbsolutePath;
282 }
283 }
284 return EResourceLocation::kNotFound;
285}
286
287#endif
288
289END_IPLUG_NAMESPACE
IPlug Constant definitions, Types, magic numbers.
Common paths useful for plug-ins.
const void * LoadWinResource(const char *resID, const char *type, int &sizeInBytes, void *pHInstance)
Load a resource from the binary (windows only).
void UserHomePath(WDL_String &path)
EResourceLocation LocateResource(const char *fileNameOrResID, const char *type, WDL_String &result, const char *bundleID, void *pHInstance, const char *sharedResourcesSubPath)
Find the absolute path of a resource based on it's file name (e.g.
void VST3PresetsPath(WDL_String &path, const char *mfrName, const char *pluginName, bool isSystem=true)
void PluginPath(WDL_String &path, PluginIDType pExtra)
Get the path to the plug-in binary.
void DesktopPath(WDL_String &path)
void HostPath(WDL_String &path, const char *bundleID=0)
Get the path to the host binary.
void AppSupportPath(WDL_String &path, bool isSystem=false)
void BundleResourcePath(WDL_String &path, PluginIDType pExtra=0)
Get the path to the plug-in bundle resource path.
void INIPath(WDL_String &path, const char *pluginName)
Get the path to the folder where the App's settings.ini file is stored.
void WebViewCachePath(WDL_String &path)
Get the path to the folder where the Plug-in's ICoreWebView2 userdata folder should be (Windows WebVi...
Include to get consistently named preprocessor macros for different platforms and logging functionali...