c vs asm - MoveFileEx()/GetLastError()

Just starting out? Need help? Post your questions and find answers here.
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

c vs asm - MoveFileEx()/GetLastError()

Post by jassing »

when I run this code using C backend, debug output is 0,0
if I use strings
when I run this code using asm backend, debug output is 0,3
if I use pointers
when I run this code using asm backend, debug output is 0,5

I discovered this trying to figure out why movefilex_() was failing
So My bigger question is why is this failing?

Code: Select all

Procedure.s GetTempFileName()
  Protected lg, tempFilename.s,tempPath.s
  tempPATH = Space( #MAX_PATH )
  lg = GetTempPath_( #MAX_PATH, tempPATH )
  tempPATH=Left( tempPATH, lg )
  
  tempFILENAME=Space( #MAX_PATH )
  GetTempFileName_( tempPATH, "huh", 0, tempFILENAME )
  debug tempFileName
  Debug FileSize( tempFilename ) ; file does exist!
  
  Debug MoveFileEx_( tempFilename, "", #MOVEFILE_DELAY_UNTIL_REBOOT ) 
  Debug GetLastError_(); C=0, asm=3 (system cannot find path specified)
  
  Debug MoveFileEx_( @tempFilename, #NUL, #MOVEFILE_DELAY_UNTIL_REBOOT ) 
  Debug GetLastError_(); C=0, asm=5 (access denied)
    
  ProcedureReturn tempFilename
EndProcedure

DeleteFile( GetTempFileName(),#PB_FileSystem_Force)
FWIW, I get this in dbgview when running this example
1259.254764 2024/04/18 04:42:45.768 5932 cc1.exe Invalid parameter passed to C runtime function.[/code]
PeDe
Enthusiast
Enthusiast
Posts: 305
Joined: Sun Nov 26, 2017 3:13 pm

Re: c vs asm - MoveFileEx()/GetLastError()

Post by PeDe »

You must call GetLastError_() immediately after an error, and you must not use 'Debug ...'.

e.g.:

Code: Select all

;Debug MoveFileEx_( tempFilename, "", #MOVEFILE_DELAY_UNTIL_REBOOT ) 
;Debug GetLastError_(); C=0, asm=3 (system cannot find path specified)
If Not MoveFileEx_( tempFilename, "", #MOVEFILE_DELAY_UNTIL_REBOOT )
    Protected iError.l
    iError = GetLastError_(); C=0, asm=3 (system cannot find path specified)
    Debug iError
EndIf
This is how it works here with Windows 7 x64.

Peter
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: c vs asm - MoveFileEx()/GetLastError()

Post by jassing »

OK -- why does movefilex fail?
GetLastError() is called immediately after movefilex()
User avatar
Demivec
Addict
Addict
Posts: 4281
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: c vs asm - MoveFileEx()/GetLastError()

Post by Demivec »

jassing wrote: Thu Apr 18, 2024 8:13 pm OK -- why does movefilex fail?
GetLastError() is called immediately after movefilex()
https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-movefileexw
Because the actual move and deletion operations specified with the MOVEFILE_DELAY_UNTIL_REBOOT flag take place after the calling application has ceased running, the return value cannot reflect success or failure in moving or deleting the file. Rather, it reflects success or failure in placing the appropriate entries into the registry.
Also, regqrding the use of the MOVEFILE_DELAY_UNTIL_REBOOT flag:
This value can be used only if the process is in the context of a user who belongs to the administrators group or the LocalSystem account.
PeDe
Enthusiast
Enthusiast
Posts: 305
Joined: Sun Nov 26, 2017 3:13 pm

Re: c vs asm - MoveFileEx()/GetLastError()

Post by PeDe »

jassing wrote: Thu Apr 18, 2024 8:13 pm OK -- why does movefilex fail?
GetLastError() is called immediately after movefilex()
The result of 'MoveFileEx_()' is output by 'Debug'. If an API function is called by 'Debug', the last error code for 'GetLastError_()' can be deleted.

The empty string "" for 'MoveFileEx()' is not a null string, so only #NUL, #Null$ or 0 should be used.

Peter
jassing
Addict
Addict
Posts: 1885
Joined: Wed Feb 17, 2010 12:00 am

Re: c vs asm - MoveFileEx()/GetLastError()

Post by jassing »

using #null or #null$, C or ASM backend
MoveFileEx_() = 0
GetLastError_() = 5
So the question is why is it not? failing but failing with "access denied"?

Code: Select all

Procedure.s GetLastErrorStr( error=-999 )
  Protected Buffer.i, result.s
  If error = -999 : error = GetLastError_() : EndIf 
  If FormatMessage_( #FORMAT_MESSAGE_ALLOCATE_BUFFER | #FORMAT_MESSAGE_FROM_SYSTEM, 0, error, 0, @Buffer, 0, 0 )
    result = PeekS( Buffer ) : result=Left(result,Len(result)-SizeOf(Character))
    LocalFree_( Buffer )
  EndIf
  ProcedureReturn result
EndProcedure

Procedure.s GetTempFileName()
  Protected lg, tempFilename.s,tempPath.s
  tempPATH = Space( #MAX_PATH )
  lg = GetTempPath_( #MAX_PATH, tempPATH )
  tempPATH=Left( tempPATH, lg )
  
  tempFILENAME=Space( #MAX_PATH )
  GetTempFileName_( tempPATH, "huh", 0, tempFILENAME )
  Debug tempFileName
  Debug "Size: "+FileSize( tempFilename ) ; file does exist!
  
  x = MoveFileEx_( @tempFilename, #Null, #MOVEFILE_DELAY_UNTIL_REBOOT ) 
  z = GetLastError_()
  Debug "  MoveFileEx_() = " + x
  Debug "GetLastError_() = " + z + " (" + GetLastErrorStr(z) + ")"
  
  ProcedureReturn tempFilename
EndProcedure

DeleteFile( GetTempFileName(),#PB_FileSystem_Force)
PeDe
Enthusiast
Enthusiast
Posts: 305
Joined: Sun Nov 26, 2017 3:13 pm

Re: c vs asm - MoveFileEx()/GetLastError()

Post by PeDe »

As described above by Demivec, you need administrator rights. If I start PureBasic with administrator rights, your code works. Tested with Windows 10 22H2.

Here is a screenshot:
https://www.dreisiebner.at/temp/PB_MoveFileEx.png

Peter
Post Reply