Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Union Übersetzung nach Pascal (https://www.delphipraxis.net/88246-union-uebersetzung-nach-pascal.html)

Neutral General 12. Mär 2007 15:04


Union Übersetzung nach Pascal
 
Hi,

Auf Assabards Seite habe ich folgende Übersetzung gefunden


Code:
union {
    struct {
      DWORD Signature;
      DWORD CheckSum;
    } Mbr;
    struct {
      GUID DiskId;
    } Gpt;
  };
:arrow:

Delphi-Quellcode:
case Integer of
    0: (
       Signature: DWORD;
       CheckSum: DWORD
       );
    1: (
       DiskId: TGUID
       );
Ok das ist nachvollziebar... ABER was ist soll das hier bedeuten:

Code:
union {
        PARTITION_INFORMATION_MBR Mbr;
        PARTITION_INFORMATION_GPT Gpt;
    };
?

Delphi-Quellcode:
Case Integer of
 0: PARTITION_INFORMATION_MBR;
 1: PARTITION_INFORMATION_GPT;
end;
... Aber was für einen Sinn ergibt das?

Gruß
Neutral General

CK_CK 12. Mär 2007 15:08

Re: Union Übersetzung nach Pascal
 
Hi!
Es wäre wohl eher:
Delphi-Quellcode:
case Integer of
  0: (Mbr: PARTITION_INFORMATION_MBR);
  1: (Gpt: PARTITION_INFORMATION_GPT);
end;
Viele Grüße,
Chris

Edit: Guck' mal [HIER], wie die's gelöst haben... ;)

Neutral General 12. Mär 2007 15:19

Re: Union Übersetzung nach Pascal
 
Zitat:

Zitat von CK_CK
Edit: Guck' mal [HIER], wie die's gelöst haben... ;)

--------- __________ -----------

Die Schweine. Das wollte ich doch machen :roll:

Pf.. Ich machs trotzdem -.-

PS: Danke ;)
PPS: Wobei das Problem auch noch bei ULong64 liegt.. Die benutzen da ein DWORD64. Sowas existiert bei mir aber nicht..
PPPS: Ich seh grad die definieren ULong64 als Int64... Ehm naja ich weiß zwar nicht seit wann Integers unsigned sind aber egal :wall:

Gruß
Neutral General

himitsu 12. Mär 2007 15:26

Re: Union Übersetzung nach Pascal
 
Delphi-Quellcode:
// ab Delphi 6:
Type DWord64 = System.UInt64;
   LargeWord = System.UInt64;


// und D1 bis D5:
Type DWord64 = Type System.Int64;
   LargeWord = Type System.Int64;

Neutral General 12. Mär 2007 15:53

Re: Union Übersetzung nach Pascal
 
Ok danke aber was heißt das hier:

Delphi-Quellcode:
_PARTITION_INFORMATION_EX = record
  PartitionStyle: PARTITION_STYLE;
  StartingOffset: LARGE_INTEGER;
  PartitionLength: LARGE_INTEGER;
  PartitionNumber: ULONG;
  RewritePartition: Boolean;
  case Integer of
    0: (Mbr: PARTITION_INFORMATION_MBR);
    1: (Gpt: PARTITION_INFORMATION_GPT);
end;
Und wie soll ich die markierte Zeile in diesem Record übersetzen ? o.O

Code:
typedef struct _DRIVE_LAYOUT_INFORMATION_EX {
    ULONG PartitionStyle;
    ULONG PartitionCount;
    union {
        DRIVE_LAYOUT_INFORMATION_MBR Mbr;
        DRIVE_LAYOUT_INFORMATION_GPT Gpt;
    };
    PARTITION_INFORMATION_EX PartitionEntry[1]; //<---- Was soll die [1] ?
}
PS: Man man Michi -.- Erst gucken dann schreiben...

Delphi-Quellcode:
PartitionEntry: array [0..0] of PARTITION_INFORMATION_EX;
Gruß
Neutral General

himitsu 12. Mär 2007 16:05

Re: Union Übersetzung nach Pascal
 
