The MASM Forum Archive 2004 to 2012

General Forums => The Workshop => Topic started by: shadow on June 27, 2005, 11:10:57 PM

Title: Help with CopyFileEx and CopyProgressRoutine
Post by: shadow on June 27, 2005, 11:10:57 PM
How do you use CopyProgressRoutine with CopyFileEx in MASM?  I can't find examples anywhere!  I really want to use a progress bar while copying files in my program and be able to pause and resume the copy operation .  Thanks for your help!      :wink
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: shadow on July 03, 2005, 03:55:02 AM
Jeez isCopyProgressRoutine even supported by masm32?? I can't find any reasources anywhere...   ::)  Growl..  No one has ever used CopyProgressRoutine in their programs?
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: Mark Jones on July 03, 2005, 04:10:11 PM
Wow, no references to it occur in masm32\include... think you've stumbled upon a function not implemented in MASM32 yet! :clap:

Anyone know in what .DLL the CopyProgressRoutine function lies? (Or if there is some other reason it is not included?) We should be able to make libs for it easily.
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: donkey on July 03, 2005, 04:20:18 PM
Quote from: Mark Jones on July 03, 2005, 04:10:11 PM
Wow, no references to it occur in masm32\include... think you've stumbled upon a function not implemented in MASM32 yet! :clap:

Anyone know in what .DLL the CopyProgressRoutine function lies? (Or if there is some other reason it is not included?) We should be able to make libs for it easily.

The CopyProgressRoutine is not in any DLL, it is an application defined callback. The name is simply a placeholder so that it can be described, nothing more. You must write the routine and pass the address to the CopyFileEx function in the lpProgressRoutine parameter.

Just to be clear here, it is not part of the API and does not really exist, you must write it yourself.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/copyprogressroutine.asp

It would look something like this

CopyProgressRoutine FRAME cbFileLow,cbFileHigh,cbTransferredLow,cbTransferredHigh,cbStreamLow,cbStreamHigh,cbStreamTransferredLow,cbStreamTransferredHigh,dwStreamNumber,dwCallbackReason,hSourceFile,hDestinationFile,lpData

mov edx,0
mov eax,[cbTransferredLow]
shl eax,8
mov ecx,[cbFileLow]
div ecx
mov ecx,100
mul ecx
shr eax,8
// Display progress here eax contains the % of transfer completed

ret
ENDF
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: Mark Jones on July 03, 2005, 04:40:41 PM
Aaah, well we heard it right from the Donkey's mouth. :toothy I was wondering how it could be an API exactly, but thought there would be a PROTO for it in any case.
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: shadow on July 03, 2005, 06:39:05 PM
wow donkey, thanks for your help.  I would have never figured out how to do that on my own.   :eek  I was thinking it would be a structure like OPENFILENAME.

That looks like GoASM...
would that be the same as


CopyProgressRoutine PROC TotalFileSize:DWORD,TotalBytesTransferred:DWORD,StreamSize:DWORD,StreamBytesTransferred:DWORD,dwStreamNumber:DWORD,dwCallbackReason:DWORD,hSourceFile:DWORD,hDestinationFile:DWORD,lpData:DWORD

mov edx,0
mov eax,[TotalBytesTransferred]
shl eax,8
mov ecx,[TotalFileSize]
div ecx
mov ecx,100
mul ecx
shr eax,8
invoke SendDlgItemMessage,hWnd,IDC_PGB2,PBM_SETPOS,eax,0
ret
CopyProgressRoutine endp


?

And how do you get lpData to CopyProgressRoutine?

Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: donkey on July 03, 2005, 09:59:04 PM
Actually the first 4 parameters are split high/low in my proc, they are actually LARGE_INTEGER types and therefor should be QWORDs not DWORDS...

CopyProgressRoutine PROC TotalFileSize:QWORD,TotalBytesTransferred:QWORD,StreamSize:QWORD,StreamBytesTransferred:QWORD,dwStreamNumber:DWORD,dwCallbackReason:DWORD,hSourceFile:DWORD,hDestinationFile:DWORD,lpData:DWORD

etc...


In GoAsm the parameters must be DWORD sized as in reality that is all the stack can use. you might like to split them up as well, makes it easier than dealing with all those disparaging types.


