How can I Create folders recursively in Delphi? - delphi

Need some help in creating function which can create folders recursively with giving path:
C:\TestFolder\Another\AndAnother
Delphi function MkDir returning IOerror = 3.
MkDir('C:\TestFolder\Another\AndAnother');

Use
ForceDirectories('C:\TestFolder\Another\AndAnother');
(This is a standard RTL function, found in SysUtils.pas. Hence you do not need to create your own function, even though that wouldn't have been difficult.)

SysUtils is obsolete now and ForceDirectories is not UNC aware!
There is a new library in since Delphi XE7 (or even earlyer?) called IOUtils.
IOUtils is cross-platform compatible and UNC aware.
function ForceDirectories(FullPath: string): Boolean; // Works with UNC paths
begin
TDirectory.CreateDirectory(FullPath);
Result:= DirectoryExists(FullPath);
end;
Note: The function is from Delphi LightSaber library. There are several other similar I/O functions there (like ListFilesOf(Folder)).

Related

app crash on call .dll in delphi

I have a DLL it crated with Delphi xe10.2 and it contain a function
function calc(b : integer;a:integer) : Integer;
begin
Result := a+b;
end;
and i will call it on other program like this
function calc(b : integer;a:integer): Integer; stdcall; external 'my.dll';
i copied the DLL in System32 folder and application .exe folder
procedure TForm1.Button1Click(Sender: TObject);
begin
showmessage(inttostr(calc(2,3)));
end;
but when i run from delphi IDE nothing happened.it dont show any error and also dont show application main form...
how can i fix this ?!
System32 is the 64-bit system folder. Your application is a 32-bit application, and hence does not search for DLLs in System32. It will search in SysWOW64 instead, which is the 32-bit system folder. If you ran the program without debugging, you would see an error message telling you that the DLL could not be located.
Now, you should never modify the contents of system folders. Remove the DLL from System32 and instead place it in the same directory as your executable file.
The other problem, given the code shown, is that the exported DLL function uses the register calling convention, but you import it using the stdcall calling convention. You must ensure that the calling conventions used by DLL and EXE match each other.

How to know the caller application of the dll in delphi

I have a dll that can be called from different exe applications (dll and exe's are written in Delphi 5).
Is it possible to know inside the dll which exe application it was called from?
In other words let's say I have App1.exe, App2.exe and MyDll.dll. App1.exe called the MyDll.exe. I want to know inside the dll that it was called from App1 but not from App2.
If you call the Windows API function GetModuleFileName() passing NULL (0) as the module handle (first parameter) then this will return the filename of the process, i.e. the executable:
function GetProcessFileName: String;
var
buf: array[0..MAX_PATH-1] of Char;
begin
GetModuleFileName(0, #buf, Length(buf));
result := buf;
end;
NOTE: As Raymond Chen always says, sample programs do little or no error checking! :)
For further information on the use of this API consult the documentation and use accordingly.

Dynamicly handle not defined functions in a dll in dlephi

I have a dll which defines a simple functions to show a message:
library testdll;
uses SysUtils, Classes, Dialogs;
{$R *res}
procedure ShowDll;stdcall;
begin
ShowMessage('ShowDLL testdll.dll');
end;
exports ShowDLL;
begin
end.
And my main file call this dll dynamicly using this procedure:
i defined a new type:
type
testdll = procedure;stdcall;
Then on my button click event:
procedure TForm1.Button1Click(Sender:TObject);
var
dllHandle: THandle; //Don't use Cardinal; it's limited to 32-bits
test : testdll;
begin
dllHandle := LoadLibrary('testdll.dll');
if dllHandle <> 0 then
begin
#test := GetProcAddress(dllHandle,'ShowDLL');
if Assigned(test) then
ShowDLL
else
ShowMessage('Func not found');
end
else
ShowMessage('dll not found');
end;
This works. But I don't know if it's possible to handle not defined functions with my dll. My purpose here is to call a function without knowing if it will be defined in my dll. So i would like the dll to tell me if the functions exists or not.
For example here i only have a ShowDLL procedure. If i call another method which does not exists it will show 'Func not found' from my main application. But i would my dll to tell me this. Is this possible? If yes, how could i achieve this pls?
EDIT: I can't modify the main function this is only a test. In my final version there will be only the dll. So exporting all functions into my main application is not possible here. That's why i want to know id the dll alone can handle it rather than doing this in my main application which i can't do.
I don't have acces to the main application to modify any code in it. I only know what are functions that will be used in this application that i will later export in my dll using exports statement. So what i try to achieve is to catch a not defined function with the dll if it's possible.
Your code already demonstrates how to detect the presence of an export. Namely to call GetProcAddress and compare the result with nil.
You can reduce the amount of boiler plate code by using delay loading. This essentially lets the compiler generate the code the performs the checks. This relies on the delayed keyword.
procedure testdll; stdcall;
external 'testdll.dll` delayed;
When you call this function, if it cannot be found, an exception is raised. Indeed this behaviour can be customised, as described in the documentation: http://docwiki.embarcadero.com/RADStudio/en/Libraries_and_Packages#Delayed_Loading
Update
In a comment to this answer you state that the executable cannot be changed. In which case, the message that you wish to avoid will be shown if the function is missing. You ask if the missing export can be handled by the DLL but that is not possible. When you call GetProcAddress, no code inside the DLL is executed. All the processing is done external to the DLL by reading its PE metadata.
The obvious conclusion is that the DLL must export the function. If the true DLL does not, put another DLL in its place. Use an interposer DLL that exports the function. Implement the function by delegating to the true DLL, if the true DLL exports the function. Otherwise do something else, whatever you please.

Exporting overloaded functions with fpc

I need to create a dll within fpc (delphi-mode). It works fine - but for some reasons, I want to do something (in a unit) like
function doSomeThing(a:type1):type2;stdcall;
function doSomeThing(a:type3):type4;stdcall;
and in the library (for building the dll using the unit above)
exports
doSomeThing(a:type1) name 'doSomeThingTYPE1',
doSomeThing(a:type3) name 'doSomeThingTYPE3';
The syntax is self explanatory and is told in How to export Overload functions from DLL? . But it seems to be unavailable in fpc (version 2.6.0-9 [2013/04/14] for x86_64). Is there a chance to do something like that - or do I have to rename the functions within my source?
The question that you link to discusses Delphi. The syntax that Delphi supports, that allows you to export overloaded functions, is not supported by FPC.
To the best of my knowledge, overloaded functions are not exportable. Although, I could easily be wrong on that score. Perhaps there is a way, as Marco proposes in his answer.
David consulted me in another thread, I devised something that compiles, but don't know if it works.
It is based on exporting the function using a defined linker level identifier, and then declaring an external function reimporting it with different Pascal names. Note that bla and bla2 doesn't even have to be in the same unit as dosomething variants.
library testdll;
{$mode delphi}
type
type1=integer;
type3=char;
type2=smallint;
type4=widechar;
function doSomeThing(a:type1):type2;stdcall; overload; [public, alias:'bla'];
begin
result:=a+1;
end;
function doSomeThing(a:type3):type4;stdcall; overload; [public, alias:'bla2'];
begin
result:=widechar(ord(a)+1000);
end;
procedure bla; external name 'bla';
procedure bla2; external name 'bla2';
exports
bla name 'doSomeThingTYPE1',
bla2 name 'doSomeThingTYPE3';
end.

Work around with Delphi DLL

I have two applications in Delphi for which I don't have any code source:
I use an interface from application A to call an DLL file from application B. Example, I usually pass a service number, 200011, from interface A to call DLL file B for a value return. But, recently the application A have changed the variable. I have to add P00200011 to call DLL file B.
I have tried to create an DLL C#, but the DLL in B is created with the fastcall convention and I cannot change this DLL file.
What are others ways I can do it? I'm out of ideas.
You need to write a wrapper DLL. You build your DLL with the functions you want to intercept, and in your code you simply load and call the original DLL. Then you place your wrapper in the same directory of your application. All calls from the application will go to your wrapper DLL and from there to the original DLL.
Here is a simple example
supose you have this library (B.DLL)
library B;
function B_FUNCTION(value:integer): integer; export;
begin
result:=value+1;
end;
exports B_FUNCTION;
end.
And this program that uses it
program A;
{$apptype console}
function B_FUNCTION(value:integer): integer; external 'b.dll';
var i:integer;
begin
i:=B_FUNCTION(2010);
writeln(i);
end.
Compile both programs and run them. The result printed is 2011.
Now, code your wrapper DLL
library w;
uses windows;
function B_FUNCTION(value:integer): integer; export;
var
adll: Thandle;
afunc: function(v:integer):integer;
begin
adll:=LoadLibrary('TRUE_B.DLL');
afunc:= GetProcAddress(adll,'B_FUNCTION');
result:=afunc(value+1);
FreeLibrary(adll);
end;
exports B_FUNCTION;
end.
Build it, you'll have A.EXE, B.DLL and W.DLL. Replace them
REN B.DLL TRUE_B.DLL
REN W.DLL B.DLL
Execute A, now it will spit 2012.
It's not entirely obvious to me which parts are yours and what calls what, but you should be able to create your own intermediate DLL in Delphi with an interface that uses fastcall and which forwards the call to the real DLL using another calling convention.

Resources