Aber vergiß dann nicht vorher abzufragen wieviele Partitionen vorhanden sind, denn du mußt ja mindestens für jede Partition da hinten Speicherplatz reservieren.


Da ich selber ums mir einfacher zu machen und Delphi die Verwaltung des Speicherplatzes aufzubrumen gerne Variablen verwende, hab ich das einfach so gelöst :angel:

mit Variable:
Delphi-Quellcode:
Type _DRIVE_LAYOUT_INFORMATION_EX = packed Record
    PartitionStyle: _PARTITION_STYLE;
    PartitionCount: LongWord;
    Union: packed Record Case _PARTITION_STYLE of
      PARTITION_STYLE_MBR: (Mbr: _DRIVE_LAYOUT_INFORMATION_MBR);
      PARTITION_STYLE_GPT: (Gpt: _DRIVE_LAYOUT_INFORMATION_GPT);
    End;
    PartitionEntry: packed Array[0..31] of _PARTITION_INFORMATION_EX;
  End;

Var DLI: _DRIVE_LAYOUT_INFORMATION_EX;

DeviceIoControl(Dh, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0,
  @DLI, SizeOf(_DRIVE_LAYOUT_INFORMATION_EX), W, nil);
...
über Pointer:
Delphi-Quellcode:
Type _DRIVE_LAYOUT_INFORMATION_EX = packed Record
    PartitionStyle: _PARTITION_STYLE;
    PartitionCount: LongWord;
    Union: packed Record Case _PARTITION_STYLE of
      PARTITION_STYLE_MBR: (Mbr: _DRIVE_LAYOUT_INFORMATION_MBR);
      PARTITION_STYLE_GPT: (Gpt: _DRIVE_LAYOUT_INFORMATION_GPT);
    End;
    PartitionEntry: packed Array[0..0] of _PARTITION_INFORMATION_EX;
  End;
  pDRIVE_LAYOUT_INFORMATION_EX = _DRIVE_LAYOUT_INFORMATION_EX^;

Var pDLI: pDRIVE_LAYOUT_INFORMATION_EX;

DLI := GetMem(SizeOf(_DRIVE_LAYOUT_INFORMATION_EX)
  + SizeOf(_PARTITION_INFORMATION_EX) * (AnzahlDerPartitionen - 1));
Try
  DeviceIoControl(Dh, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0,
    DLI, SizeOf(_DRIVE_LAYOUT_INFORMATION_EX), W, nil);
  ...
Finally
  FreeMem(DLI);
End;

// -1 da Array[0..0] of _PARTITION_INFORMATION_EX bereits einmal _PARTITION_INFORMATION_EX einschließt

Neutral General 12. Mär 2007 16:16

Re: Union Übersetzung nach Pascal
 
Ok danke aber woher weiß ich wie viele Partitionen auf der Festplatte drauf sind ? o.O

himitsu 12. Mär 2007 16:22

Re: Union Übersetzung nach Pascal
 
von nirgendwo?

na ja, im Grunde machen es alle einfach so ... sie reservieren mehr, als es vermutlich gibt :zwinker:
und lassen sich dann im Nachhinein überraschen was in PartitionCount steht.

also meist einfach:
Delphi-Quellcode:
DLI := GetMem(SizeOf(_DRIVE_LAYOUT_INFORMATION_EX)
  + SizeOf(_PARTITION_INFORMATION_EX) * 31);
Im Grunde mach ich genau das Selbe ... oder bist du der Meinung, daß jemand mehr als 32 Partitionen auf einer Platte hat? (sehr unwarscheinlich)

Neutral General 12. Mär 2007 16:36

Re: Union Übersetzung nach Pascal
 
Also mein Problem liegt im Moment hauptsächlich bei GetMem^^

Delphi-Quellcode:
procedure GetMem(var P: Pointer; Size: Integer);
So ist das bei mir definiert. Und
Delphi-Quellcode:
DLI := GetMem(SizeOf(_DRIVE_LAYOUT_INFORMATION_EX)
  + SizeOf(_PARTITION_INFORMATION_EX) * 31);
