![]() |
Wie DVD Transfer mit ShrinkTo5.DLL?
Die ShrinkTo5.DLL mit der ShrinkTo5GUI waren mal Open Source und auch früher auf der OpenSourceCD. Da auf
![]() ![]() Die Funktionen scheinen bei beiden DLLs gleich zu sein. Das Auslesen der DVD-Informationen funktioniert jedenfalls genauso. Das Problem liegt nun beim DVD-Transfer (Transcodieren). Ich dachte, dass im Prinzip diese Funktionen ausreichen würden:
Code:
Die Callback-Procedure habe ich nicht übersetzt, weil ich nicht weiß, wie:
type
TFNOpen = function(srcPath: PChar): Integer; stdcall; TFNSetTargetSizeMB = function(targetSize: Integer): Integer; stdcall; TFNTransferPath = function(targetPath, stopFlag: PChar): Integer; stdcall; type TShrinkTo5 = Class private FNOpen : TFNOpen; FNSetTargetSizeMB : TFNSetTargetSizeMB; FNTransferPath : TFNTransferPath;
Code:
Nach dem Öffnen der DVD auf Festplatte und dem Setzen der Zielgröße sollte der Transfer mit diesem Aufruf starten:
void _stdcall SetCallBack(int (_stdcall *pCallBack)(int alert, int param, void *pTransfer, void *pUser), void *pUser)
Delphi-Quellcode:
Es gibt aber bei der DLL v1.7.1 eine Zugriffsverletzung nachdem der Ordner VIDEO_TS sowie die Datei VIDEO_TS.VOB angelegt wurden:
FNTransferPath(PChar(srcPath), PChar('0'));
Zitat:
Zitat:
|
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
:?
Über das Callback kommen zwei Arten von Alarmen herein. Einmal wenn ein neues Vorschaubild zur Verfügung und dann, wenn sich die Datei ändert. Der Absturz kommt, wenn die erste Datei transcodiert werden soll. Könnte also die Ursache in der fehlenden Callback-Routine liegen. |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Hallo,
void _stdcall SetCallBack(int (_stdcall *pCallBack)(int alert, int param, void *pTransfer, void *pUser), void *pUser) Lass dich nicht von den vielen * ärgern. int (_stdcall *pCallBack)(int alert, int param, void *pTransfer, void *pUser) Addresse einer int-Funktion. Im Unterschied zu Delphi kann man den kompletten Funktions-Kopf als Parameter schreiben, unter Delphi muss das per type definiert werden. (hast du ja bei den anderen Sachen schon gemacht). Mal so frei getippt. Die Parameter bekommst du bestimmt selber hin
Delphi-Quellcode:
Aufruf per SetCallBack(@CallBack, );
function CallBack(int alert, int param, void *pTransfer, void *pUser): Integer; stdcall;
procedure SetCallBack(int (CallBacl: Pointer; void *pUser); stdcall; Es wird einfach eine Adresse auf eine Funktion übergeben. Noch ein Link zu CallBacks. ![]() Heiko |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Hallo Heiko,
vielen Dank für Deine Antwort. Callbacks sind neu für mich. Das Beispiel von Luckie kann ich nachvollziehen, aber bei meinem Problem komme ich nicht viel weiter:
Delphi-Quellcode:
Bevor der Transfer starten soll, habe ich jetzt vorerst
type
... TFNCallBack = function(alert, param: Integer; pTransfer, pUser: Pointer): Integer; stdcall; TFNSetCallBack = procedure(pCallBack, pUser: Pointer); stdcall; ... TShrinkTo5 = Class private ... FCallBack: TFNCallBack; procedure SetCallBack(pCallBack, pUser: Pointer); stdcall; public property CallBack: TFNCallBack write FCallBack; ... end; procedure TShrinkTo5.SetCallBack(pCallBack, pUser: Pointer); var CallbackProc: TFNCallBack; begin @CallBackProc := PCallBack; // FCallBack(CallBackProc.); end;
Delphi-Quellcode:
zu stehen, wobei pUser = nil ist, weil ich noch nicht weiß, was ich damit anfangen soll.
FNSetCallBack(@FCallBack, pUser);
|
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Hallo,
Delphi-Quellcode:
hm ?
var
CallbackProc: TFNCallBack; begin @CallBackProc := PCallBack; Du musst doch die CalllBack-Prozedure selber noch definieren.
Delphi-Quellcode:
Und jetzt kommt das Gemeine.
function MyCallBack(alert, param: Integer; pTransfer, pUser: Pointer): Integer; stdcall;
begin Beep (0); ;) end; begin SetCallBack(@MyCallBack); Es darf keine Klassen-Methode sein !!! Grund: Klassen-Methoden haben einen unsichtbaren 1. Parameter (das Objekt selbst). Heiko |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Guten Abend,
Zitat:
Zitat:
Leider tritt danach immernoch der selbe Fehler in der DLL auf. In der Source der DLL ist eine Liste von Callbacks enthalten. Da ist steht zwar anstelle pUser pUserData drin, dürfte aber keinen Unterschied machen. Leider ist da kein Hinweis, was das sein soll. Muss mir mal die Source der GUI ansehen, vielleicht finde ich dort etwas. |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Hallo,
Lesen von Adresse 00000000 Das heisst NIL-Zugriff. Vielleicht muss ja ein gültiger User-Pointer übergeben werden, weil dort etwas durch die DLL reingeschrieben wird. Heiko |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Liste der Anhänge anzeigen (Anzahl: 2)
Was den Callback angeht, findet sich in der DoShrink.h
Code:
und in der DoShrink.cpp
virtual int CallBack(int alert, int param, void *pTransfer);
Code:
Zu den pUser/pUserData finde ich nichts. :wall:
// derived callback routine
int UserTransferAlert::CallBack(int alert, int param, void *pTransfer) { switch(alert) { case ALERT_PREVIEW_AVAIL: HBITMAP hprevBitmap; hprevBitmap = bmpStatic->SetBitmap((HBITMAP)param); DeleteObject(hprevBitmap); return 1; // we keep the current hbitmap default: return -1; } } Jetzt bekomme ich nach dem Start des Transfer die Zugriffsverletzung:
Code:
und anschließend
---------------------------
Anwendungsfehler --------------------------- Exception EAccessViolation in Modul ShrinkTo5.dll bei 0000D23D. Zugriffsverletzung bei Adresse 1000D23D in Modul 'ShrinkTo5.dll'. Lesen von Adresse 00000030. --------------------------- OK ---------------------------
Code:
Das ist unabhängig davon, ob das Callback gesetzt ist oder nicht.
---------------------------
Anwendungsfehler --------------------------- Exception EOSError in Modul ShrinkGUI.exe bei 0000DEBD. Systemfehler. Code: 5. Zugriff verweigert. --------------------------- OK --------------------------- Ich hänge mal mein Projekt und den ShrinkTo5 Source an. Vielleicht hat jemand Lust, drüber zu sehen. |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Hallo,
Zitat:
Was hast du denn bei PUser (pXXXX) jetzt angegeben. Heiko |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Ich habe pUser nur als Pointer deklariert und nil zugewiesen. Jetzt überlege ich, ob da eventuell der Pointer zu der Procedure hingehört, von welcher ich ein Callback möchte.
Was ich nicht verstehe: Transfer.h:
Code:
TransferAlert.cpp
// *** for alert receivers
// for C++ Languages: defines a CallBack to be overriden virtual int CallBack(int alert, int param, void *pTransfer); // defines the callback routine to be called when an alert is available // this function must be overwritten by a derived class // the last parameter can be reinterpreted (explicit cast) to (Transfer *) // for non C++ Languages: sets a pointer to a callback function // when calling the CallBack the pTransfer parameter points to Transfer Object and pUser to the user supplied data to this function virtual void SetCallBack(int (_stdcall *pCallBack)(int alert, int param, void *pTransfer, void *pUser), void *pUser);
Code:
// for non C++ Languages: sets a pointer to a callback function
void TransferAlert::SetCallBack(int (_stdcall *pCallBack)(int alert, int param, void *pTransfer, void *pUser), void *pUser) { this->pCallBack = pCallBack; this->pUser = pUser; } |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Hallo,
Zitat:
sprich von dir definierter Datenbereich, falls du mehrere CallBack-Methoden hast und die richtige wiederfinden willst. Ich würde einfach mal nen PInteger erzeugen und übergeben. Ich befürchte aber, dass der Fehler damit nicht behoben ist. Zeig doch noch mal den relevanten Code, besonders die Definition der CallBack-Methode und der Aufruf von SetCallBack. Heiko |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
In der Unit mit dem Formular:
Delphi-Quellcode:
Und in der Class TShrinkTo5:
function CallBack(alert, param: Integer; pTransfer, pUser: Pointer): Integer;
begin beep; end; ... ShrinkTo5.CallBack := CallBack; ...
Delphi-Quellcode:
So sieht die Procedure aus. Bin jetzt auf die Idee gekommen, das Projekt in OllyDebug (v2.0.0k von heute) anzusehen. Da steht dann
type
... TFNCallBack = function(alert, param: Integer; pTransfer, pUser: Pointer): Integer; stdcall; TFNSetCallBack = procedure(pCallBack, pUser: Pointer); stdcall; type TShrinkTo5 = Class private fCallBack : TFNCallBack; pUser : Pointer; ... public property CallBack : TFNCallBack write FCallBack; ... end; function TShrinkTo5.GetExecute: Integer; {******************************************************************************* * Den Transfer beginnen. } type TThreadParams = record FNTransferPath : TFNTransferPath; TransferPath : String; end; PThreadParams = ^TThreadParams; var ThreadParams : PThreadParams; hThread : THandle; ThreadID : Cardinal; lResult : Cardinal; function Thread(p: PThreadParams): Cardinal; var PTransferPath : PChar; PstopFlag : PChar; FNTransferPath : TFNTransferPath; lResult : Integer; begin PTransferPath := PChar(PThreadParams(p)^.TransferPath); PstopFlag := PChar('0'); FNTransferPath := PThreadParams(p)^.FNTransferPath; lResult := FNTransferPath(PTransferPath, PstopFlag); FreeMem(p, sizeof(TThreadParams)); if lResult < 0 then Result := $0FFFFFFF - lResult else Result := lResult; end; begin Result := 0; if DirectoryExists(fTransferPath) and Assigned(FNTransferPath) then try { * Das Callback setzen } pUser := nil; FNSetCallBack(@FCallBack, pUser); { * Den Arbeitsthread erstellen } GetMem(ThreadParams, sizeof(TThreadParams)); ThreadParams.FNTransferPath := FNTransferPath; ThreadParams.TransferPath := fTransferPath; hThread := BeginThread(nil, 0, @Thread, ThreadParams, 0, ThreadID); if hThread <> INVALID_HANDLE_VALUE then begin while WaitForSingleObject(hThread, 300) = WAIT_TIMEOUT do Application.ProcessMessages; { * return codes for TransferPath * >0 success - number of MegaBytes written * 0 user aborted (stopFlag == 1) * -2 if stream is scrambled and either descrambling failed or is disabled * -5 source was not opened with "Open" * -6 cannot authorize driveend; } end; finally GetExitCodeThread(hThread, lResult); end; if lResult > $0FFFfff0 then Result := lResult - $0FFFFFFF else Result := lResult; end;
Code:
Bei EAX steht 0000030. Was dann die Zugriffsverletzung darstellt.
1000D23D | 8038 01 | CMP Byte PTR DS: [EAX], 1
Ich finde es irritierend, dass der Parameter pUser nicht mitgegeben wird. pUser als PInteger zu deklarieren, bringt keine Änderung. |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Hallo,
function CallBack(alert, param: Integer; pTransfer, pUser: Pointer): Integer; Wo ist das stdcall ? Heiko |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Oh, das habe ich übersehen, als ich es hier rein kopiert habe.
Delphi-Quellcode:
function CallBack(alert, param: Integer; pTransfer, pUser: Pointer): Integer; stdcall;
implementation {$R *.dfm} function CallBack(alert, param: Integer; pTransfer, pUser: Pointer): Integer; begin beep; end; |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Es hängt wohl doch nicht am Callback. Der Fehler tritt mit und ohne Callback immer an der selben Stelle mit der selben Fehlermeldung auf. Irgendwie sollte sich herausfinden lassen, was die Original GUI anders macht!?
Nachtrag: Anscheinend wird bei der Original GUI auch kein Callback zugewiesen. Die Breakpoints scheinen bei Ollydbg nur bei statischen DLL zu funktionieren... |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Hallo,
was macht die denn anders ? Der Link in Thread #1 zeigt mir keine Download-Möglichkeit. Heiko |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Zitat:
![]() ![]() Ich habe mir die Original GUI mit OllyDbg angesehen. Die Einsprungpunkte, welche ich für meine dynamischen DLL hole, werden garnicht angesprungen. Es geht immer zu den anderen, welche bei diesen angegeben sind, zum Beispiel ?TransferPath@Transfer@@UAEHPAD0@Z. Da ich davon noch keine Ahnung habe, weiß ich nicht ob die von der GUI oder nur innerhalb der DLL angesprungen werden. Vielleicht sind auch nur meine Deklarationen falsch. Zuerst
Delphi-Quellcode:
Jetzt:
TFNTransferPath = function(targetPath, stopFlag: PChar): Integer; stdcall;
Delphi-Quellcode:
Vielleicht ist es ja immernoch falsch!?
TFNTransferPath = function(targetPath, stopFlag: PAnsiChar): Integer cdecl; stdcall;
Die übergebenen Pfade zeigt OllyDbg bei der Zugriffsverletzung richtig an. :wall: Werde mein Projekt jetzt erstmal auf statische Einbindung der DLL ändern. Vielleicht sehe ich dann mehr. |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Hallo,
noch mal drübergeflogen ... FNTransferPath(PChar(srcPath), PChar('0')); hmmmmmm .... srcPath : String -> OK, ist kompatibel mit PChar PChar('0') das würde ich ändern, var sFlag: String = '0'; PChar(Flag) Hast du vielleicht noch irgendwelche Return-Strings, die due paar PChar(StringVar) übergibst (ohne SetLength), dann geht der Schreibzugriff ins Nirvana. Früher habe ich immer array[0..XXX] of Char benutzt + die explizite Umformung von Strng nach PChar (SrrPas usw.) Heiko |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Liste der Anhänge anzeigen (Anzahl: 1)
Den Aufruf habe ich zwischenzeitlich in einen Thread ausgelagert:
Delphi-Quellcode:
Was ich nicht verstehe ist, dass ich die Struktur der DVD auslesen kann und der Unterordner VIDEO_TS im Zielordner angelegt wird.
PTransferPath := PAnsiChar(PThreadParams(p)^.TransferPath);
PstopFlag := PAnsiChar('0'); FNTransferPath := PThreadParams(p)^.FNTransferPath; lResult := FNTransferPath(PTransferPath, PstopFlag); FreeMem(p, sizeof(TThreadParams)); |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Liste der Anhänge anzeigen (Anzahl: 1)
So, jetzt habe ich die DLL statisch eingebunden. Es tritt - wie eigentlich zu erwarten war - der selbe Fehler auf. Mal sehen, ob etwas in OllyDbg zu sehen ist.
|
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Zitat:
|
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Habe es jetzt mit StrPCopy versucht. Es hat aber nichts genutzt.
So bekomme ich einen Ordner VIDEO_TS und die VIDEO_TS.VOB wird angelegt:
Delphi-Quellcode:
Und so bekomme ich nur den Ordner:
function TShrinkTo5.GetExecute: Integer;
var StopFlag : String; begin StopFlag := '0'; Result := FNTransferPath(PChar(fTransferPath), PChar(stopFlag)); end;
Delphi-Quellcode:
:wall:
function TShrinkTo5.GetExecute: Integer;
type TThreadParams = record TransferPath : String; end; PThreadParams = ^TThreadParams; var ThreadParams : PThreadParams; hThread : THandle; ThreadID : Cardinal; lResult : Cardinal; function Thread(p: PThreadParams): Cardinal; var PTransferPath : PAnsiChar; PStopFlag : PAnsiChar; lResult : Integer; begin PTransferPath := PAnsiChar(PThreadParams(p)^.TransferPath); PStopFlag := PAnsiChar('0'); lResult := FNTransferPath(PTransferPath, PStopFlag); FreeMem(p, sizeof(TThreadParams)); if lResult < 0 then Result := $0FFFFFFF - lResult else Result := lResult; end; begin Result := 0; hThread := 0; if DirectoryExists(fTransferPath) then try { * Den Arbeitsthread erstellen } GetMem(ThreadParams, sizeof(TThreadParams)); ThreadParams.TransferPath := fTransferPath; hThread := BeginThread(nil, 0, @Thread, ThreadParams, 0, ThreadID); if hThread <> INVALID_HANDLE_VALUE then begin while WaitForSingleObject(hThread, 300) = WAIT_TIMEOUT do Application.ProcessMessages; { * return codes for TransferPath * >0 success - number of MegaBytes written * 0 user aborted (stopFlag == 1) * -2 if stream is scrambled and either descrambling failed or is disabled * -5 source was not opened with "Open" * -6 cannot authorize driveend; } end; finally GetExitCodeThread(hThread, lResult); end; if lResult > $0FFFfff0 then Result := lResult - $0FFFFFFF else Result := lResult;} end; |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
In beiden Fällen wird die VIDEO_TS.IFO gelesen und der Fehler geschieht beim Lesen der VIDEO_TS.VOB. Die Original-GUI verarbeitet die DVD.
Bei der Original-GUI werden keine Einsprungpunkte der Exports, welche mein Projekt verwendet, angesprungen. Ich weiß allerdings nicht, ob dies auf die unterschiedlichen Programmiersprachen zurück zu führen ist. Beim Start der Original-GUI wird ein TransferAlert gesetzt und ein paar Voreinstellungen vorgenommen. Beim Öffnen passiert bei beiden im Prinzip dasselbe. Bevor der Transfer gestartet wird, werden noch einmal ein paar Einstellungen vorgenommen, welche nicht ins Gewicht fallen dürften. Nach Start des Transfer werden die Pfad- und Dateinamen mehrfach hin- und hergeschubst. Vielleicht liegt es an dem TransferAlert!? Damit wird auch eine Änderung der zu verarbeitenden Datei gemeldet. |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Beim Erstellen der Original-GUI werden noch die Proceduren
Code:
aufgerufen. Das sind zwei Klassen. Die Funktionen, welche genutzt werden, gehören zur Klasse Transfer.
1000CEF0 - ??0Transfer@@QAE@XZ
1000E4B0 - ??0TransferAlert@@Q |
Re: Wie DVD Transfer mit ShrinkTo5.DLL?
Ich frage mich, ob es richtig war, nur die C Exports zu nehmen:
![]() |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:59 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz