diff options
| -rw-r--r-- | vfs/ModuleLoader.pas | 156 | ||||
| -rw-r--r-- | vfs/UVFSCore.pas | 100 |
2 files changed, 51 insertions, 205 deletions
diff --git a/vfs/ModuleLoader.pas b/vfs/ModuleLoader.pas deleted file mode 100644 index 51351dd..0000000 --- a/vfs/ModuleLoader.pas +++ /dev/null @@ -1,156 +0,0 @@ -{******************************************************************} -{ } -{ Project JEDI } -{ OS independent Dynamic Loading Helpers } -{ } -{ The initial developer of the this code is } -{ Robert Marquardt <robert_marquardt@gmx.de) } -{ } -{ Copyright (C) 2000, 2001 Robert Marquardt. } -{ } -{ Obtained through: } -{ Joint Endeavour of Delphi Innovators (Project JEDI) } -{ } -{ You may retrieve the latest version of this file at the Project } -{ JEDI home page, located at http://delphi-jedi.org } -{ } -{ The contents of this file are used with permission, subject to } -{ the Mozilla Public License Version 1.1 (the "License"); you may } -{ not use this file except in compliance with the License. You may } -{ obtain a copy of the License at } -{ http://www.mozilla.org/NPL/NPL-1_1Final.html } -{ } -{ Software distributed under the License is distributed on an } -{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or } -{ implied. See the License for the specific language governing } -{ rights and limitations under the License. } -{ } -{******************************************************************} - -unit ModuleLoader; - -interface -{$WEAKPACKAGEUNIT ON} - - -uses - Libc; -type - // Handle to a loaded .so - TModuleHandle = Pointer; - -const - // Value designating an unassigned TModuleHandle od a failed loading - INVALID_MODULEHANDLE_VALUE = TModuleHandle(nil); - -function LoadModule(var Module: TModuleHandle; FileName: string): Boolean; -function LoadModuleEx(var Module: TModuleHandle; FileName: string; Flags: Cardinal): Boolean; -procedure UnloadModule(var Module: TModuleHandle); -function GetModuleSymbol(Module: TModuleHandle; SymbolName: string): Pointer; -function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: string; var Accu: Boolean): Pointer; -function ReadModuleData(Module: TModuleHandle; SymbolName: string; var Buffer; Size: Cardinal): Boolean; -function WriteModuleData(Module: TModuleHandle; SymbolName: string; var Buffer; Size: Cardinal): Boolean; - -implementation - -// load the .so file FileName -// the rules for FileName are those of dlopen() -// Returns: True = success, False = failure to load -// Assigns: the handle of the loaded .so to Module -// Warning: if Module has any other value than INVALID_MODULEHANDLE_VALUE -// on entry the function will do nothing but returning success. - -function LoadModule(var Module: TModuleHandle; FileName: string): Boolean; -begin - Module := dlopen(PChar(FileName), RTLD_LAZY); - Result := Module <> INVALID_MODULEHANDLE_VALUE; -end; - -// load the .so file FileName -// dlopen() with flags is used to get better control of the loading -// for the allowed values for flags see "man dlopen". - -function LoadModuleEx(var Module: TModuleHandle; FileName: string; Flags: Cardinal): Boolean; -begin - Module := dlopen(PChar(FileName), Flags); - Result := Module <> INVALID_MODULEHANDLE_VALUE; -end; - -// unload a .so loaded with LoadModule or LoadModuleEx -// The procedure will not try to unload a handle with -// value INVALID_MODULEHANDLE_VALUE and assigns this value -// to Module after unload. - -procedure UnloadModule(var Module: TModuleHandle); -begin - if Module <> INVALID_MODULEHANDLE_VALUE then - dlclose(Module); - Module := INVALID_MODULEHANDLE_VALUE; -end; - -// returns the pointer to the symbol named SymbolName -// if it is exported from the .so Module -// nil is returned if the symbol is not available - -function GetModuleSymbol(Module: TModuleHandle; SymbolName: string): Pointer; -begin - Result := nil; - if Module <> INVALID_MODULEHANDLE_VALUE then - Result := dlsym(Module, PChar(SymbolName)); -end; - -// returns the pointer to the symbol named SymbolName -// if it is exported from the .so Module -// nil is returned if the symbol is not available. -// as an extra the boolean variable Accu is updated -// by anding in the success of the function. -// This is very handy for rendering a global result -// when accessing a long list of symbols. - -function GetModuleSymbolEx(Module: TModuleHandle; SymbolName: string; var Accu: Boolean): Pointer; -begin - Result := nil; - if Module <> INVALID_MODULEHANDLE_VALUE then - Result := dlsym(Module, PChar(SymbolName)); - Accu := Accu and (Result <> nil); -end; - -// get the value of variables exported from a .so Module -// Delphi cannot access variables in a .so directly, so -// this function allows to copy the data from the .so. -// Beware! You are accessing the .so memory image directly. -// Be sure to access a variable not a function and be sure -// to read the correct amount of data. - -function ReadModuleData(Module: TModuleHandle; SymbolName: string; var Buffer; Size: Cardinal): Boolean; -var - Sym: Pointer; -begin - Result := True; - Sym := GetModuleSymbolEx(Module, SymbolName, Result); - if Result then - Move(Sym^, Buffer, Size); -end; - -// set the value of variables exported from a .so Module -// Delphi cannot access variables in a .so directly, so -// this function allows to copy the data to the .so! -// BEWARE! You are accessing the .so memory image directly. -// Be sure to access a variable not a function and be sure -// to write the correct amount of data. -// The changes are not persistent. They get lost when the -// .so is unloaded. - -function WriteModuleData(Module: TModuleHandle; SymbolName: string; var Buffer; Size: Cardinal): Boolean; -var - Sym: Pointer; -begin - Result := True; - Sym := GetModuleSymbolEx(Module, SymbolName, Result); - if Result then - Move(Buffer, Sym^, Size); -end; -end. - - - diff --git a/vfs/UVFSCore.pas b/vfs/UVFSCore.pas index 88277ae..e3bdf4c 100644 --- a/vfs/UVFSCore.pas +++ b/vfs/UVFSCore.pas @@ -162,7 +162,7 @@ var PluginList: TList; implementation -uses SysUtils, ModuleLoader, UConfig, ULocale; +uses SysUtils, UConfig, ULocale; const ConstGlobalModulePath1 = '/usr/lib/tuxcmd'; @@ -188,47 +188,47 @@ begin ModuleHandle := PluginHandle; // Find the symbols - @FVFSAllocNeeded := GetModuleSymbol(ModuleHandle, 'VFSAllocNeeded'); - @FVFSInit := GetModuleSymbol(ModuleHandle, 'VFSInit'); - @FVFSDestroy := GetModuleSymbol(ModuleHandle, 'VFSDestroy'); - @FVFSVersion := GetModuleSymbol(ModuleHandle, 'VFSVersion'); - @FVFSGetInfo := GetModuleSymbol(ModuleHandle, 'VFSGetInfo'); - @FVFSOpen := GetModuleSymbol(ModuleHandle, 'VFSOpen'); - @FVFSClose := GetModuleSymbol(ModuleHandle, 'VFSClose'); - @FVFSListFirst := GetModuleSymbol(ModuleHandle, 'VFSListFirst'); - @FVFSListNext := GetModuleSymbol(ModuleHandle, 'VFSListNext'); - @FVFSListClose := GetModuleSymbol(ModuleHandle, 'VFSListClose'); - @FVFSGetPath := GetModuleSymbol(ModuleHandle, 'VFSGetPath'); - @FVFSChangeDir := GetModuleSymbol(ModuleHandle, 'VFSChangeDir'); - @FVFSGetPrefix := GetModuleSymbol(ModuleHandle, 'VFSGetPrefix'); - @FVFSGetFileSystemSize := GetModuleSymbol(ModuleHandle, 'VFSGetFileSystemSize'); - @FVFSGetFileSystemFree := GetModuleSymbol(ModuleHandle, 'VFSGetFileSystemFree'); - @FVFSLogin := GetModuleSymbol(ModuleHandle, 'VFSLogin'); - @FVFSFileExists := GetModuleSymbol(ModuleHandle, 'VFSFileExists'); - @FVFSFileInfo := GetModuleSymbol(ModuleHandle, 'VFSFileInfo'); - @FVFSMkDir := GetModuleSymbol(ModuleHandle, 'VFSMkDir'); - @FVFSRemove := GetModuleSymbol(ModuleHandle, 'VFSRemove'); - @FVFSRename := GetModuleSymbol(ModuleHandle, 'VFSRename'); - @FVFSMakeSymLink := GetModuleSymbol(ModuleHandle, 'VFSMakeSymLink'); - @FVFSChmod := GetModuleSymbol(ModuleHandle, 'VFSChmod'); - @FVFSChown := GetModuleSymbol(ModuleHandle, 'VFSChown'); - @FVFSChangeTimes := GetModuleSymbol(ModuleHandle, 'VFSChangeTimes'); - @FVFSGetDirSize := GetModuleSymbol(ModuleHandle, 'VFSGetDirSize'); - @FVFSBreakGetDirSize := GetModuleSymbol(ModuleHandle, 'VFSBreakGetDirSize'); - @FVFSCopyOut := GetModuleSymbol(ModuleHandle, 'VFSCopyOut'); - @FVFSCopyIn := GetModuleSymbol(ModuleHandle, 'VFSCopyIn'); - @FVFSOpenFile := GetModuleSymbol(ModuleHandle, 'VFSOpenFile'); - @FVFSReadFile := GetModuleSymbol(ModuleHandle, 'VFSReadFile'); - @FVFSWriteFile := GetModuleSymbol(ModuleHandle, 'VFSWriteFile'); - @FVFSCloseFile := GetModuleSymbol(ModuleHandle, 'VFSCloseFile'); - @FVFSFileSeek := GetModuleSymbol(ModuleHandle, 'VFSFileSeek'); - @FVFSSetBlockSize := GetModuleSymbol(ModuleHandle, 'VFSSetBlockSize'); - @FVFSIsOnSameFS := GetModuleSymbol(ModuleHandle, 'VFSIsOnSameFS'); - @FVFSTwoSameFiles := GetModuleSymbol(ModuleHandle, 'VFSTwoSameFiles'); - @FVFSGetExts := GetModuleSymbol(ModuleHandle, 'VFSGetExts'); - @FVFSGetServices := GetModuleSymbol(ModuleHandle, 'VFSGetServices'); - @FVFSSetPassword := GetModuleSymbol(ModuleHandle, 'VFSSetPassword'); - @FVFSGetPasswordRequired := GetModuleSymbol(ModuleHandle, 'VFSGetPasswordRequired'); + @FVFSAllocNeeded := dlsym(ModuleHandle, 'VFSAllocNeeded'); + @FVFSInit := dlsym(ModuleHandle, 'VFSInit'); + @FVFSDestroy := dlsym(ModuleHandle, 'VFSDestroy'); + @FVFSVersion := dlsym(ModuleHandle, 'VFSVersion'); + @FVFSGetInfo := dlsym(ModuleHandle, 'VFSGetInfo'); + @FVFSOpen := dlsym(ModuleHandle, 'VFSOpen'); + @FVFSClose := dlsym(ModuleHandle, 'VFSClose'); + @FVFSListFirst := dlsym(ModuleHandle, 'VFSListFirst'); + @FVFSListNext := dlsym(ModuleHandle, 'VFSListNext'); + @FVFSListClose := dlsym(ModuleHandle, 'VFSListClose'); + @FVFSGetPath := dlsym(ModuleHandle, 'VFSGetPath'); + @FVFSChangeDir := dlsym(ModuleHandle, 'VFSChangeDir'); + @FVFSGetPrefix := dlsym(ModuleHandle, 'VFSGetPrefix'); + @FVFSGetFileSystemSize := dlsym(ModuleHandle, 'VFSGetFileSystemSize'); + @FVFSGetFileSystemFree := dlsym(ModuleHandle, 'VFSGetFileSystemFree'); + @FVFSLogin := dlsym(ModuleHandle, 'VFSLogin'); + @FVFSFileExists := dlsym(ModuleHandle, 'VFSFileExists'); + @FVFSFileInfo := dlsym(ModuleHandle, 'VFSFileInfo'); + @FVFSMkDir := dlsym(ModuleHandle, 'VFSMkDir'); + @FVFSRemove := dlsym(ModuleHandle, 'VFSRemove'); + @FVFSRename := dlsym(ModuleHandle, 'VFSRename'); + @FVFSMakeSymLink := dlsym(ModuleHandle, 'VFSMakeSymLink'); + @FVFSChmod := dlsym(ModuleHandle, 'VFSChmod'); + @FVFSChown := dlsym(ModuleHandle, 'VFSChown'); + @FVFSChangeTimes := dlsym(ModuleHandle, 'VFSChangeTimes'); + @FVFSGetDirSize := dlsym(ModuleHandle, 'VFSGetDirSize'); + @FVFSBreakGetDirSize := dlsym(ModuleHandle, 'VFSBreakGetDirSize'); + @FVFSCopyOut := dlsym(ModuleHandle, 'VFSCopyOut'); + @FVFSCopyIn := dlsym(ModuleHandle, 'VFSCopyIn'); + @FVFSOpenFile := dlsym(ModuleHandle, 'VFSOpenFile'); + @FVFSReadFile := dlsym(ModuleHandle, 'VFSReadFile'); + @FVFSWriteFile := dlsym(ModuleHandle, 'VFSWriteFile'); + @FVFSCloseFile := dlsym(ModuleHandle, 'VFSCloseFile'); + @FVFSFileSeek := dlsym(ModuleHandle, 'VFSFileSeek'); + @FVFSSetBlockSize := dlsym(ModuleHandle, 'VFSSetBlockSize'); + @FVFSIsOnSameFS := dlsym(ModuleHandle, 'VFSIsOnSameFS'); + @FVFSTwoSameFiles := dlsym(ModuleHandle, 'VFSTwoSameFiles'); + @FVFSGetExts := dlsym(ModuleHandle, 'VFSGetExts'); + @FVFSGetServices := dlsym(ModuleHandle, 'VFSGetServices'); + @FVFSSetPassword := dlsym(ModuleHandle, 'VFSSetPassword'); + @FVFSGetPasswordRequired := dlsym(ModuleHandle, 'VFSGetPasswordRequired'); // Initialize the extensions list SetLength(Extensions, 0); SetLength(Services, 0); @@ -238,7 +238,7 @@ end; destructor TVFSPlugin.Destroy; begin - if ModuleHandle <> nil then UnloadModule(ModuleHandle); + if ModuleHandle <> nil then dlclose(ModuleHandle); inherited Destroy; end; @@ -963,7 +963,7 @@ var Handle: PDirectoryStream; DirEnt: PDirent64; s: string; PluginItem: TVFSPlugin; - ModuleHandler: TModuleHandle; + ModuleHandler: Pointer; VFSVersionFunc: TVFSVersion; i: integer; Buf: PChar; @@ -1020,16 +1020,18 @@ begin end; ModuleHandler := nil; - if b then DebugMsg(['Module ', s, ' is already loaded --> skipping...']) else - if not LoadModule(ModuleHandler, IncludeTrailingPathDelimiter(s) + Buf) then DebugMsg([' XXX Error loading module: ', dlerror]) - else try - @VFSVersionFunc := GetModuleSymbol(ModuleHandler, 'VFSVersion'); + if b then DebugMsg(['Module ', s, ' is already loaded --> skipping...']) else begin + ModuleHandler := dlopen(PChar(IncludeTrailingPathDelimiter(s) + Buf), RTLD_LAZY); + if ModuleHandler = nil then DebugMsg([' XXX Error loading module: ', dlerror]) + else try + @VFSVersionFunc := dlsym(ModuleHandler, 'VFSVersion'); if (@VFSVersionFunc <> nil) and (VFSVersionFunc >= ConstVFSVersionRequired) then begin PluginItem := TVFSPlugin.Create(ModuleHandler); PluginItem.FullPath := IncludeTrailingPathDelimiter(s) + Buf; PluginList.Add(PluginItem); end else DebugMsg([' $XXX: Error getting version info or version mismatch']); except end; + end; end; end; until DirEnt = nil; @@ -1049,7 +1051,7 @@ begin if Assigned(PluginList) and (PluginList.Count > 0) then for i := PluginList.Count - 1 downto 0 do try - UnloadModule(TVFSPlugin(PluginList[i]).ModuleHandle); + dlclose(TVFSPlugin(PluginList[i]).ModuleHandle); TVFSPlugin(PluginList[i]).Free; PluginList.Delete(i); except |
