Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus-es / 2014-10

problema con Unicode y CreateFileW

9 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

J.Alejandro Martinez Linares

Hola estoy tratando de reparar una versi�n de supercopier que es un programa para copiar archivos y carpetas pero justo en la seccion que les pongo abajo cada vez que el sitema se encuentra una carpeta con tildes el sistema me da una excepci�n notificandome que no tiene acceso, y justo en el fragmento que les muestro es donde el sistema se engancha ,
en "HSrcINVALID_HANDLE_VALUE" se supne que no varien y var�a y es solo cuando encuntra como dije antes una carpeta con tilde ya he probado con archivos con tilde y no pasa, al igual que con � y tampoco nada, solo las carpetas con tildes son lo que estropea todo, ayudeneme a entender que es lo que sucede ac�, gracias,

HSrc:=Windows.CreateFileW(PWideChar(UTF8Decode(SourceFile)), GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED
or
IfThen(SourceIsNetwork,0,FILE_FLAG_NO_BUFFERING),

                             0);
         RaiseCopyErrorIfNot(HSrcINVALID_HANDLE_VALUE);

Saludos A todos y gracias de antemano.

Nunca digas nunca, di mejor: gracias, permiso, disculpe. Este mensaje le ha llegado mediante el servicio de correo electronico que ofrece Infomed para respaldar el cumplimiento de las misiones del Sistema Nacional de Salud. La persona que envia este correo asume el compromiso de usar el servicio a tales fines y cumplir con las regulaciones establecidas Infomed: http://www.sld.cu/

Reply by email

José Mejuto
to J.Alejandro Martinez Linares

El 14/10/2014 a las #4, J.Alejandro Martinez Linares escribi�:

Show quoted text 5 lines
Hola estoy tratando de reparar una versi�n de supercopier que es un programa para copiar archivos y carpetas pero justo en la seccion que les pongo abajo cada vez que el sitema se encuentra una carpeta con tildes el sistema me da una excepci�n notificandome que no tiene acceso, y justo en el fragmento que les muestro es donde el sistema se engancha

Hola,

Deber�as de mostrar tambi�n de donde sacas SourceFile, si es un ansistring, un utf8string o qu�.

Reply by email

islanis en infomed.sld.cu
to José Mejuto

OK, para que no quede mas dudas ac� env�o el archivo SCWideUnbufferedCopier.pas,que es donde se encuentra todo lo que me pides si a�n tienes mas dudas pues me preguntas o quedamos y te env�o la fuente del proyecto completo si por aca podemos resolver el problema pues para alante, que espero que si.
Saludos Ale

//--------------------------SCWideUnbufferedCopier.pas------------------- {
This file is part of SuperCopier.

SuperCopier is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

SuperCopier is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
}

unit SCWideUnbufferedCopier;
{$MODE Delphi}
interface
uses
   Windows,Messages,SCCopier, lclproc, Dialogs;
const
   MAX_WAITING_IO=16; // nombre max d'I/O en attente
   READ_ENDING_EVENT=0;
   WRITE_ENDING_EVENT=1;
   WORK_EVENT=2;
   READ_ENDING_EVENT_NAME='SC2 Read ending';
   WRITE_ENDING_EVENT_NAME='SC2 Write ending';
   WORK_EVENT_NAME='SC2 Work';
   ENABLE_32K_CHARS_PATH='\\?\';
type
   TWideUnbufferedCopier=class(TCopier)
   private
     SrcOvr,DestOvr:TOverlapped;
     Events:array[0..2] of THandle;
     Buffer:PByte;
     FullBufferSize:Cardinal;
   protected
     procedure SetBufferSize(Value:cardinal);override;
   public
     constructor Create;
     destructor Destroy;override;
     function DoCopy:Boolean;override;
   end;
implementation
uses SCCommon,SCLocStrings,SCWin32,SysUtils,Math;
//******************************************************************************
//******************************************************************************
//******************************************************************************
// TWideUnbufferedCopier: descendant de TCopier, copie non
bufferisйe asynchrone
//                        gйrant l'unicode
//******************************************************************************
//******************************************************************************
//******************************************************************************
//******************************************************************************
// Create
//******************************************************************************
constructor TWideUnbufferedCopier.Create;
   // MakeUnique: ajoute un identifiant unique de Copier а S
   function MakeUnique(S:String):String;
   begin
     Result:=S+IntToStr(Cardinal(Self));
   end;
begin
   inherited;
   FBufferSize:=0;
   // crйer les йvиnements pour le copier
Events[READ_ENDING_EVENT]:=Windows.CreateEvent(nil,True,False,PChar(MakeUnique(READ_ENDING_EVENT_NAME)));
Events[WRITE_ENDING_EVENT]:=Windows.CreateEvent(nil,True,False,PChar(MakeUnique(WRITE_ENDING_EVENT_NAME)));
Events[WORK_EVENT]:=Windows.CreateEvent(nil,True,False,PChar(MakeUnique(WORK_EVENT_NAME)));
   if (Events[READ_ENDING_EVENT]=INVALID_HANDLE_VALUE) or
      (Events[WRITE_ENDING_EVENT]=INVALID_HANDLE_VALUE) or
      (Events[WORK_EVENT]=INVALID_HANDLE_VALUE) then
   begin
     raise Exception.Create('Failed to create copy events');
   end;
   // associer les йvиnements aux structures Overlapped
   SrcOvr.hEvent:=Events[READ_ENDING_EVENT];
   DestOvr.hEvent:=Events[WRITE_ENDING_EVENT];
end;
//******************************************************************************
// Destroy
//******************************************************************************
destructor TWideUnbufferedCopier.Destroy;
begin
   SetBufferSize(0);
   // dйtruire les йvиnements
   FileClose(Events[READ_ENDING_EVENT]); { *Converted from CloseHandle*  }
   FileClose(Events[WRITE_ENDING_EVENT]); { *Converted from CloseHandle*  }
   FileClose(Events[WORK_EVENT]); { *Converted from CloseHandle*  }
   inherited;
end;
//******************************************************************************
// SetBufferSize: fixe la taille du buffer de copie
//******************************************************************************
procedure TWideUnbufferedCopier.SetBufferSize(Value:cardinal);
begin
   if ValueFBufferSize then
   begin
     FBufferSize:=Value;
     FullBufferSize:=FBufferSize*MAX_WAITING_IO;
     VirtualFree(Buffer,0,MEM_RELEASE); // on libиre le
prйcйdent buffer allouй
     Buffer:=VirtualAlloc(nil,FullBufferSize,MEM_COMMIT,PAGE_READWRITE);
   end;
end;
//******************************************************************************
// DoCopy: renvoie false si la copie йchoue
//******************************************************************************
function TWideUnbufferedCopier.DoCopy:boolean;
   function OnlyFullChunks(Size:Int64):Int64;
   begin
     Result:=Size-Size mod FBufferSize;
   end;
var HSrc,HDest,HBufferedDest:THandle;
     SourceFile,DestFile:WideString;
     ReadPending,WritePending,ReadEnd,WriteEnd:Boolean;
     BytesProcessed,UsedBuffer:Cardinal;
     Ok,ContinueCopy:Boolean;
     ReadPos,WritePos:Int64;
     ReadPosRec:Int64Rec absolute ReadPos;
     WritePosRec:Int64Rec absolute WritePos;
     LastError:Cardinal;
     SourceIsNetwork,DestIsNetwork:Boolean;
begin
   Assert(Assigned(OnCopyProgress),'OnCopyProgress not assigned');
   Result:=True;
   with CurrentCopy do
   begin
     ContinueCopy:=True;
     CopiedSize:=0;
     SkippedSize:=0;
     UsedBuffer:=0;
     ReadPending:=False;
     WritePending:=False;
     ReadEnd:=False;
     WriteEnd:=False;
     ReadPos:=0;
     WritePos:=0;
     SourceFile:=FileItem.SrcFullName;
     DestFile:=FileItem.DestFullName;
     SourceIsNetwork:=PathIsNetworkPath(PWideChar(SourceFile));
     DestIsNetwork:=PathIsNetworkPath(PWideChar(DestFile));
     // gйrer les chemins de plus de MAX_PATH caractиres
     if not PathIsUNC(PWideChar(SourceFile)) then
SourceFile:=ENABLE_32K_CHARS_PATH+SourceFile;
     if not PathIsUNC(PWideChar(DestFile)) then
DestFile:=ENABLE_32K_CHARS_PATH+DestFile;
     Inc(FileItem.CopyTryCount);
     try
       HSrc:=INVALID_HANDLE_VALUE;
       HDest:=INVALID_HANDLE_VALUE;
       HBufferedDest:=INVALID_HANDLE_VALUE;
       try
         // on ouvre le fichier source
         //ShowMessage(UTF8Decode(SourceFile));
         HSrc:=Windows.CreateFileW(PWideChar(UTF8Decode(SourceFile)),
                             GENERIC_READ,
                             FILE_SHARE_READ or FILE_SHARE_WRITE,
                             nil,
                             OPEN_EXISTING,
                             FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED
                             or
IfThen(SourceIsNetwork,0,FILE_FLAG_NO_BUFFERING),
                             0);
         RaiseCopyErrorIfNot(HSrcINVALID_HANDLE_VALUE);
         // effacer les attributs du fichier de destination pour
pouvoir l'ouvrir en йcriture
         FileItem.DestClearAttributes;
         // on ouvre le fichier de destination
         if NextActioncpaRetry then // doit-on reprendre le transfert?
         begin
           HDest:=CreateFileW(PWideChar(UTF8Decode(DestFile)),
                               GENERIC_WRITE,
                               FILE_SHARE_READ or FILE_SHARE_WRITE,
                               nil,
                               CREATE_ALWAYS,
                               FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED
                               or

IfThen(DestIsNetwork,0,FILE_FLAG_NO_BUFFERING),

                               0);
           RaiseCopyErrorIfNot(HDestINVALID_HANDLE_VALUE);
           // on ouvre un handle sur le fichier de destination en

bufferisй pour pouvoir

           // fixer le fichier а la bonne taille (en non

bufferisй, on ne peut copier

           // que des blocs de taille multiple de celle d'une page

mйmoire)

           HBufferedDest:=CreateFileW(PWideChar(UTF8Decode(DestFile)),
                                       GENERIC_WRITE,
                                       FILE_SHARE_READ or FILE_SHARE_WRITE,
                                       nil,
                                       CREATE_ALWAYS,
                                       FILE_ATTRIBUTE_NORMAL,
                                       0);
           RaiseCopyErrorIfNot(HBufferedDestINVALID_HANDLE_VALUE);
         end
         else
         begin
           HDest:=CreateFileW(PWideChar(UTF8Decode(DestFile)),
                               GENERIC_WRITE,
                               FILE_SHARE_READ or FILE_SHARE_WRITE,
                               nil,
                               OPEN_ALWAYS,
                               FILE_ATTRIBUTE_NORMAL or

FILE_FLAG_NO_BUFFERING or FILE_FLAG_OVERLAPPED,

                               0);
           RaiseCopyErrorIfNot(HDestINVALID_HANDLE_VALUE);
           HBufferedDest:=CreateFileW(PWideChar(UTF8Decode(DestFile)),
                                       GENERIC_WRITE,
                                       FILE_SHARE_READ or FILE_SHARE_WRITE,
                                       nil,
                                       OPEN_ALWAYS,
                                       FILE_ATTRIBUTE_NORMAL,
                                       0);
           RaiseCopyErrorIfNot(HBufferedDestINVALID_HANDLE_VALUE);
           SkippedSize:=OnlyFullChunks(FileItem.DestSize);
           Self.SkippedSize:=Self.SkippedSize+SkippedSize;
         end;
         // on aggrandit fichier de destination a au moins sa taille finale
         // (pour йviter la fragmentation et pour que
l'overlapped fonctionne correctement)
RaiseCopyErrorIfNot(SetFileSize(HDest,OnlyFullChunks(FileItem.SrcSize)+FBufferSize));
         // on amorce le systиme
         ReadPos:=SkippedSize;
         WritePos:=SkippedSize;
         SetEvent(Events[WORK_EVENT]);
         if FileItem.SrcSize>0 then // aucun traitemeant a faire pour
les fichiers vides
         begin
           while not (ReadEnd and WriteEnd) and ContinueCopy  do
           begin
             // on attends qu'un йvиnement se produise
             case
WaitForMultipleObjects(Length(Events), en Events[0],False,INFINITE) of
               WAIT_OBJECT_0+READ_ENDING_EVENT:
               begin
                 ResetEvent(Events[READ_ENDING_EVENT]);
                 ReadPending:=False;
RaiseCopyErrorIfNot(GetOverlappedResult(HSrc,SrcOvr,BytesProcessed,True));
                 ReadPos:=ReadPos+BytesProcessed;
                 UsedBuffer:=UsedBuffer+BytesProcessed;
                 ReadEnd:=ReadPos>=FileItem.SrcSize;
                 // on lance la lecture suivante
                 SetEvent(Events[WORK_EVENT]);
               end;
               WAIT_OBJECT_0+WRITE_ENDING_EVENT:
               begin
                 ResetEvent(Events[WRITE_ENDING_EVENT]);
                 WritePending:=False;
RaiseCopyErrorIfNot(GetOverlappedResult(HDest,DestOvr,BytesProcessed,True));
                 WritePos:=WritePos+BytesProcessed;
                 UsedBuffer:=UsedBuffer-BytesProcessed;
                 WriteEnd:=WritePos>=FileItem.SrcSize;
                 // on lance l'йcriture suivante
                 SetEvent(Events[WORK_EVENT]);
                 // des donnйes ont йtйs
йcrites -> on dйclenche l'evenement de progression
                   // ne pas compter le dйpassement de la taille
du fichier
                 if WriteEnd then
BytesProcessed:=BytesProcessed-(WritePos-FileItem.SrcSize);
                 CopiedSize:=CopiedSize+BytesProcessed;
                 Self.CopiedSize:=Self.CopiedSize+BytesProcessed;
                 ContinueCopy:=OnCopyProgress;
               end;
               WAIT_OBJECT_0+WORK_EVENT:
               begin
                 ResetEvent(Events[WORK_EVENT]);
                 // on lance une lecture si il n'y en a pas en cours
et si le buffer n'est pas plein
                 if not ReadEnd and not ReadPending and
(FullBufferSize-UsedBuffer>=FBufferSize) then
                 begin
                   SrcOvr.Offset:=ReadPosRec.Lo;
                   SrcOvr.OffsetHigh:=ReadPosRec.Hi;
                   // on vйrifie que l'on est pas en buffer overflow
                   if (Abs((WritePos-ReadPos) mod
FullBufferSize)>FBufferSize) or not WritePending then
                   begin
                     Ok := Windows.ReadFile(HSrc,
Pointer(Cardinal(Buffer)+SrcOvr.Offset mod FullBufferSize)^,
FBufferSize, BytesProcessed, @SrcOvr);
                     ReadPending:=GetLastError=ERROR_IO_PENDING;
                     RaiseCopyErrorIfNot(Ok or ReadPending);
                     if not ReadPending then
SetEvent(Events[READ_ENDING_EVENT]); // si l'i/o est synchrone, on
dйclenche l'evenement a la main
                   end;
                 end;
                 // on lance une йcriture si il n'y en a pas en
cours et si il y a au moins un bloc de lu
                 if not WriteEnd and not WritePending and
((UsedBuffer>=FBufferSize) or ReadEnd) then
                 begin
                   DestOvr.Offset:=WritePosRec.Lo;
                   DestOvr.OffsetHigh:=WritePosRec.Hi;
                   // on vйrifie que l'on est pas en buffer overflow
                   if (Abs((WritePos-ReadPos) mod
FullBufferSize)>FBufferSize) or not ReadPending then
                   begin
Ok:=WriteFile(HDest,Pointer(Cardinal(Buffer)+DestOvr.Offset mod
FullBufferSize)^,FBufferSize,BytesProcessed, en DestOvr);
                     WritePending:=GetLastError=ERROR_IO_PENDING;
                     RaiseCopyErrorIfNot(Ok or WritePending);
                     if not WritePending then
SetEvent(Events[WRITE_ENDING_EVENT]); // si l'i/o est synchrone, on
dйclenche l'evenement a la main
                   end;
                 end;
               end;
             end;
           end;
         end;
         // on fixe le fichier а la bonne taille en utilisant le
handle bufferisй
         RaiseCopyErrorIfNot(SetFileSize(HBufferedDest,FileItem.SrcSize));
         // copie de la date de modif
         CopyFileAge(HSrc,HDest);
         CopyFileAge(HSrc,HBufferedDest);
       finally
         LastError:=GetLastError;
         // on dйclare la position courrante dans le fichier
destination comme fin de fichier
         SetFileSize(HBufferedDest,CopiedSize+SkippedSize); //TODO:
ajouter gestion des erreurs !!!
         // fermeture des handles si ouverts
         FileClose(HSrc); { *Converted from CloseHandle*  }
         FileClose(HDest); { *Converted from CloseHandle*  }
         FileClose(HBufferedDest); { *Converted from CloseHandle*  }
         SetLastError(LastError); // ne pas polluer le code d'erreur
         NextAction:=cpaNextFile;
       end;
     except
       on E:ECopyError do
       begin
         dbgln(GetLastError);
         Result:=False;
         CopyError;
       end;
     end;
   end;
end;
end.
//---------------------------------------------------------------------------

Jos� Mejuto <joshyfun en gmail.com> escribi�:

Show quoted text 20 lines
El 14/10/2014 a las #4, J.Alejandro Martinez Linares escribi�: > Hola estoy tratando de reparar una versi�n de supercopier que es un > programa para copiar archivos y carpetas pero justo en la seccion que > les pongo abajo cada vez que el sitema se encuentra una carpeta con > tildes el sistema me da una excepci�n notificandome que no tiene acceso, > y justo en el fragmento que les muestro es donde el sistema se engancha Hola, Deber�as de mostrar tambi�n de donde sacas SourceFile, si es un ansistring, un utf8string o qu�. -- _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es

---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.

Nunca digas nunca, di mejor: gracias, permiso, disculpe. Este mensaje le ha llegado mediante el servicio de correo electronico que ofrece Infomed para respaldar el cumplimiento de las misiones del Sistema Nacional de Salud. La persona que envia este correo asume el compromiso de usar el servicio a tales fines y cumplir con las regulaciones establecidas Infomed: http://www.sld.cu/

Reply by email

islanis en infomed.sld.cu
to José Mejuto: El 14/10/2014 a las #4, J.Alejandro Martinez Linares escribi�: Deber�as de mostrar…

uff y veo que se me quedaron algunas cosillas importantes,bueno ac� se los dejo mejor y mas reducido de donde sale sourcefile

SourceFile:=FileItem.SrcFullName;

y FileItem sale de la clase TCopier es de tipo TFileItem

o sea que sal de ac�

CurrentCopy:record
			FileItem:TFileItem;
			DirItem:TDirItem;
			CopiedSize,SkippedSize:Int64;
			NextAction:TCopyAction;
		end;

y ac� les dejo la clase TFileItem

Saludos Ale y gracias de antemano

//-----------------SCFileList.pas--------------------------------- {
This file is part of SuperCopier.

SuperCopier is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

SuperCopier is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
}

unit SCFileList;
{$MODE Delphi}
interface
uses SCCommon,SCDirList,Classes,SCObjectThreadList, FileUtil, Windows;
const
   FILELIST_DATA_VERSION=001;
type
	TFileList=class;
	TFileItem=class
	private
     Owner:TFileList;
	public
     BaseListId:Integer;
     CopyTryCount:Integer;
		SrcName,
		DestName:WideString;
		SrcSize:Int64;
		Directory:TDirItem;
     procedure SaveToStream(TheStream:TStream);
     procedure
LoadFromStream(TheStream:TStream;Version:integer;BaseDirListIndex:Integer);
		function SrcFullName:WideString;
		function DestFullName:WideString;
		function DestSize:Int64;
		function SrcAge:Integer;
		function DestAge:Integer;
		function SrcExists:Boolean;
		function DestExists:Boolean;
		function DestIsSameFile:Boolean;
     function SrcDelete:Boolean;
     function DestDelete:Boolean;
     function DestCopyAttributes:boolean;
     function DestCopySecurity:boolean;
     function DestClearAttributes:boolean;
	end;
	TFileList = class (TObjectThreadList)
   private
     FDirList:TDirList;
     FSortMode:TFileListSortMode;
     FSortReverse:Boolean;
	protected
		function Get(Index: Integer): TFileItem;
		procedure Put(Index: Integer; Item: TFileItem);
	public
		TotalCount:cardinal;
		TotalSize,Size:Int64;
		constructor Create(PDirList:TDirList);
		destructor Destroy; override;
     procedure SaveToStream(TheStream:TStream);
     procedure LoadFromStream(TheStream:TStream);
		function Add(Item: TFileItem): Integer;
		procedure Delete(Index: Integer;UpdateTotalCount:Boolean=False);
     procedure Sort;
		property Items[Index: Integer]: TFileItem read Get write Put; default;
     property SortMode:TFileListSortMode read FSortMode write FSortMode;
     property SortReverse:Boolean read FSortReverse write FSortReverse;
	end;
implementation
uses SCWin32,SysUtils,LCLIntf, LCLType, LMessages, Contnrs, Math;
function FLSortCompare(Item1,Item2:Pointer):Integer;forward;
//******************************************************************************
//******************************************************************************
//******************************************************************************
// TFileItem: fichier &#1072; copier
//******************************************************************************
//******************************************************************************
//******************************************************************************
procedure TFileItem.SaveToStream(TheStream:TStream);
var Len,Idx:Integer;
begin
   // version 1
     // On ne peut pas sauvegarder un pointeur, on sauvegarde l'index
a la place
     // L'index commence de la fin de la liste pour pouvoir retrouver
le DirItem
     // au chargement alors que la DirList est d&#1081;j&#1072; charg&#1081;e
   Idx:=Owner.FDirList.Count-1-Owner.FDirList.IndexOf(Directory);
   TheStream.Write(Idx,SizeOf(Integer));
   Len:=Length(SrcName);
   TheStream.Write(Len,SizeOf(Integer));
   TheStream.Write(SrcName[1],Len*SizeOf(WideChar));
   Len:=Length(DestName);
   TheStream.Write(Len,SizeOf(Integer));
   TheStream.Write(DestName[1],Len*SizeOf(WideChar));
   TheStream.Write(SrcSize,SizeOf(Int64));
end;
procedure
TFileItem.LoadFromStream(TheStream:TStream;Version:integer;BaseDirListIndex:Integer);
var Len,Idx:Integer;
begin
   if Version>=001 then
   begin
     TheStream.Read(Idx,SizeOf(Integer));
       // on r&#1081;cup&#1080;re le DirItem en retranchant &#1072;
l'index du dernier item de DirList
       // l'index sauvegard&#1081;
     Directory:=Owner.FDirList[BaseDirListIndex-Idx];
     TheStream.Read(Len,SizeOf(Integer));
     SetLength(SrcName,Len);
     TheStream.Read(SrcName[1],Len*SizeOf(WideChar));
     TheStream.Read(Len,SizeOf(Integer));
     SetLength(DestName,Len);
     TheStream.Read(DestName[1],Len*SizeOf(WideChar));
     TheStream.Read(SrcSize,SizeOf(Int64));
   end;
end;
function TFileItem.SrcFullName:WideString;
begin
   Result:=Concat(Directory.SrcPath,SrcName);
end;
function TFileItem.DestFullName:WideString;
begin
   Result:=Concat(Directory.DestPath,DestName);
end;
function TFileItem.DestSize:Int64;
begin
   Result:=SCCommon.GetFileSizeByName(DestFullName);
end;
function TFileItem.SrcAge:Integer;
begin
	Result:=FileAge(SrcFullName);
end;
function TFileItem.DestAge:Integer;
begin
	Result:=FileAge(DestFullName);
end;
function TFileItem.DestExists:Boolean;
begin
	Result:=FileAge(DestFullName)-1;
end;
function TFileItem.SrcExists: Boolean;
begin
	Result:=FileAge(SrcFullName)-1;
end;
function TFileItem.DestIsSameFile:Boolean;
begin
	// Deux fichiers sont consid&#1081;r&#1081;s identiques lorsque ils
ont la m&#1082;me taille et la m&#1082;me date de derni&#1080;re modif
	Result:=(SrcSize=DestSize) and (SrcAge=DestAge);
end;
function TFileItem.SrcDelete:Boolean;
var ErrCode:Integer;
   //HACK: la gestion interne de l'unicode de delphi pourrit le code
d'erreur win32
   //      lors du retour d'une fonction, ceci permets de le conserver
   procedure SrcDelete_;
   begin
     Result:=SCWin32.DeleteFile(PWideChar(SrcFullName)); { *Converted
from DeleteFile*  }
     ErrCode:=GetLastOSError;
   end;
begin
   SrcDelete_;
   Windows.SetLastError(ErrCode);
end;
function TFileItem.DestDelete:Boolean;
var ErrCode:Integer;
   //HACK: la gestion interne de l'unicode de delphi pourrit le code
d'erreur win32
   //      lors du retour d'une fonction, ceci permets de le conserver
   procedure DestDelete_;
   begin
     Result:=SCWin32.DeleteFile(PWideChar(DestFullName)); { *Converted
from DeleteFile*  }
     ErrCode:=GetLastError;
   end;
begin
   DestDelete_;
   SetLastError(ErrCode);
end;
function TFileItem.DestCopyAttributes:Boolean;
var Attr:Cardinal;
     ErrCode:Integer;
   //HACK: la gestion interne de l'unicode de delphi pourrit le code
d'erreur win32
   //      lors du retour d'une fonction, ceci permets de le conserver
   procedure DestCopyAttributes_;
   begin
     Attr:=SCWin32.GetFileAttributes(PWideChar(SrcFullName));
     Result:=Attr$ffffffff;
     if Result then
Result:=SCWin32.SetFileAttributes(PWideChar(DestFullName),Attr);
     ErrCode:=GetLastError;
   end;
begin
   DestCopyAttributes_;
   SetLastError(ErrCode);
end;
function TFileItem.DestCopySecurity:boolean;
var ErrCode:Integer;
   //HACK: la gestion interne de l'unicode de delphi pourrit le code
d'erreur win32
   //      lors du retour d'une fonction, ceci permets de le conserver
   procedure DestCopySecurity_;
   begin
     Result:=CopySecurity(SrcFullName,DestFullName);
     ErrCode:=GetLastError;
   end;
begin
   DestCopySecurity_;
   SetLastError(ErrCode);
end;
function TFileItem.DestClearAttributes:boolean;
var ErrCode:Integer;
   //HACK: la gestion interne de l'unicode de delphi pourrit le code
d'erreur win32
   //      lors du retour d'une fonction, ceci permets de le conserver
   procedure DestClearAttributes_;
   begin
Result:=SCWin32.SetFileAttributes(PWideChar(DestFullName),FILE_ATTRIBUTE_NORMAL);
     ErrCode:=GetLastError;
   end;
begin
   DestClearAttributes_;
   SetLastError(ErrCode);
end;
//******************************************************************************
//******************************************************************************
//******************************************************************************
// TFileList: liste de fichiers &#1072; copier
//******************************************************************************
//******************************************************************************
//******************************************************************************
procedure TFileList.SaveToStream(TheStream:TStream);
var i,Num,Version:integer;
begin
   Version:=FILELIST_DATA_VERSION;
   TheStream.Write(Version,SizeOf(Integer));
   Num:=Count;
   TheStream.Write(Num,SizeOf(Integer));
   for i:=0 to Num-1 do
   begin
     Items[i].SaveToStream(TheStream);
   end;
end;
procedure TFileList.LoadFromStream(TheStream:TStream);
var i,Num,Version:integer;
     FileItem:TFileItem;
     BaseDirListIndex:Integer;
begin
   Version:=000;
   Num:=0;
   TheStream.Read(Version,SizeOf(Integer));
   if Version>FILELIST_DATA_VERSION then raise
Exception.Create('FileItems: data file is for a newer SuperCopier
version');
   TheStream.Read(num,SizeOf(Integer));
   BaseDirListIndex:=FDirList.Count-1;
   for i:=0 to Num-1 do
   begin
     FileItem:=TFileItem.Create;
     FileItem.Owner:=Self;
     FileItem.LoadFromStream(TheStream,Version,BaseDirListIndex);
     Add(FileItem);
   end;
end;
function TFileList.Add(Item: TFileItem): Integer;
begin
	// maj des compteurs
	Inc(Size,Item.SrcSize);
   Inc(TotalSize,Item.SrcSize);
   Inc(TotalCount,1);
   Item.Owner:=Self;
	Result:=inherited Add(Item);
end;
procedure TFileList.Delete(Index: Integer;UpdateTotalCount:Boolean=False);
begin
	// maj des compteurs
   if Items[Index]nil then
   begin
     Dec(Size,Items[Index].SrcSize);
     if UpdateTotalCount then
     begin
       Dec(TotalSize,Items[Index].SrcSize);
       Dec(TotalCount,1);
     end;
   end;
	inherited Delete(Index);
end;
function TFileList.Get(Index: Integer): TFileItem;
begin
	Result:=TFileItem(inherited Get(Index));
end;
procedure TFileList.Put(Index: Integer; Item: TFileItem);
begin
	inherited Put(Index,Item);
end;
constructor TFileList.Create(PDirList:TDirList);
begin
	inherited Create;
   // init des variables
	TotalCount:=0;
	TotalSize:=0;
   Size:=0;
   FDirList:=PDirList;
   FSortMode:=fsmNone;
   FSortReverse:=False;
end;
destructor TFileList.Destroy;
begin
	inherited Destroy;
end;
procedure TFileList.Sort;
begin
   if Count>1 then inherited Sort(FLSortCompare);
end;
//******************************************************************************
// FLSortCompare: fonction de tri pour la filelist
//******************************************************************************
function FLSortCompare(Item1,Item2:Pointer):Integer;
var FileItem1,FileItem2:TFileItem;
begin
   FileItem1:=TFileItem(Item1);
   FileItem2:=TFileItem(Item2);
   // le premier element de la liste dois rester le premier element de la liste
   // ca il est en train d'&#1082;tre copi&#1081;
   if FileItem1=FileItem1.Owner.First then
   begin
     Result:=-1;
     Exit;
   end;
   if FileItem2=FileItem2.Owner.First then
   begin
     Result:=1;
     Exit;
   end;
   Result:=0;
   case FileItem1.Owner.SortMode of
     fsmBySrcName:
       Result:=WideCompareText(FileItem1.SrcName,FileItem2.SrcName);
     fsmBySrcFullName:
       Result:=WideCompareText(FileItem1.SrcFullName,FileItem2.SrcFullName);
     fsmByDestName:
       Result:=WideCompareText(FileItem1.DestName,FileItem2.DestName);
     fsmByDestFullName:
       Result:=WideCompareText(FileItem1.DestFullName,FileItem2.DestFullName);
     fsmBySrcSize:
       Result:=CompareValue(FileItem1.SrcSize,FileItem2.SrcSize);
     fsmBySrcExt:
Result:=WideCompareText(ExtractFileExt(FileItem1.SrcName),ExtractFileExt(FileItem2.SrcName));
   end;
   if FileItem1.Owner.SortReverse then Result:=-Result;
end;
end.
//---------------------------------------------------------------

Jos� Mejuto <joshyfun en gmail.com> escribi�:

Show quoted text 20 lines
El 14/10/2014 a las #4, J.Alejandro Martinez Linares escribi�: > Hola estoy tratando de reparar una versi�n de supercopier que es un > programa para copiar archivos y carpetas pero justo en la seccion que > les pongo abajo cada vez que el sitema se encuentra una carpeta con > tildes el sistema me da una excepci�n notificandome que no tiene acceso, > y justo en el fragmento que les muestro es donde el sistema se engancha Hola, Deber�as de mostrar tambi�n de donde sacas SourceFile, si es un ansistring, un utf8string o qu�. -- _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es

---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.

Nunca digas nunca, di mejor: gracias, permiso, disculpe. Este mensaje le ha llegado mediante el servicio de correo electronico que ofrece Infomed para respaldar el cumplimiento de las misiones del Sistema Nacional de Salud. La persona que envia este correo asume el compromiso de usar el servicio a tales fines y cumplir con las regulaciones establecidas Infomed: http://www.sld.cu/

Reply by email

islanis en infomed.sld.cu
to José Mejuto: El 14/10/2014 a las #4, J.Alejandro Martinez Linares escribi�: Deber�as de mostrar…

Hola chicos acabo de darme cuenta de algo, que el error al parecer est� mucho antes de llegar a esa funci�n y les explico por que, les pondr� como ejemplo que quiero copiar una carpeta que se llama "�folder", recuerden que esto es parte de un copiador, la cuestion est� en que ya cuando llegamos a la funci�n esta: //-------------------------------------------------------- HSrc:=Windows.CreateFileW(PWideChar(UTF8Decode(SourceFile)), GENERIC_READ,
FILE_SHARE_READ or FILE_SHARE_WRITE,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED
or
IfThen(SourceIsNetwork,0,FILE_FLAG_NO_BUFFERING),

                             0);
         RaiseCopyErrorIfNot(HSrcINVALID_HANDLE_VALUE);

//-------------------------------------------------------- Pues claro que tiene que dar error al no coincidir los hash pues es que la carpeta no existe porque no ha sido creada o copiada por eso da error ac� pero antes, mucho antes me percat� de que hay una rutina que en el transcurso de la iteraci�n y la organizaci�n de lo que se va a copiar pues comete a mi entender un fallo, y es que solo pasa con lo que tiene tilde, o sea, en nuestro ejemplo la carpeta "�folder", y cuando llega a la rutina que al parecer lo que hace es que le asigna las propiedades pertinentes a cada uno de los archivos que son analizados por el sistema antes de copiar, o sea, en el proceso de preparaci�n, pero, justo cuando le pregunta a la carpeta si es un directorio o no pues para mi sorpresa encontre que el sistema entiende que esto no es un directorio cuando en realidad lo es,la rutina es esta, ah AItemName es un camino a nuestra carpeta, o sea para poner un ejemplo pues es "c:\\�folder"
//-------------------------------------------------------- { TAPI }

procedure TAPI.APIBaselistAddItem(ABaseListHandle: Integer;
   AItemName: WideString);
var Item:TBaseItem;
begin
   if not CheckHandle(ABaseListHandle,TBaseList) then Exit;
   Item:=TBaseItem.Create;
   Item.SrcName:=UTF8Encode(AItemName);
   Item.IsDirectory:=DirectoryExists(UTF8Encode(AItemName));// ac� es
donde veo que da el problema,
   (FHandleList[ABaseListHandle] as TBaseList).Add(Item);
   FLastError:=aeNone;
end;
//--------------------------------------------------------
Y esta es DirectoryExists que se encuentra dentro de sysutils.pp del lazarus
Function DirectoryExists (Const Directory : String) : Boolean;
var
   Attr:Dword;
begin
   Attr:=GetFileAttributes(PChar(Directory));
   if Attr  $ffffffff then
     Result:= (Attr and FILE_ATTRIBUTE_DIRECTORY) > 0
   else
     Result:=False;
end;
//--------------------------------------------------------
al parecer el problema est� en GetFileAttributes() o en el mismo
DirectoryExists ahora si espero a que me den alguna respuesta ustedes.

Saludos y gracias de antemano.

Jos� Mejuto <joshyfun en gmail.com> escribi�:

Show quoted text 20 lines
El 14/10/2014 a las #4, J.Alejandro Martinez Linares escribi�: > Hola estoy tratando de reparar una versi�n de supercopier que es un > programa para copiar archivos y carpetas pero justo en la seccion que > les pongo abajo cada vez que el sitema se encuentra una carpeta con > tildes el sistema me da una excepci�n notificandome que no tiene acceso, > y justo en el fragmento que les muestro es donde el sistema se engancha Hola, Deber�as de mostrar tambi�n de donde sacas SourceFile, si es un ansistring, un utf8string o qu�. -- _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es

---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.

Nunca digas nunca, di mejor: gracias, permiso, disculpe. Este mensaje le ha llegado mediante el servicio de correo electronico que ofrece Infomed para respaldar el cumplimiento de las misiones del Sistema Nacional de Salud. La persona que envia este correo asume el compromiso de usar el servicio a tales fines y cumplir con las regulaciones establecidas Infomed: http://www.sld.cu/

Reply by email

José Mejuto
to islanis en infomed.sld.cu

El 15/10/2014 a las #4, islanis en infomed.sld.cu escribi�:

Item.SrcName:=UTF8Encode(AItemName); Item.IsDirectory:=DirectoryExists(UTF8Encode(AItemName));// ac� es donde veo que da el problema,

Hola,

Aqu� DirectoryExists trabaja en ANSI (no UTF8), al igual que todas las funciones de archivos de fpc. Para esas funciones deber�as o bien hacerte unas funciones que usen los equivalentes *W de Windows o bien usar la unit de funciones de ficheros UTF8 de Lazarus (LazUTF8).

Comprueba siempre las funciones manualmente creando ficheros y carpetas en ruso, chino, �rabe y/o japon�s (necesitar�s un shell de ficheros que no sea el de Windows, como el "Directory Opus". Para conseguir archivos en eses idiomas, copiar y pegar palabras de la Wikipedia y crear archivos con el Opus por ejemplo.

Reply by email

islanis en infomed.sld.cu
to José Mejuto

Hola Jos�, acabo de corregir uno de los problemas de por que el hash me da mal, es que no estaba creando la carpeta acentuada, entonces lo que hice fu� como bien dices tu ac� lo que hice fu� sustituir la funci�n DirectoryExists por CreateDirectoryUTF8 y ya por lo menos cuando pasa por esa rutina pues devuelve true cuando verifica nuestra carpeta "�folder" que antes no lo hac�a ahora crea la carpeta vac�a e igual cuando va a copiar me da error cuando comienza a copiar su contenido su contenido estoy buscando la forma de subir todo el proyecto en un compactado a alg�n lugar para entonces ir a la par, porque me parece que de esta forma todo es muy lento y a veces estamos por lugares distintos, de momento sigo revisando a ver si encuentro el problema.

Gracias por todo a todos

Jos� Mejuto <joshyfun en gmail.com> escribi�:

Show quoted text 29 lines
El 15/10/2014 a las #4, islanis en infomed.sld.cu escribi�: > Item.SrcName:=UTF8Encode(AItemName); > Item.IsDirectory:=DirectoryExists(UTF8Encode(AItemName));// ac� es > donde veo que da el problema, > Hola, Aqu� DirectoryExists trabaja en ANSI (no UTF8), al igual que todas las funciones de archivos de fpc. Para esas funciones deber�as o bien hacerte unas funciones que usen los equivalentes *W de Windows o bien usar la unit de funciones de ficheros UTF8 de Lazarus (LazUTF8). Comprueba siempre las funciones manualmente creando ficheros y carpetas en ruso, chino, �rabe y/o japon�s (necesitar�s un shell de ficheros que no sea el de Windows, como el "Directory Opus". Para conseguir archivos en eses idiomas, copiar y pegar palabras de la Wikipedia y crear archivos con el Opus por ejemplo. -- _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es

---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.

Nunca digas nunca, di mejor: gracias, permiso, disculpe. Este mensaje le ha llegado mediante el servicio de correo electronico que ofrece Infomed para respaldar el cumplimiento de las misiones del Sistema Nacional de Salud. La persona que envia este correo asume el compromiso de usar el servicio a tales fines y cumplir con las regulaciones establecidas Infomed: http://www.sld.cu/

Reply by email

José Mejuto
to islanis en infomed.sld.cu

El 15/10/2014 a las 21:08, islanis en infomed.sld.cu escribi�:

Show quoted text 12 lines
Hola Jos�, acabo de corregir uno de los problemas de por que el hash me da mal, es que no estaba creando la carpeta acentuada, entonces lo que hice fu� como bien dices tu ac� lo que hice fu� sustituir la funci�n DirectoryExists por CreateDirectoryUTF8 y ya por lo menos cuando pasa por esa rutina pues devuelve true cuando verifica nuestra carpeta "�folder" que antes no lo hac�a ahora crea la carpeta vac�a e igual cuando va a copiar me da error cuando comienza a copiar su contenido su contenido estoy buscando la forma de subir todo el proyecto en un compactado a alg�n lugar para entonces ir a la par, porque me parece que de esta forma todo es muy lento y a veces estamos por lugares distintos, de momento sigo revisando a ver si encuentro el problema.

Hola,

99% seguro es un problema Ansi<->UTF8<->WideString. Si quieres puedes subir un ZIP a donde te parezca (zippyshare, uploaded, etc.) y me lo bajo y ma�ana le pego un ojo a todo eso.

Reply by email

islanis en infomed.sld.cu
to José Mejuto

Hola Jose

Te env�o el proyecto por ac�

http://www15.zippyshare.com/v/6383648/file.html

para que le eches un ojo y me digas por fin que problemas tiene porque me he cansado de debugearlo de arriba abajo y no soy capaz de darme cuenta solo de
que es lo que en realidad tiene, lo env�o por ac� pues no tengo acceso a internet adem�s
de que es correo m�o permite un adjunto mayor del que uso en la lista, pero bueno a medidas que
vayas esclareciendo el problema con las codificaciones del proyecto pues vas coment�ndomelo
en la lista si quieres para saber que tengo que cambiar y bueno aprovechas ah� y lo explicas
porque soy nuevo en lazarus y nunca toqu� tan profundo pascal, cuando estaba en el 10mo grado
lo que dimos ah� fue delphi y muy por encima por lo que no tengo nada de experiencia en el tema
, el proyecto est� lleno de puntos de ruptura porque he estado debugeandolo como te comentaba
sin exito alguno, he hecho algunos cambios, si te fijas dondequiera que aparezca una l�nea
comentariada y debajo una muy similar es que la original que ven�a en el proyecto es la comentariada
y la que est� debajo es la que tiene los cambios realizados por m�, he hecho esto con solo aquellas
que ten�an utf8Encode y utf8Decode y las he cambiado por algo como esto ConvertEncoding(varstr,GuessEncoding(varstr),'utf8') Porque me pareci� que era lo correcto al ver que hab�a codificaciones que eran CP1252 que me di cuenta
gracias a la funci�n GuessEncoding entonces ni idea tampoco pero igual trataba de convertirlas a
utf8 pero bueno ahora el copiador crea las carpetas pero el contenido de ellas no los copia
y antes copiaba bien las carpetas sin tilde y sus contenidos, y de las carpetas que ten�an
tilde solo copiaba sus carpetas pero no su contenido, ahora tanto pata las con tilde como
las que no tienen tilde hacen lo mismo "solo copia las carpetas", lo otro es que en existen 2 dll
que deben estar siempre junto con el ejecutable que compiles, y bueno en install esta e setup compilado
en nsis para que sea lo primero que hagas, instalarlo y luego que lo instales cierras el de la instalaci�n
y ejecuta el del proyecto y es as� como hago yo, adem�s el proyecto depende de un componente que esta
en lo que te enc�o tambien que se llama SCcomponent compilas el lazarus con el y luego abres ya el
proyecto, porque la instalaci�n pone cosas en el registro que luego el mismo ejecutable usa luego para que no te de errores y dolores de cabeza por gusto, entonces espero que me
ayudes con esto te lo agradecer� siempre, el objetivo es corregir este copiador que es muy bueno
pero tiene muchos errores este es uno de ellos, ya he corregido muchos ya, pero de este
no salgo llevo d�as, es que tambi�n no entiendo mucho esto de las codificaciones de
el trabajo con ficheros, espero que me vayas ense�ando a medida que hagas cambios.

Saludos Ale

Jos� Mejuto <joshyfun en gmail.com> escribi�:

Show quoted text 29 lines
El 15/10/2014 a las 21:08, islanis en infomed.sld.cu escribi�: > Hola Jos�, acabo de corregir uno de los problemas de por que el hash me > da mal, es que no estaba creando la carpeta acentuada, entonces lo que > hice fu� como bien dices tu ac� lo que hice fu� sustituir la funci�n > DirectoryExists por CreateDirectoryUTF8 y ya por lo menos cuando pasa > por esa rutina pues devuelve true cuando verifica nuestra carpeta > "�folder" que antes no lo hac�a ahora crea la carpeta vac�a e igual > cuando va a copiar me da error cuando comienza a copiar su contenido su > contenido estoy buscando la forma de subir todo el proyecto en un > compactado a alg�n lugar para entonces ir a la par, porque me parece que > de esta forma todo es muy lento y a veces estamos por lugares distintos, > de momento sigo revisando a ver si encuentro el problema. > Hola, 99% seguro es un problema Ansi<->UTF8<->WideString. Si quieres puedes subir un ZIP a donde te parezca (zippyshare, uploaded, etc.) y me lo bajo y ma�ana le pego un ojo a todo eso. -- _______________________________________________ Lazarus-es mailing list Lazarus-es en lists.lazarus.freepascal.org http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es

---------------------------------------------------------------- This message was sent using IMP, the Internet Messaging Program.

Nunca digas nunca, di mejor: gracias, permiso, disculpe. Este mensaje le ha llegado mediante el servicio de correo electronico que ofrece Infomed para respaldar el cumplimiento de las misiones del Sistema Nacional de Salud. La persona que envia este correo asume el compromiso de usar el servicio a tales fines y cumplir con las regulaciones establecidas Infomed: http://www.sld.cu/

Reply by email