Page 1 of 1

API Copy problem

Posted: Sun Feb 10, 2008 8:41 pm
by trather
I am having trouble understanding why this code keeps failing. It is a simple copy command using the windows API function. I like to use it because is as the progress bar and icon all in one. Here is the code. I can get it to work if I code the file path my self. You will see that it is remarked out now but if I use the other function to get the same path it will fail. I have checked and the name is the same. I am open for suggestions.

Code: Select all

Procedure.s Win_Spec_Loc(Valeur.l) 
;Based on Droopy Library v1.31.4 
;Modified to no have a \ at the end
  If SHGetSpecialFolderLocation_(0, Valeur, @TR_ID) = 0 
    SpecialFolderLocation.s = Space(#MAX_PATH) 
    SHGetPathFromIDList_(TR_ID, @SpecialFolderLocation) 
  EndIf 
  ProcedureReturn SpecialFolderLocation.s 
EndProcedure 

Procedure.b CpyDir(FromLoc.s, Toloc.s)
  Switches.SHFILEOPSTRUCT ;Windows API Structure
  File_From.s = FromLoc
  File_Dest.s = Toloc
  Switches\wFunc = #FO_COPY
  Switches\pFrom = @File_From
  Switches\pTo = @File_Dest
  Switches\fFlags = #FOF_NOCONFIRMATION | #FOF_NOCONFIRMMKDIR
  Result.l = SHFileOperation_(@Switches)   
  ; If cancel was pressed then result will NOT be zero (0)
EndProcedure

Procedure Main()
  Dir_From.s =Win_Spec_Loc(6)
  ;Dir_From.s = "C:\Documents and Settings\Todd\Favorites"
  Dir_To.s = "C:\Todd1234"
  Error.b = CpyDir(Dir_From,Dir_To)
  If Error =#False : A$= "Cancel" : End : Else : A$ = "Sucessful" :EndIf
EndProcedure

Main()

Posted: Sun Feb 10, 2008 9:25 pm
by akj
The documentation for SHFileOperation_() say that Switches\pFrom and Switches\pTo both need to end in 2 trailing nulls, but you have not done that.
See also http://www.purebasic.fr/english/viewtopic.php?t=3783

Posted: Sun Feb 10, 2008 9:38 pm
by srod
akj just beat me as I was adjusting your code, but the following works okay and does exactly what akj was infering etc.

Code: Select all

Procedure.s Win_Spec_Loc(Valeur.l) 
;Based on Droopy Library v1.31.4 
;Modified to no have a \ at the end 
  If SHGetSpecialFolderLocation_(0, Valeur, @TR_ID) = 0 
    SpecialFolderLocation.s = Space(#MAX_PATH) 
    SHGetPathFromIDList_(TR_ID, @SpecialFolderLocation) 
  EndIf 
  ProcedureReturn SpecialFolderLocation.s 
EndProcedure 

Procedure.l CpyDir(FromLoc.s, Toloc.s) 
  Switches.SHFILEOPSTRUCT ;Windows API Structure 
  ;The filename needs to be double null-terminated.
  temp1$=Space(#MAX_PATH+SizeOf(character))
  RtlZeroMemory_(@temp1$, #MAX_PATH+SizeOf(character))
  PokeS(@temp1$, FromLoc)
  temp2$=Space(#MAX_PATH+SizeOf(character))
  RtlZeroMemory_(@temp2$, #MAX_PATH+SizeOf(character))
  PokeS(@temp2$, ToLoc)
;  File_Dest.s = Toloc +Chr(0)+Chr(0)
  Switches\wFunc = #FO_COPY 
  Switches\pFrom = @temp1$ 
  Switches\pTo = @temp2$ 
  Switches\fFlags = #FOF_NOCONFIRMATION

  Result.l = SHFileOperation_(@Switches)    

  ; If cancel was pressed then result will NOT be zero (0) 
EndProcedure 

Procedure Main() 
  Dir_From.s =Win_Spec_Loc(6) +"\*.*"
  Dir_To.s = "C:\Todd1234" 
  CreateDirectory(Dir_To)
  Error.b = CpyDir(Dir_From,Dir_To) 
  If Error =#False : A$= "Cancel" : End : Else : A$ = "Sucessful" :EndIf 
EndProcedure 

Main()

Posted: Sun Feb 10, 2008 9:54 pm
by SFSxOI
;The filename needs to be double null-terminated.

??? why?

Posted: Sun Feb 10, 2008 9:57 pm
by srod
You can pass multiple filenames to these functions and individual filenames must be null-terminated. A double-null is then used to terminate the entire list of filenames etc.

Posted: Tue Feb 12, 2008 4:07 am
by trather
Thank you. I was not aware of the double Null that was needed.

Posted: Tue Feb 12, 2008 8:27 am
by SFSxOI
If your using Vista, you can do multiple operations of different types in a single call (without the need for double null's) using the new Vista API IFileOperation interface.

http://www.purebasic.fr/english/viewtopic.php?t=31094