lpData is passed in the lpData parameter of CopyFileEx, it is user defined and can be anything you like.
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: shadow on July 04, 2005, 05:08:56 AM
Sorry... I'm still really new to this...
would I split them like this?

invoke atodw,addr TotalBytesTransferred
shl eax,32
push TotalBytesTransferred
push eax
call dwtoa
invoke atodw,addr TotalFileSize
shl eax,32
push TotalFileSize
push eax
call dwtoa

(Just a guess) to get the low DWORD out of a QWORD?

invalid instruction operands for both push TotalFileSize and push TotalBytesTransferred when TotalBytesTransferred and TotalFileSize are QWORDS... I guess a QWORD can't fit in a 32 bit register.  How do I split these up?

Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: donkey on July 04, 2005, 06:00:13 AM
No, atodw converts ascii to a dword for example the string "1234" to a numeric value. A QWORD is essentially 2 DWORDs stored contiguously with the low order DWORD first. In a structure it would look like this (this is just an example for demonstration purposes, it is not really a structure)...

QWORD struct
LowPart DD ?
HighPart DD ?
QWORD ends


So in order to extract the low order dword from a qword in MASM you would use DWORD PTR as follows...

SomeQWord DQ 12345

mov eax, DWORD PTR SomeQWord


To get the high part you would move the pointer ahead by 4 bytes...

mov eax, DWORD PTR SomeQWord+4
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: donkey on July 04, 2005, 06:37:21 AM
For what you need using integer arithmetic might not be the best idea, if you are looking to get the percentage of the copy completed you might think about the FPU. This is because some files may be over 4 Gig in size and DWORD math fails at that point. To get the percentage using the FPU you would do this...

LOCAL Percentage :DWORD

mov [Percentage], 100
fild TotalBytesTransferred
fild TotalFileSize
db 0DEh, 0F9h ; For some stupid reason MASM won't encode FDIVP without operands ????
fild Percentage
db 0DEh, 0C9h ; Same stupid thing for FMULP
fistp Percentage


I used Percentage the first time just to store 100, as the FPU cannot take immediate operands. This will use the QWORDs directly, no need to alter them. On completion Percentage will contain a DWORD percentage (0-100).

Note that for the FDIVP and FMULP instructions I couldn't figure out how to get MASM to properly encode them. It kept giving an error even though they are perfectly legal without operands. Eventually I just gave up and coded those two lines in HEX, it is sometimes easier not to argue with the assembler :) The pop versions of the instructions are necessary in order to balance the FPU.
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: shadow on July 04, 2005, 07:24:16 AM
 :U Thanks!
I'm still not getting something though... this basically what I have:

.data
data   DWORD 0

.code
invoke CopyFileEx,addr finalpth,addr copypath,addr CopyProgressRoutine,addr data,FALSE,NULL

CopyProgressRoutine PROC TotalFileSize:QWORD,TotalBytesTransferred:QWORD,StreamSize:QWORD,StreamBytesTransferred:QWORD,dwStreamNumber:DWORD,dwCallbackReason:DWORD,hSourceFile:DWORD,hDestinationFile:DWORD,lpData:DWORD

LOCAL Percentage :DWORD

mov [Percentage], 100
fild TotalBytesTransferred
fild TotalFileSize
db 0DEh, 0F9h
fild Percentage
db 0DEh, 0C9h
fistp Percentage
invoke SendDlgItemMessage,hWnd,IDC_PGB2,PBM_SETPOS,Percentage,0
ret
CopyProgressRoutine endp

I'm sorta confused... CopyFileEx is supposed to send all this to CopyProgressRoutine, but what does lpData do?  I just have lpData for CopyFileEx going to data:DWORD.   Is my CopyProgressRoutine supposed to do something with it?  TotalBytesTransferred and TotalFileSize seem to be empty when I run my code..   :eek  I'm so confused...  But thanks for spending some 4th of july time trying to help me! :) (old school smiley) Happy 4th by the way... everyone :toothy

Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: donkey on July 04, 2005, 07:45:31 AM
As I said in an earlier post...

QuotelpData is passed in the lpData parameter of CopyFileEx, it is user defined and can be anything you like.