funktioniert daher auch nicht so toll....

EDIT: Ja ok.. man muss es ander schreiben...

Delphi-Quellcode:
Size := SizeOf(_DRIVE_LAYOUT_INFORMATION_EX) + SizeOf(_PARTITION_INFORMATION_EX)*31;

GetMem(P,Size);
DeviceIoControl(H,IOCTL_DISK_GET_DRIVE_LAYOUT_EX,nil,0,P,Size,OutBytes,nil)
FreeMem(P);
Aber auf jeden Fall herzlichen Dank für die gute Hilfe :)

Gruß
Neutral General


EDIT: Oh man... Ich bekomme jetzt als P.PartitionCount 32 zurück..... Damit kann ich ja gar nix anfangen und P.ParitionEntry[0].PartitionNumber ist 288.. Kann das sein?

himitsu 12. Mär 2007 17:27

Re: Union Übersetzung nach Pascal
 
tja, das kommt wohl von den vielen Varianten -.-''

P := GetMemory(Size);
GetMem(P, Size);
P := SysGetMem(Size);
...

wobei GetMem eine Exception (EOutOfMemory) auslößt, wenn der gewpnschte Speicher nicht reserviert werden kann und die Anderen "nur" P=nil zurückliefern (also ohne Exception).


Was gibt DeviceIoControl für'n Fehler aus?
(bei 'nem Fehler wird nichts in den Record geschrieben, daher könnten auch die "komischen" Werte kommen ... standen halt vorher schon so drin)
Delphi-Quellcode:
Size := SizeOf(_DRIVE_LAYOUT_INFORMATION_EX) + SizeOf(_PARTITION_INFORMATION_EX) * 31;
GetMem(P, Size);
Try
  FillChar(P^, Size, 0);
  If DeviceIoControl(H, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0,
    P, Size, OutBytes, nil) Then Begin
   
    ...

  End Else ShowMessage(SysErrorMessage(GetLastError));
Finally
  FreeMem(P);
End;
Und wie hast du dir eigentlich das Handle zur Partition geholt?

Neutral General 12. Mär 2007 17:42

Re: Union Übersetzung nach Pascal
 
GetLastError gibt mir keinen Fehler zurück... Das Handle bekomm ich wie in MSDN beschrieben durch

Delphi-Quellcode:
h:= CreateFile('\\.\C:',0,FILE_SHARE_DELETE or FILE_SHARE_READ or FILE_SHARE_WRITE,
                 nil,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0);
Dieses Handle ist auch gültig.

Nebenbei mal ne Frage: Ich will ja (wie du vielleicht noch aus dem anderen Thread weißt) herausfinden wie viele Partitionen auf einer Festplatte sind und welche das dann sind. Komm ich hiermit überhaupt an mein Ziel? Hatte mal mit deiner WMI-Unit die Festplatten ausgelesen:

Delphi-Quellcode:
var
  X: TWMIInfo;
  i,j: Integer;
begin
  ComputerName := '.';
  WMIGetInfo(ComputerName,'root\CIMV2','','','SELECT Caption, DeviceID FROM Win32_DiskDrive',x);

  if x.Instance = nil then
   ShowMessage('Hat nicht geklappt');
  for i:= 0 to High(x.Instance) do
    for j:= 0 to High(x.Propname) do
   ShowMessage(X.PropName[j] + ': ' + WMIRead(x,i,j));
Da bekomme ich auch schön die Festplatten-Namen und ID's angezeigt (ID z.B \\.\PHYSICALDRIVE0).
Dann versuche ich damit die Partitionen auszulesen nämlich so:

Delphi-Quellcode:
WMIGetInfo(ComputerName,'root\CIMV2','','','ASSOCIATORS OF {Win32_DiskDrive.DeviceID='''
             + WMIRead(x,0,1) + '''} WHERE AssocClass = Win32_DiskDriveToDiskPartition',y);
(nach diesem Vorbild):

Code:
'Use the disk drive device id to
'find associated partition

query = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" _
        & wmiDiskDrive.DeviceID & "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition"  
    Set wmiDiskPartitions = wmiServices.ExecQuery(query)
Aber da bekomm ich für Y immer nur nil zurück... (vgl. Letztes Beispiel)

Gruß
Neutral General

himitsu 12. Mär 2007 18:18

Re: Union Übersetzung nach Pascal
 
Zitat:

Zitat von Neutral General
Dieses Handle ist auch gültig.

Ein gültiges Handle heißt noch garnichts.

Das gültige Handle bedeutet nur, daß du nun ein Handle mit den angegebenen Rechten bekommen hast,

aber ob die Rechte auch für die gewünschte Funktion ausreichen?

Code:
Dh := CreateFile(PChar(S), [color=#ff0000]GENERIC_READ or GENERIC_WRITE[/color],
  FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, [color=#ff0000]0[/color], 0);
also mit bekomm ich auch keine Antwort
Zitat:

ASSOCIATORS OF {Win32_DiskDrive.DeviceID='\\.\PHYSICALDRIVE0'} WHERE AssocClass = Win32_DiskDriveToDiskPartition
> http://www.delphipraxis.net/internal...ct.php?t=89423

wenn \\.\PhysicalDrive0 einzeln vorkommen würde, dann könnte man es so machen,
Zitat:

SELECT * FROM Win32_DiskDriveToDiskPartition WHERE Antecedent = "\\.\PhysicalDrive0"
aber wie man nur "teilweise" suchen kann weiß ich auch nicht -.-''

Notfalls halt alles durchgehn was Win32_DiskDriveToDiskPartition rausrückt und mit Pos in den Antworten danach suchen?

Neutral General 12. Mär 2007 18:35

Re: Union Übersetzung nach Pascal
 
Hi,

Also mit

Delphi-Quellcode:
SELECT * FROM Win32_DiskDriveToDiskPartition WHERE Antecedent = "\\.\PhysicalDrive0"
erreiche ich auch nix (y = nil)...

Ach ja:

Delphi-Quellcode:
Dh := CreateFile(PChar(S), GENERIC_READ or GENERIC_WRITE,
  FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
ändert auch nix an der ganzen Sache...

himitsu 12. Mär 2007 19:14

Re: Union Übersetzung nach Pascal
 
Zitat:

Zitat von Neutral General
Also mit ... erreiche ich auch nix (y = nil)...

sag ich doch?

Kennst dich zufällig mit SQL aus?
Die WMI-Queries ähneln diesem ja.

Wie kann man da nach "TeilStrings" suchen?


Zitat:

Zitat von Neutral General
Ach ja ... ändert auch nix an der ganzen Sache...

Hast du den Record vorher mal geleert?

Wenn das dateihandle OK ist und DeviceIoControl True liefert, dann sollten eigentlich korrekt Werte in dem Record liegen.

Also, ist DeviceIoControl = True
und was gibt OutBytes zurück?


Was sagt das?
Delphi-Quellcode:
H := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,
  FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
Size := SizeOf(_DRIVE_LAYOUT_INFORMATION_EX) + SizeOf(_PARTITION_INFORMATION_EX) * 31;
GetMem(P, Size);
Try
  FillChar(P^, Size, 0);
  If DeviceIoControl(H, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0,
    P, Size, OutBytes, nil) Then Begin
   
    ...

  End Else ShowMessage(SysErrorMessage(GetLastError));
Finally
  FreeMem(P);
End;
CloseHandle(H);

Neutral General 12. Mär 2007 19:24

Re: Union Übersetzung nach Pascal
 
Delphi-Quellcode:
procedure TForm1.Button6Click(Sender: TObject);
var H: THandle;
    P: PDRIVE_LAYOUT_INFORMATION_EX;
    outBytes: Cardinal;
    Size: Cardinal;
begin
  H := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,
  FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);

Size := SizeOf(_DRIVE_LAYOUT_INFORMATION_EX) + SizeOf(_PARTITION_INFORMATION_EX) * 31;

GetMem(P, Size);
Try
  FillChar(P^, Size, 0);
  If DeviceIoControl(H, IOCTL_DISK_GET_DRIVE_LAYOUT_EX, nil, 0,
    P, Size, OutBytes, nil) Then
      ShowMessage('Klappt')

  Else ShowMessage(SysErrorMessage(GetLastError));
Finally
  FreeMem(P);
End;
CloseHandle(H);
end;
Das sagt mir: 'klappt' :mrgreen:
OutBytes = 4656
Werte von P sind die selben wie sonst auch...

Robert Marquardt 12. Mär 2007 19:31

Re: Union Übersetzung nach Pascal
 
Delhpi kennt kein unsigned Int64, C aber schon. Man muss daher notgedrungen ein Int64 in Delphi nehmen und beim Rechnen auf das Vorzeichen aufpassen. Da gibt es aber selten Probleme, da ueblicherweise die Werte nicht so gross werden oder eh nicht gerechnet wird.

himitsu 12. Mär 2007 20:47

Re: Union Übersetzung nach Pascal
 
jetzt sag blos das zeigt was falsches an?

Robert: System.UInt64 :zwinker:

[add]
und jupp, dat sagt hier och klappt :gruebel:
obwohl ich demnach angeblich 8 Partitionen hier hab, statt nur 2.

Allerdings scheinen die weiteren Daten selber zu stimmen...
- die Daten der ersten 2 Records kommen anscheinend hin
- und die nachfolgenden Records sind mit 0 gefüllt

Robert Marquardt 13. Mär 2007 05:01

Re: Union Übersetzung nach Pascal
 
Oops, UInt64 ist aber ziemlich frisch bei Delphi.

himitsu 13. Mär 2007 09:51

Re: Union Übersetzung nach Pascal
 
Zitat:

Zitat von Robert Marquardt
Oops, UInt64 ist aber ziemlich frisch bei Delphi.

> http://www.delphipraxis.net/internal...=694376#694376

kommt drauf an, was man "frisch" nennt :roll:

@Neutral General:
also komisch ist das Ganze schon, denn ich hab für den Test mit deiner Funktion meine Definitionen verwendet.
Die Funktion ist ja i.O. und die Definitionen eigentlich uch, :stupid:
dennoch gehts nicht, obwohl das ganze in meinem Programm läuft, wo ja der "selbe" Code verwendet wird. :gruebel:

Robert Marquardt 13. Mär 2007 10:07

Re: Union Übersetzung nach Pascal
 
Zitat:

Zitat von himitsu
Delphi-Quellcode:
// ab Delphi 6:
Type DWord64 = System.UInt64;
   LargeWord = System.UInt64;


// und D1 bis D5:
Type DWord64 = Type System.Int64;
   LargeWord = Type System.Int64;

Haeh?
In welcher Unit ist das deklariert?

himitsu 13. Mär 2007 10:14

Re: Union Übersetzung nach Pascal
 
Liste der Anhänge anzeigen (Anzahl: 1)
Selbst erfunden?


Definiert is UInt64 seit Delphi 6 in der Unit System, oder besser gesagt als CompilerMagic im Compiler.

gammatester 13. Mär 2007 12:40

Re: Union Übersetzung nach Pascal
 
Zitat:

Zitat von himitsu
Selbst erfunden?


Definiert is UInt64 seit Delphi 6 in der Unit System, oder besser gesagt als CompilerMagic im Compiler.

Interessante Unit in Anhang. Allerdings ist zumindest der Kommentar in dem selbsterfundenen Zitat irreführend, denn auch

Delphi-Quellcode:
   // und D1 bis D5:
   Type DWord64 = Type System.Int64;
   LargeWord = Type System.Int64;
ist erst ab Delphi 4 übersetzbar (vorher gab's kein int64).

Gruß Gammmatester

Robert Marquardt 13. Mär 2007 12:59

Re: Union Übersetzung nach Pascal
 
Das muss .net sein. Nicht mal mein Turbo Delphi kennt UInt64 in System.pas. Es kommt kein Tooltip. Definitiv das Gleiche mit Delphi 6.

himitsu 13. Mär 2007 13:05

Re: Union Übersetzung nach Pascal
 
Int64 gab's auch schon vorher, nur kennt der Compiler es da unter 'nem anderem Namen ... wenn mir nur einfiele welchen :|

Die Unit selber ist zumindestens bis D4 vollständig kompatibel ... darunter konnte ich noch nicht so testen.

Hab zwar noch ein D1, aber dieses laß ich einfach mal außer Acht. :angel2:


D6 hab ich selber nicht, aber D5 kennt es definitiv noch nicht und D7 kennt es.
Hatte es anfangs als "Ab Dlphi 7" definiert, dann wurde mir von jemandem gesagt daß es schon in D6 existiere :gruebel:


Ich versuch mal den compilerinternen Namen nochmals rauszufinden *meld mich dann*


[add]
Zitat:

Das muss .net sein. Nicht
also die Unit ist rein Win32 ... das ganze .Net-Zeugs versuch ich noch zu ignorieren.

Hawkeye219 13. Mär 2007 15:00

Re: Union Übersetzung nach Pascal
 
Hallo Leute,

der Typ UInt64 ist zwar in Delphi definiert, er wurde aber nie offiziell von Borland dokumentiert. Der Grund könnte sein, daß nicht alle Operationen fehlerfrei ablaufen (getestet mit BDS 2006):

Delphi-Quellcode:
var
  u : System.UInt64;
begin
  u := $ffffffffffffffff;
  u := u div 10;
  ShowMessage(IntToStr(u));
end;
Gruß Hawkeye

gammatester 13. Mär 2007 15:21

Re: Union Übersetzung nach Pascal
 
Zitat:

Zitat von Hawkeye219
Hallo Leute,

der Typ UInt64 ist zwar in Delphi definiert, er wurde aber nie offiziell von Borland dokumentiert. Der Grund könnte sein, daß nicht alle Operationen fehlerfrei ablaufen

Kann aber nicht der Hauptgrund sein! Die ganze 64-Bit-Arithemtik ist ziemlich buggy, zB behaupten Delphi 4 bis 10 (2006), daß ein Quadrat negativ sein kann:

Delphi-Quellcode:
program sqr_babe;
 {$apptype console}
var
  Babe: int64;
begin
  Babe:=$Babe;
  writeln(sqr(Babe)<0);
end.

himitsu 13. Mär 2007 15:26

Re: Union Übersetzung nach Pascal
 
@Hawkeye219:
dieses liegt z.B. in D7 daran, daß die 64-Bit-Unsigned-Operationen nicht auf die entsprechenden (vorhandenen Funktionen verweisen, sondern dafür "einfach" die SignedFunktionen verwendet werden.

hmm, aber ging das nicht in BDS 2005 mal :gruebel:
Hatte doch damals 'nen Test diesbezüglich angeleiert ... mal sehn wo der sich hier rumtreibt.

Na ja, zumindest IntToStr sollte bei dir mit UInt64 laufen?


Ansonsten nutze ich selber für div/mul immernoch "eigene" Funktionen dafür ... und wenn das im BDS06 wieder nicht geht, dann isses ja gut, daß ich noch nicht umgestellt hab :)

himitsu 30. Mär 2007 14:28

Re: Union Übersetzung nach Pascal
 
Ach ja, warum die Partition nicht stimmen ... hier mal was aus'm PSDK.
Zitat:

DRIVE_LAYOUT_INFORMATION

PartitionCount
The number of partitions on a drive.
On disks with the MBR layout, this value is always a multiple of 4. Any partitions that are unused have a partition type of PARTITION_ENTRY_UNUSED.
Ich wußte doch es geht ... man muß halt nur auf mehr achten, als nur auf PartitionCount :roll:


In den Partitionstabellen (MBR) auf der Platte sind immer 4 Plätze und wo/ob da was drinsteht is sozusagen egal.

Bei mehr als 4 Partionen, werden dann einfach weitere Tabellen angelegt, welche dann als "erweiterte Partition" in einer vorhandenen Tabelle eingetragen sind.
(darum sind auch nur maximal 4 primäre Partitionen möglich)


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz