xoblite™ / Blackbox for Windows bb5 | RC6 preview | 0.25.2.14
http://xoblite.net/
PluginManager Class Reference

#include <PluginManager.h>

Public Member Functions

 PluginManager (HINSTANCE)
 
 ~PluginManager ()
 
bool LoadPlugin (LPSTR pluginPath)
 
bool StartPlugin (HMODULE hModule, LPSTR pluginPath, bool dockingEnabled)
 
void UnloadPlugin (LPSTR pluginPath, int pluginNumber)
 
void UpdatePlugin (LPSTR pluginPath, int pluginNumber, bool forceUpdate)
 
void AboutPlugins ()
 
LPCSTR GetPluginInfo (int pluginNumber, int infoParam)
 
bool WritePluginsRC ()
 
void LoadPluginDialog ()
 
bool IsPluginLoaded (LPSTR pluginPath)
 

Public Attributes

PluginsVector pluginList
 
bool startupLock
 
char pluginName [MAX_LINE_LENGTH]
 
HINSTANCE hModule
 
beginPluginExFunc beginPluginEx
 
beginPluginFunc beginPlugin
 
beginSlitPluginFunc beginSlitPlugin
 
endPluginFunc endPlugin
 
pluginInfoFunc pluginInfo
 

Constructor & Destructor Documentation

◆ PluginManager()

PluginManager::PluginManager ( HINSTANCE hMainInstance)
50{
51 char szBuffer[MAX_LINE_LENGTH]="";
52
53 startupLock = true;
54
55 // SAFE MODE: Hold down control to disable loading of plugins at startup
56 // ### Beware! -> Do not load any plugins when running in safe mode or you
57 // will overwrite the contents of your plugins.rc! ###
58 if (!(GetAsyncKeyState(VK_CONTROL) & 0x8000))
59 {
60 FILE *f = FileOpen(plugrcPath());
61 while (ReadNextCommand(f, szBuffer, sizeof(szBuffer))) LoadPlugin(szBuffer);
62 FileClose(f);
63 }
64 else SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_WARNING_MESSAGE, (LPARAM)"Safe mode: Holding down the Ctrl key disables loading of plugins at startup.");
65
66 //====================
67
68 if (!pluginList.empty())
69 {
70 char szCurrentPlugin[MAX_LINE_LENGTH] = "", szPreviousPlugin[MAX_LINE_LENGTH] = "";
71 char szMultiplier[10];
72 int numberOfInstances = 1;
73
74 // Display the names of all loaded plugins in the console...
75 // (nb. grouped together if more than one plugin of the same name is loaded in succession)
76 strcpy(szBuffer, "Loading plugins -> ");
77 for (int i=0; i < (int)pluginList.size(); i++)
78 {
79 pluginInfo = (pluginInfoFunc)GetProcAddress(pluginList[i].hModule, "pluginInfo");
80 if (pluginInfo)
81 {
82 strcpy(szCurrentPlugin, pluginInfo(PLUGIN_NAME));
83
84 if (!_stricmp(szCurrentPlugin, szPreviousPlugin))
85 {
86 numberOfInstances++;
87 continue;
88 }
89 else
90 {
91 if (numberOfInstances > 1)
92 {
93 sprintf(szMultiplier, " x %d", numberOfInstances);
94 strcat(szBuffer, szMultiplier);
95 numberOfInstances = 1;
96 }
97
98 if (i > 0) strcat(szBuffer, " | ");
99 strcat(szBuffer, szCurrentPlugin);
100
101 strcpy(szPreviousPlugin, szCurrentPlugin);
102 }
103 }
104 else // Extract name from file name...
105 {
106 char pluginName[MAX_PATH];
107 strcpy(pluginName, pluginList[i].path);
109 strcpy(pluginName, &pluginList[i].path[n]);
110 PathRemoveExtension(pluginName);
111 if (i > 0) strcat(szBuffer, " | ");
112 strcat(szBuffer, pluginName);
113 }
114 }
115
116 if (numberOfInstances > 1)
117 {
118 sprintf(szMultiplier, " x %d", numberOfInstances);
119 strcat(szBuffer, szMultiplier);
120 }
121
122 SendMessage(GetBBWnd(), BB_CONSOLEMESSAGE, (WPARAM)CONSOLE_REGULAR_MESSAGE, (LPARAM)szBuffer);
123 }
124
125 //====================
126
127 startupLock = false;
129
130 // Automatic checking for updates at startup? (note: call later moved to Blackbox.cpp, kept here only for reference)
131// if (_stricmp(pSettings->checkedForUpdates, "*Disabled*")) _beginthread(periodicCheckForUpdates, 0, NULL);
132}
FILE * FileOpen(LPCSTR szPath)
Definition BBApi.cpp:239
bool ReadNextCommand(FILE *f, LPSTR szBuffer, DWORD dwLength)
Definition BBApi.cpp:713
LPCSTR plugrcPath(LPCSTR other)
Definition BBApi.cpp:900
int GetParentFolder(LPSTR path)
Definition BBApi.cpp:3853
Settings * pSettings
Definition Blackbox.cpp:46
bool FileClose(FILE *fp)
Definition BBApi.cpp:254
HWND GetBBWnd()
Definition BBApi.cpp:128
#define PLUGIN_NAME
Definition BBApi.h:266
#define BB_CONSOLEMESSAGE
Definition BBApi.h:165
#define CONSOLE_REGULAR_MESSAGE
Definition BBApi.h:297
#define MAX_LINE_LENGTH
Definition BBApi.h:64
#define CONSOLE_WARNING_MESSAGE
Definition BBApi.h:299
LPCSTR(* pluginInfoFunc)(int)
Definition PluginManager.h:51
pluginInfoFunc pluginInfo
Definition PluginManager.h:95
char pluginName[MAX_LINE_LENGTH]
Definition PluginManager.h:87
bool startupLock
Definition PluginManager.h:86
bool LoadPlugin(LPSTR pluginPath)
Definition PluginManager.cpp:150
PluginsVector pluginList
Definition PluginManager.h:84
HINSTANCE hModule
Definition PluginManager.h:90
bool checkingForUpdates
Definition Settings.h:391

◆ ~PluginManager()

PluginManager::~PluginManager ( )
137{
138 for (int i=0; i < (int)pluginList.size(); i++)
139 {
140 endPlugin = (endPluginFunc)GetProcAddress(pluginList[i].hModule, "endPlugin");
142 FreeLibrary(pluginList[i].hModule);
143 }
144
145 pluginList.clear();
146}
int(* endPluginFunc)(HINSTANCE)
Definition PluginManager.h:50
endPluginFunc endPlugin
Definition PluginManager.h:94

Member Function Documentation

◆ LoadPlugin()

bool PluginManager::LoadPlugin ( LPSTR pluginPath)
151{
152 char msg[MAX_LINE_LENGTH];
153
154 //====================
155
156 if (strchr(pluginPath, '\"')) StrRemoveEncap(pluginPath);
157 if (strchr(pluginPath, '$')) ReplaceShellFolders(pluginPath);
158 if (strchr(pluginPath, '%')) ReplaceEnvVars(pluginPath);
159
160 if (IsInString(pluginPath, "BBSystemBar.dll") || // Do not load the BBSystemBar plugin (integrated functionality in xoblite)
161 IsInString(pluginPath, "BBSystemBarEx.dll") || // Do not load the BBSystemBarEx plugin (similar to integrated functionality in xoblite)
162 IsInString(pluginPath, "SystemBarEx.dll") || // Do not load the SystemBarEx plugin (similar to integrated functionality in xoblite)
163 IsInString(pluginPath, "BBSlit.dll") || // Do not load the BBSlit plugin (integrated functionality in xoblite)
164 IsInString(pluginPath, "BBKeys.dll") || // Do not load the BBKeys plugin (integrated functionality in xoblite)
165 IsInString(pluginPath, "RandomStyle.dll") || // Do not load the RandomStyle plugin (integrated functionality in xoblite)
166 IsInString(pluginPath, "BBDDE.dll")) // Do not load the BBDDE plugin (integrated functionality in xoblite)
167 {
168 strcpy(msg, "The following plugins are automatically excluded \n"
169 "because the functionality they provide (or similar \n"
170 "functionality) is already part of xoblite itself: \n\n"
171 "BBSystemBar\nBBSystemBarEx/SystemBarEx\nBBSlit\nBBKeys\nRandomStyle\nBBDDE \n");
172 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_ICONINFORMATION | MB_TOPMOST);
173 return false;
174 }
175
176 //====================
177
178 // Check if this particular plugin has already been loaded...
179
180 char dllName[MAX_LINE_LENGTH], dllTempName[MAX_LINE_LENGTH];
181 strcpy(dllName, pluginPath);
182 int nLen = strlen(dllName) - 1;
183 if (IsInString(dllName, "/")) while (nLen >0 && dllName[nLen] != '/') nLen--;
184 else while (nLen >0 && dllName[nLen] != '\\') nLen--;
185 strcpy(dllName, &pluginPath[nLen+1]);
186
187 for (int i=0; i < (int)pluginList.size(); i++)
188 {
189 strcpy(dllTempName, pluginList[i].path);
190 nLen = strlen(dllTempName) - 1;
191 if (IsInString(dllTempName, "/")) while ((nLen > 0) && (dllTempName[nLen] != '/')) nLen--;
192 else while ((nLen > 0) && (dllTempName[nLen] != '\\')) nLen--;
193 strcpy(dllTempName, &pluginList[i].path[nLen+1]);
194
195 if (!_stricmp(dllName, dllTempName))
196 {
197 strcpy(msg, pluginPath);
198 strcat(msg, " \n\nThis plugin is already loaded. ");
199 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_ICONINFORMATION | MB_TOPMOST);
200 return false;
201 }
202 }
203
204 //====================
205
206 bool dockingEnabled;
207
208 if (pluginPath[0] == '&') // dock plugin?
209 {
210 dockingEnabled = true;
211 hModule = LoadLibrary(&pluginPath[1]);
212 }
213 else // normal plugin
214 {
215 dockingEnabled = false;
216 hModule = LoadLibrary(pluginPath);
217 }
218
219 if (hModule)
220 {
221 if (StartPlugin(hModule, pluginPath, dockingEnabled))
222 {
223 pluginItem plg;
224 plg.hModule = hModule;
225 plg.DockingEnabled = dockingEnabled;
226 strcpy(plg.path, pluginPath);
227 plg.UpdateAvailable = false;
228 pluginList.push_back(plg);
229
230 if (IsInString(pluginPath, "xDesignerGUI.dll")) pSettings->designerModeEnabled = true; // Safeguard ;)
231
232// if (!startupLock) // ...writing to plugins.rc during startup is not a good idea... <g>
233 else if (!startupLock) // ...writing to plugins.rc during startup is not a good idea... <g>
234 {
235 if (!WritePluginsRC()) MessageBox(GetBBWnd(), "Could not write to plugins.rc!", "xoblite", MB_OK | MB_ICONERROR | MB_TOPMOST);
236 }
237
238 return true;
239 }
240 }
241 else
242 {
243 strcpy(msg, pluginPath);
244 strcat(msg, " (LoadLibrary failed)");
245 Log("Plugin error", msg);
246 strcpy(msg, pluginPath);
247 strcat(msg, " \n\nThe plugin you are trying to load does not exist, \nor is not compatible with your operating system. \n\nPlease check your plugin configuration file. ");
248 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_ICONERROR | MB_TOPMOST);
249 }
250
251 return false;
252}
bool IsInString(LPCSTR inputString, LPCSTR searchString)
Definition BBApi.cpp:2519
LPSTR StrRemoveEncap(LPSTR string)
Definition BBApi.cpp:406
void Log(LPCSTR des, LPCSTR line)
Definition BBApi.cpp:638
void ReplaceEnvVars(LPSTR string)
Definition BBApi.cpp:2594
void ReplaceShellFolders(LPSTR string)
Definition BBApi.cpp:2633
bool WritePluginsRC()
Definition PluginManager.cpp:1005
bool StartPlugin(HMODULE hModule, LPSTR pluginPath, bool dockingEnabled)
Definition PluginManager.cpp:256
bool designerModeEnabled
Definition Settings.h:330
bool DockingEnabled
Definition PluginManager.h:57
HMODULE hModule
Definition PluginManager.h:55
bool UpdateAvailable
Definition PluginManager.h:58
char path[MAX_LINE_LENGTH]
Definition PluginManager.h:56

◆ StartPlugin()

bool PluginManager::StartPlugin ( HMODULE hModule,
LPSTR pluginPath,
bool dockingEnabled )
257{
258 beginPluginEx = (beginPluginExFunc)GetProcAddress(hModule, "beginPluginEx");
259 beginPlugin = (beginPluginFunc)GetProcAddress(hModule, "beginPlugin");
260 beginSlitPlugin = (beginSlitPluginFunc)GetProcAddress(hModule, "beginSlitPlugin");
261 endPlugin = (endPluginFunc)GetProcAddress(hModule, "endPlugin");
262
264 {
265 FreeLibrary(hModule);
266 char msg[MAX_LINE_LENGTH];
267 strcpy(msg, pluginPath);
268 strcat(msg, " (entry point missing)");
269 Log("Plugin failed", msg);
270 strcpy(msg, pluginPath);
271 strcat(msg, " \n\nThe plugin you are trying to load is \nmissing the necessary entry point. \n\nPlease contact the plugin author. ");
272 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_ICONERROR | MB_TOPMOST);
273 return false;
274 }
275
276 if (!endPlugin)
277 {
278 FreeLibrary(hModule);
279 char msg[MAX_LINE_LENGTH];
280 strcpy(msg, pluginPath);
281 strcat(msg, " (exit point missing)");
282 Log("Plugin failed", msg);
283 strcpy(msg, pluginPath);
284 strcat(msg, " \n\nThe plugin you are trying to load is \nmissing the necessary exit point. \n\nPlease contact the plugin author. ");
285 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_ICONERROR | MB_TOPMOST);
286 return false;
287 }
288
289 // Show plugins if they are hidden and we're not starting up...
290 // (needed for visibility consistency when loading a new plugin)
291 if (pSettings->pluginsHidden && !startupLock && !IsInString(pluginPath, "xDesignerGUI.dll")) PostMessage(GetBBWnd(), BB_TOGGLEPLUGINS, 0, 0);
292
293 //====================
294
295 try
296 {
297 if (pDock)
298 {
300 else if (beginSlitPlugin && dockingEnabled) beginSlitPlugin(hModule, pDock->hDockWnd);
303 }
305 }
306 catch (...)
307 {
308 FreeLibrary(hModule);
309 char msg[MAX_LINE_LENGTH];
310 strcpy(msg, pluginPath);
311 strcat(msg, " (try/catch exception)");
312 Log("Plugin failed", msg);
313 strcpy(msg, pluginPath);
314 strcat(msg, " \n\nThe plugin you are trying to load has failed. \n\nPlease contact the plugin author. ");
315 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_ICONERROR | MB_TOPMOST);
316 return false;
317 }
318
319 //====================
320
321 return true;
322}
#define BB_TOGGLEPLUGINS
Definition BBApi.h:167
Dock * pDock
Definition Blackbox.cpp:38
int(* beginSlitPluginFunc)(HINSTANCE, HWND)
Definition PluginManager.h:49
int(* beginPluginExFunc)(HINSTANCE, HWND)
Definition PluginManager.h:47
int(* beginPluginFunc)(HINSTANCE)
Definition PluginManager.h:48
HWND hDockWnd
Definition Dock.h:86
beginSlitPluginFunc beginSlitPlugin
Definition PluginManager.h:93
beginPluginFunc beginPlugin
Definition PluginManager.h:92
beginPluginExFunc beginPluginEx
Definition PluginManager.h:91
bool pluginsHidden
Definition Settings.h:315

◆ UnloadPlugin()

void PluginManager::UnloadPlugin ( LPSTR pluginPath,
int pluginNumber )
327{
328 if (pluginNumber != -1)
329 {
330 endPlugin = (endPluginFunc)GetProcAddress(pluginList[pluginNumber].hModule, "endPlugin");
331 endPlugin(pluginList[pluginNumber].hModule);
332 FreeLibrary(pluginList[pluginNumber].hModule);
333
334 if (IsInString(pluginList[pluginNumber].path, "xDesignerGUI.dll")) pSettings->designerModeEnabled = false; // Safeguard ;)
335
336 pluginList.erase(pluginList.begin() + pluginNumber);
337
338 if (!WritePluginsRC()) MessageBox(GetBBWnd(), "Could not write to plugins.rc!", "xoblite", MB_OK | MB_ICONERROR | MB_TOPMOST);
339
340 return;
341 }
342
343 //====================
344
345 if (strchr(pluginPath, '\"')) StrRemoveEncap(pluginPath);
346 if (strchr(pluginPath, '$')) ReplaceShellFolders(pluginPath);
347 if (strchr(pluginPath, '%')) ReplaceEnvVars(pluginPath);
348
349 char dllName[MAX_LINE_LENGTH], dllTempName[MAX_LINE_LENGTH];
350 int nLen;
351
352 // Extract the name of the .dll to unload (disregard the full path)...
353 strcpy(dllName, pluginPath);
354 nLen = strlen(dllName) - 1;
355 if (strchr(dllName, '/')) while (nLen >0 && dllName[nLen] != '/') nLen--;
356 else while (nLen >0 && dllName[nLen] != '\\') nLen--;
357 strcpy(dllName, &pluginPath[nLen+1]);
358
359 //====================
360
361 for (int i=0; i < (int)pluginList.size(); i++)
362 {
363 // Extract the name of the current .dll (disregard the full path)...
364 strcpy(dllTempName, pluginList[i].path);
365 nLen = strlen(dllTempName) - 1;
366 if (strchr(dllName, '/')) while (nLen >0 && dllTempName[nLen] != '/') nLen--;
367 else while (nLen >0 && dllTempName[nLen] != '\\') nLen--;
368 strcpy(dllTempName, &pluginList[i].path[nLen+1]);
369
370 // Is the current plugin the plugin we wish to unload?
371 if (!_stricmp(dllName, dllTempName))
372 {
373 endPlugin = (endPluginFunc)GetProcAddress(pluginList[i].hModule, "endPlugin");
375 FreeLibrary(pluginList[i].hModule);
376
377 if (IsInString(pluginPath, "xDesignerGUI.dll")) pSettings->designerModeEnabled = false; // Safeguard ;)
378
379 pluginList.erase(pluginList.begin() + i);
380
381 if (!WritePluginsRC()) MessageBox(GetBBWnd(), "Could not write to plugins.rc!", "xoblite", MB_OK | MB_ICONERROR | MB_TOPMOST);
382
383 return;
384 }
385 }
386/*
387 char msg[MAX_LINE_LENGTH];
388 strcpy(msg, pluginPath);
389 strcat(msg, " \n\nThe plugin you were trying to unload was not found running. ");
390 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_ICONERROR | MB_TOPMOST);
391*/
392}

◆ UpdatePlugin()

void PluginManager::UpdatePlugin ( LPSTR pluginPath,
int pluginNumber,
bool forceUpdate )
397{
398 if (pSettings->checkingForUpdates) return;
399
400 char msg[MAX_LINE_LENGTH], temp[MAX_LINE_LENGTH], path[MAX_LINE_LENGTH];
401
402 // Make sure the updates metafile exists...
403 GetBlackboxPath(path, sizeof(path));
404 strcat(path, "update.log");
405 if (!FileExists(path) || forceUpdate)
406 {
407 bool silent = true;
408 _beginthread(checkForUpdates, 0, &silent);
409 }
410
411 //====================
412
413 // Display "<->" icon in toolbar.windowLabel -> update in progress!
415// if ((pSettings->toolbarMode == TOOLBAR_MODE_WINDOWLABEL) && pToolbar) pToolbar->UpdateToolbarWindow();
416
417 //====================
418
419 if (pluginNumber != -1)
420 {
421 pluginInfo = (pluginInfoFunc)GetProcAddress(pluginList[pluginNumber].hModule, "pluginInfo");
422 if (pluginInfo)
423 {
424 if (FileExists(path))
425 {
426 char plugin[MAX_LINE_LENGTH], parameter[MAX_LINE_LENGTH];
427 char onlineVersion[MAX_LINE_LENGTH], currentVersion[MAX_LINE_LENGTH];
428 char onlineDate[MAX_LINE_LENGTH], currentDate[MAX_LINE_LENGTH];
429
430 strcpy(plugin, pluginInfo(PLUGIN_NAME));
431 strcpy(currentVersion, pluginInfo(PLUGIN_VERSION));
432 strcpy(currentDate, pluginInfo(PLUGIN_RELEASEDATE));
433
434 sprintf(parameter, "%s.version:", plugin);
435 strcpy(onlineVersion, ReadString(path, parameter, ""));
436 if (!strlen(onlineVersion))
437 {
438 pluginList[pluginNumber].UpdateAvailable = false;
439 strcpy(temp, pluginInfo(PLUGIN_UPDATE_URL));
440 if (!IsInString(temp, "http://")) strcpy(temp, pSettings->pluginsRepository);
441 sprintf(msg, "%s \n\n%s is not supported by the specified repository! ", temp, plugin);
442 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_SETFOREGROUND | MB_ICONERROR);
443 return;
444 }
445 sprintf(parameter, "%s.date:", plugin);
446 strcpy(onlineDate, ReadString(path, parameter, "xxxx-xx-xx"));
447
448 //====================
449
450 // Check if online version/date differs from the current version/date...
451 if (!_stricmp(currentDate, onlineDate))
452 {
453 if (!_stricmp(currentVersion, onlineVersion))
454 {
455 pluginList[pluginNumber].UpdateAvailable = false;
456 sprintf(msg, "You are already using the latest version of %s. ", plugin);
457 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_SETFOREGROUND | MB_ICONINFORMATION);
458 return;
459 }
460 }
461
462 //====================
463
464 sprintf(msg, "%s update found!\n\nCurrent version:\t %s \t%s \nOnline version:\t %s \t%s ", plugin, currentVersion, currentDate, onlineVersion, onlineDate);
465
466 sprintf(parameter, "%s.changes:", plugin);
467 strcpy(temp, ReadString(path, parameter, ""));
468 if (strlen(temp))
469 {
470 strcat(msg, "\n\nUpdate information:\n");
471 strcat(msg, temp);
472 }
473
474 strcat(msg, "\n\nDo you want to download this update? ");
475
476 //====================
477
478 if (MessageBox(GetBBWnd(), msg, "xoblite", MB_YESNO | MB_ICONQUESTION | MB_SETFOREGROUND | MB_TOPMOST) == IDYES)
479 {
480 int nLen;
481 char token[MAX_LINE_LENGTH], extra[MAX_LINE_LENGTH], filename[MAX_LINE_LENGTH], pluginPath[MAX_LINE_LENGTH];
482 char savedfiles[MAX_LINE_LENGTH] = "";
483 LPSTR tokens[1];
484 tokens[0] = token;
485
486 // Copy the path to the plugin + the URL...
487 bool dllFound = false, zipFound = false;
488
489 if (!strstr(pluginList[pluginNumber].path, ":\\"))
490 {
491 // Make sure we use the full path of the plugin and
492 // not just a path relative to the Blackbox folder...
494 strcat(filename, pluginList[pluginNumber].path);
495 }
496 else strcpy(filename, pluginList[pluginNumber].path);
497
498 sprintf(parameter, "%s.files:", plugin);
499 strcpy(temp, ReadString(path, parameter, ""));
500 if (!strlen(temp))
501 {
502 // Download the plugin .zip archive if no
503 // list of updated files was specified...
504 sprintf(parameter, "%s.archive:", plugin);
505 strcpy(temp, ReadString(path, parameter, ""));
506 }
507
508 if (IsInString(temp, ".dll")) dllFound = true;
509 else if (IsInString(temp, ".zip")) zipFound = true;
510
511 if (!dllFound && !zipFound)
512 {
513 // Neither an archive (.zip) nor individual files (including at least one .dll)
514 // was directly linked to -> Open the link in the user's default browser...
515 if (IsInString(temp, "http")) BBSmartExecute(temp);
516 else
517 {
518 sprintf(msg, "Invalid update link detected for %s: \n\n%s ", plugin, temp);
519 if (strlen(temp) == 0) strcat(msg, "<empty> ");
520 strcat(msg, "\n\nUpdate request aborted. Click OK to continue.");
521 MessageBox(GetBBWnd(), msg, "Error updating plugin!", MB_ICONERROR | MB_SETFOREGROUND | MB_TOPMOST);
522 }
523 return;
524 }
525
526 if (dllFound)
527 {
528 // Unload the plugin...
529 strcpy(pluginPath, pluginList[pluginNumber].path);
530 endPlugin = (endPluginFunc)GetProcAddress(pluginList[pluginNumber].hModule, "endPlugin");
531 endPlugin(pluginList[pluginNumber].hModule);
532 FreeLibrary(pluginList[pluginNumber].hModule);
533 pluginList.erase(pluginList.begin() + pluginNumber);
534 }
535
536 // Download the updated files...
537 while(strlen(temp))
538 {
539 token[0] = extra[0] = '\0';
540 BBTokenize (temp, tokens, 1, extra);
541 strcpy(temp, extra);
542
543 // Extract the plugin folder from the plugin path...
544 nLen = strlen(filename) - 1;
545 if (IsInString(filename, "/")) while (nLen >0 && filename[nLen] != '/') nLen--;
546 else while (nLen >0 && filename[nLen] != '\\') nLen--;
547 filename[nLen + 1] = 0;
548
549 // Extract the name of the file from the URL...
550 nLen = strlen(token) - 1;
551 while (nLen >0 && token[nLen] != '/') nLen--;
552 strcat(filename, &token[nLen+1]);
553
554 // Download the file and save it in the plugin folder...
555 DownloadFile(token, filename);
556
557 // Copy the path of the saved file to the list of updated files...
558 strcat(savedfiles, "\n");
559 strcat(savedfiles, filename);
560 strcat(savedfiles, " ");
561 }
562
563 if (dllFound)
564 {
565 // Reload the plugin...
566 bool dockingEnabled;
567
568 if (pluginPath[0] == '&') // dock plugin?
569 {
570 dockingEnabled = true;
571 hModule = LoadLibrary(&pluginPath[1]);
572 }
573 else // normal plugin
574 {
575 dockingEnabled = false;
576 hModule = LoadLibrary(pluginPath);
577 }
578
579 if (hModule)
580 {
581 if (StartPlugin(hModule, pluginPath, dockingEnabled))
582 {
583 pluginItem plg;
584 plg.hModule = hModule;
585 plg.DockingEnabled = dockingEnabled;
586 strcpy(plg.path, pluginPath);
587 plg.UpdateAvailable = false;
588 pluginList.insert(pluginList.begin() + pluginNumber, plg);
589 }
590 }
591 else return;
592
593 sprintf(msg, "%s update downloaded and installed. \n%s", plugin, savedfiles);
594 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_SETFOREGROUND | MB_TOPMOST | MB_ICONINFORMATION);
595 }
596 else if (zipFound)
597 {
598 sprintf(msg, "%s update in .zip format downloaded, \nsee archive for further instructions. \n%s", plugin, savedfiles);
599 if (MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_SETFOREGROUND | MB_TOPMOST | MB_ICONINFORMATION))
600 {
601 char arg[MAX_LINE_LENGTH];
602 strcpy(arg, "/e,/select,");
603 strcat(arg, savedfiles);
604 BBExecute(GetDesktopWindow(), NULL, "explorer.exe", arg, NULL, SW_SHOWNORMAL, false);
605 return;
606 }
607 }
608 else
609 {
610 sprintf(msg, "%s update downloaded. \n%s", plugin, savedfiles);
611 MessageBox(GetBBWnd(), msg, "xoblite", MB_OK | MB_SETFOREGROUND | MB_TOPMOST | MB_ICONINFORMATION);
612 }
613 }
614
615 // Turn off the "update available" indicator...
616 pluginList[pluginNumber].UpdateAvailable = false;
617 }
618 else MessageBox(GetBBWnd(), "Could not find the updates metafile! [update.log] ", "xoblite", MB_OK | MB_SETFOREGROUND | MB_TOPMOST | MB_ICONERROR);
619 }
620 else MessageBox(GetBBWnd(), "This plugin does not support automatic updating. ", "xoblite", MB_OK | MB_SETFOREGROUND | MB_TOPMOST | MB_ICONERROR);
621 }
622
623 // Remove "<->" icon from toolbar.windowLabel -> update no longer in progress
625// if ((pSettings->toolbarMode == TOOLBAR_MODE_WINDOWLABEL) && pToolbar) pToolbar->UpdateToolbarWindow();
626}
bool DownloadFile(LPCSTR url, LPCSTR path)
Definition BBApi.cpp:3296
LPSTR ReadString(LPCSTR fp, LPCSTR szString, LPSTR szDefault)
Definition BBApi.cpp:544
void BBSmartExecute(LPSTR inputString)
Definition BBApi.cpp:1767
bool FileExists(LPCSTR szFileName)
Definition BBApi.cpp:819
bool WINAPI GetBlackboxPath(LPSTR pszPath, int nMaxLen)
Definition BBApi.cpp:214
int BBTokenize(LPCSTR szString, char *lpszBuffers[], DWORD dwNumBuffers, LPSTR szExtraParameters)
Definition BBApi.cpp:316
HINSTANCE BBExecute(HWND Owner, LPCSTR szOperation, LPCSTR szCommand, LPCSTR szArgs, LPCSTR szDirectory, int nShowCmd, bool noErrorMsgs)
Definition BBApi.cpp:1648
#define PLUGIN_UPDATE_URL
Definition BBApi.h:273
#define PLUGIN_RELEASEDATE
Definition BBApi.h:269
#define PLUGIN_VERSION
Definition BBApi.h:267
void checkForUpdates(void *param)
Definition PluginManager.cpp:630
char pluginsRepository[MAX_LINE_LENGTH]
Definition Settings.h:316

◆ AboutPlugins()

void PluginManager::AboutPlugins ( )
947{
948 char msg[MAX_LINE_LENGTH] = "", temp[MAX_LINE_LENGTH];
949
950 for (int i=0; i < (int)pluginList.size(); i++)
951 {
952 pluginInfo = (pluginInfoFunc)GetProcAddress(pluginList[i].hModule, "pluginInfo");
953 if (pluginInfo)
954 {
956 strcat(msg, temp);
957 if (pluginList[i].path[0] == '&') strcat(msg, " *\n"); // &-loaded plugin (beginSlitPlugin)
958 else strcat(msg, "\n"); // Normal plugin (beginPlugin, beginPluginEx)
959 }
960 else
961 {
962 strcat(msg, pluginList[i].path);
963 if (pluginList[i].path[0] == '&') strcat(msg, " *\n"); // &-loaded plugin (beginSlitPlugin)
964 else strcat(msg, "\n"); // Normal plugin (beginPlugin, beginPluginEx)
965 }
966 }
967
968 if (strlen(msg))
969 {
970 msg[strlen(msg)-1] = '\0'; // Remove the last line feed auto-generated above...
971 SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)"About the loaded plugins...", (LPARAM)msg);
972 }
973 else SendMessage(GetBBWnd(), BB_POPUPMESSAGE, (WPARAM)"About the loaded plugins...", (LPARAM)"--- No plugins loaded --- ");
974}
#define PLUGIN_AUTHOR
Definition BBApi.h:268
#define BB_POPUPMESSAGE
Definition BBApi.h:166

◆ GetPluginInfo()

LPCSTR PluginManager::GetPluginInfo ( int pluginNumber,
int infoParam )
979{
980 pluginInfo = (pluginInfoFunc)GetProcAddress(pluginList[pluginNumber].hModule, "pluginInfo");
981 if (pluginInfo)
982 {
983 LPCSTR result = pluginInfo(infoParam); // e.g. PLUGIN_VERSION (see BBApi.h)
984 if (result) return result;
985 // Fetch default fallback string in case the result was NULL
986 // (i.e. if the requested field was not supported/defined)
987// else return pluginInfo(-1);
988 else return pluginInfo(PLUGIN_NAME);
989 }
990 else
991 {
992 // Extract the name of the plugin...
993 strcpy(pluginName, pluginList[pluginNumber].path);
994 int nLen = strlen(pluginName) - 1;
995 if (IsInString(pluginName, "/")) while (nLen >0 && pluginName[nLen] != '/') nLen--;
996 else while (nLen >0 && pluginName[nLen] != '\\') nLen--;
997 strcpy(pluginName, &pluginList[pluginNumber].path[nLen+1]);
998 pluginName[strlen(pluginName)-4] = 0; // Remove .dll at the end...
999 return pluginName;
1000 }
1001}

◆ WritePluginsRC()

bool PluginManager::WritePluginsRC ( )
1006{
1007 if (pSettings->writeProtection) return true;
1008
1009 HANDLE f = CreateFile(plugrcPath(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
1010 if (f)
1011 {
1012 char szTemp[MAX_LINE_LENGTH];
1013 DWORD retLength = 0;
1014
1015 for (int i=0; i < (int)pluginList.size(); i++)
1016 {
1017 // If the full path to the plugin is specified (e.g. from drag'n'drop) and it is in
1018 // a subfolder to the Blackbox folder, extract the relative path to the plugin
1019 // -> full path minus Blackbox folder path.
1020 // Example: "C:\Blackbox\plugins\BBbin\BBbin.dll" becomes "plugins\BBbin\BBbin.dll"
1021 // This way the Blackbox folder can be moved, and the plugin path will still work! :D
1022
1024 {
1025 strcpy(szTemp, "$CurrentTheme$");
1026 strcat(szTemp, &pluginList[i].path[(strlen(pSettings->SF_currentThemePath))]);
1027 }
1028 else if (IsInString(pluginList[i].path, pSettings->SF_blackboxPath))
1029 {
1030 strcpy(szTemp, &pluginList[i].path[(strlen(pSettings->SF_blackboxPath)+1)]);
1031 }
1032 else strcpy(szTemp, pluginList[i].path);
1033
1034 strcat(szTemp, "\r\n");
1035 WriteFile(f, szTemp, strlen(szTemp), &retLength, NULL);
1036 }
1037
1038 CloseHandle(f);
1039 return true;
1040 }
1041 else
1042 {
1043 CloseHandle(f);
1044 return false;
1045 }
1046}
bool usingDefaultTheme
Definition Settings.h:386
char SF_currentThemePath[MAX_PATH]
Definition Settings.h:385
char SF_blackboxPath[MAX_PATH]
Definition Settings.h:377
bool writeProtection
Definition Settings.h:331

◆ LoadPluginDialog()

void PluginManager::LoadPluginDialog ( )
1051{
1052 char msg[MAX_LINE_LENGTH];
1053 strcpy(msg, "Always be careful when loading plugins and \nrunning scripts downloaded from the internet. \n\nEnsure they are from a trusted source. \n\nDo you want to continue? ");
1054
1055 if (MessageBox(GetBBWnd(), msg, "xoblite", MB_YESNO | MB_ICONQUESTION | MB_SETFOREGROUND | MB_TOPMOST) == IDYES)
1056 {
1057 char file[MAX_PATH] = "", path[MAX_PATH];
1058
1060 {
1061 strcpy(path, pSettings->SF_blackboxPath);
1062 strcat(path, "\\plugins");
1063 }
1064 else
1065 {
1066 strcpy(path, pSettings->SF_currentThemePath);
1067 strcat(path, "\\plugins");
1068 if (!FolderExists(path))
1069 {
1070 strcpy(path, pSettings->SF_blackboxPath);
1071 strcat(path, "\\plugins");
1072 }
1073 }
1074
1075 // Set the required formats for the file dialog...
1076 OPENFILENAME ofn;
1077 ZeroMemory(&ofn, sizeof(ofn));
1078 ofn.lStructSize = sizeof(ofn);
1079 ofn.hwndOwner = NULL;
1080 ofn.lpstrFilter = "Plugins (*.dll)\0*.dll", NULL, NULL;
1081 ofn.lpstrFile = file;
1082 ofn.nMaxFile = MAX_PATH;
1083 ofn.lpstrInitialDir = path;
1084 ofn.lpstrTitle = "Load plugin...";
1085 ofn.lpstrDefExt = NULL;
1086 ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER;
1087
1088 if (GetOpenFileName(&ofn)) LoadPlugin(ofn.lpstrFile);
1089 }
1090}
bool FolderExists(LPCSTR szFolderPath)
Definition BBApi.cpp:842

◆ IsPluginLoaded()

bool PluginManager::IsPluginLoaded ( LPSTR pluginPath)
1095{
1096 bool fileNameOnly = false;
1097 if (!strchr(pluginPath, '\\')) fileNameOnly = true;
1098
1099 for (int i=0; i < (int)pluginList.size(); i++)
1100 {
1101 if (fileNameOnly)
1102 {
1103 if (IsInString(pluginList[i].path, pluginPath)) return true;
1104 }
1105 else
1106 {
1107 if (!_stricmp(pluginList[i].path, pluginPath)) return true;
1108 }
1109 }
1110
1111 return false;
1112}

Member Data Documentation

◆ pluginList

PluginsVector PluginManager::pluginList

◆ startupLock

bool PluginManager::startupLock

◆ pluginName

char PluginManager::pluginName[MAX_LINE_LENGTH]

◆ hModule

HINSTANCE PluginManager::hModule

◆ beginPluginEx

beginPluginExFunc PluginManager::beginPluginEx

◆ beginPlugin

beginPluginFunc PluginManager::beginPlugin

◆ beginSlitPlugin

beginSlitPluginFunc PluginManager::beginSlitPlugin

◆ endPlugin

endPluginFunc PluginManager::endPlugin

◆ pluginInfo

pluginInfoFunc PluginManager::pluginInfo