Just set it to 0 if you don't need to pass any extra information to the callback.

In Canada the holiday is the 1st of July ;) The 4th is US only.
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: shadow on July 04, 2005, 07:51:07 AM
O!  so i don't really need it :)  Happy 1st of july 3 days ago then!    :lol
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: donkey on July 04, 2005, 08:01:32 AM
Thanks :)

You must put PROGRESS_CONTINUE in EAX before you return from the callback if you wish to continue copying the file. Either that or one of the other allowed values...

PROGRESS_CONTINUE (0) Continue the copy operation.
PROGRESS_CANCEL (1) Cancel the copy operation and delete the destination file.
PROGRESS_STOP (2) Stop the copy operation. It can be restarted at a later time.
PROGRESS_QUIET (3) Continue the copy operation, but stop invoking CopyProgressRoutine to report progress.

Since PBM_SETPOS returns the previous position of your progress bar in EAX, you are definitely not returning the right response from the callback. As soon as your progress indicator reaches 4 you effectively shut the routine off as PROGRESS_QUIET = 3, but I doubt you got there as you would have sent PROGRESS_CANCEL at 2%.

I tried the following with a 4.5 Gig file and it worked flawlessly, didn't bother setting up the progress indicator etc... but the percentages printed perfectly all values, 0 - 100. (GoAsm Syntax)

invoke CopyFileEx,"C:\BIG_DVD.ISO","C:\RadGoAsm\BIG_DVD.ISO",offset CopyProgressRoutine,0,0,0

CopyProgressRoutine FRAME cbFileLow,cbFileHigh,cbTransferredLow,cbTransferredHigh,cbStreamLow,cbStreamHigh,cbStreamTransferredLow,cbStreamTransferredHigh,dwStreamNumber,dwCallbackReason,hSourceFile,hDestinationFile,lpData

LOCAL Percentage :D

DATA SECTION
OldPercent DD 0
CODE SECTION

mov D[Percentage], 100
fild Q[cbTransferredLow]
fild Q[cbFileLow]
fdivp
fild D[Percentage]
fmulp
fistp D[Percentage]

// Display progress here
mov eax,[Percentage]
cmp eax,[OldPercent]
je >
PrintDec([Percentage])
:
mov [OldPercent],eax

mov eax,PROGRESS_CONTINUE
ret
ENDF

Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: chep on July 04, 2005, 03:35:56 PM
BTW, how does exactly the pause/resume thing work?

Here is how I understand it :

- call CopyFileEx with the COPY_FILE_RESTARTABLE flag
- later, send PROGRESS_STOP from the progress routine
- even later, calling CopyFileEx again with exactly the same parameters should resume the copy operation

Am I right? I don't find the documentation is really clear about this point...
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: donkey on July 04, 2005, 03:45:24 PM
Exactly right, at least that's what it explains in the docs, never tried it myself. This is actually the first time I used copyFileEx as it is not available in Windows 9x and I still try to make my apps compatible with that family of OSes.
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: shadow on July 06, 2005, 10:20:21 PM
what does COPY_FILE_RESTARTABLE   equal and how do you know that?
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: chep on July 06, 2005, 11:36:46 PM
Quote from: shadow on July 06, 2005, 10:20:21 PM
what does COPY_FILE_RESTARTABLE   equal and how do you know that?

As usual : MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/copyfileex.asp) / Platform SDK...


Quote from: MSDN / CopyFileEx / COPY_FILE_RESTARTABLEProgress of the copy is tracked in the target file in case the copy fails. The failed copy can be restarted at a later time by specifying the same values for lpExistingFileName and lpNewFileName as those used in the call that failed.

Quote from: Platform SDK / WinBase.h#define COPY_FILE_RESTARTABLE                 0x00000002
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: shadow on July 06, 2005, 11:52:52 PM
O!  I always wondered about that!  Thanks!   :lol
Title: Re: Help with CopyFileEx and CopyProgressRoutine
Post by: jklosak on July 10, 2005, 03:47:12 PM
I want to thank everyone for these posts. i found this page on google for exactly the same programming issues with CopyFileEx with MASM 32 and it works great

John Klosak