Re: need native call help

[email protected] (ToddAndMargo via perl6-users)
Newsgroups perl.perl6.users
Message-ID <[email protected]>
On 4/16/24 18:43, ToddAndMargo via perl6-users wrote:
> On 4/16/24 01:21, ToddAndMargo via perl6-users wrote:
>> Hi All,
>>
>> Windows 11
>>
>> It has been so long that I have done one of these that
>> my brain is seizing.
>>
>> https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-deletefilea
>>
>> C++
>>
>> BOOL DeleteFileA(
>>    [in] LPCSTR lpFileName
>> );
>>
>>
>> Would some kind soul please show me how to do this again?
>>
>> Many thanks,
>> -T
> 
> I got a good night's sleep and my head unfroze.
> 
> I figured it out.  I will post back how in a
> few days or so.
> 
> -T
> 


Hi All,

https://docs.raku.org/language/nativecall
is a wonderful documeht, but as far as I can
tell, they do not breakdown how to make an
API call.  They expect you to already know how
to do it.  So not for the beginners.

This is the code I came up with.  There is a lot
of the my libraries missing from this, if you want
them, I can eMail them to you.  I am only posting
this so you can get the idea of how to do this:

-T

# unit module NativeDelete;
# NativeDelete.rakumod

#`{

    Delete a filed directory with the Windows DeleteFileA function
    (fileapi.h) API with NativeCall.

 
https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-deletefilea
    https://docs.raku.org/language/nativecall

    To use, place the following at the top of your program:

    use NativeDelete :ApiDeleteFile;
    use NativeCall;
    use NativeConstants;
    use NativeConvert :to-UTF8-c-str;
    use WinErr :WinGetLastError, :WinFormatMessage;

    Test one liner:
       Note: in Windows Explorer, right click on the file, left click on 
copy as path,
             then paste the entire path.  Note the `\\?\` at the 
beginning for long file names.

       K:\Windows\NtUtil>echo abc > eraseme.txt && raku -I. -e "use 
NativeDelete :ApiDeleteFile; say ApiDeleteFile( Q[eraseme.txt] )" && 
type eraseme.txt
       OK
       The system cannot find the file specified.

       K:\Windows\NtUtil>echo abc > eraseme.txt && raku -I. -e "use 
NativeDelete :ApiDeleteFile; say ApiDeleteFile( Q[eraseme2.txt] )" && 
type eraseme.txt
       The system cannot find the file specified.
       abc

       raku -I. -e "use NativeDelete :ApiDeleteFile; say ApiDeleteFile( 
Q[\\?\D:\MyDocsBackup\backup2\Mozilla 2024-04-15 21;14;31 
(Full)\Firefox\Profiles\pj0elosu.default-release\storage\default\https+++505991220932649.webpush.freshchat.com^partitionKey=%28https%2Cbid13.com%29\cache\morgue\114\{7cccd5e9-a7aa-4349-a2e9-569baf007272}.final] 
);"
       OK

}

use NativeCall;
use NativeConstants;
use NativeConvert :to-UTF8-c-str;
use WinErr :WinGetLastError, :WinFormatMessage;


sub DeleteFileA(
    #`{
        C++
          BOOL DeleteFileA(
          [in] LPCSTR lpFileName
        );
    }

    CArray[uint8] $lpFileName
    )
    is native("Kernel32.dll")
    is symbol("DeleteFileA")
    returns BOOL
    { * };


sub ApiDeleteFile( Str $FileName ) returns Str is export( :ApiDeleteFile ) {
#`{
     $FileName is the file name and optional path path
     Format:  Q[D:\NtUtil\eraseme.txt]   Note the backslashes.

     Returned "OK" if successful or the error message if not

     Syntax
     C++

     BOOL DeleteFileA(
        [in] LPCSTR lpFileName
     );
     DLL 	Kernel32.dll

     Return value
     If the function succeeds, the return value is nonzero.
     If the function fails, the return value is zero (0). To get 
extended error information, call GetLastError.

     By default, the name is limited to MAX_PATH characters. To extend 
this limit to 32,767
     wide characters, prepend "\\?\" to the path.

     If using `\\?\` you must use the full path.

}

    my DWORD $LastError   = 0;
    my Str   $WinErrorMsg = "OK";
    my BOOL  $RtnValue    = 1;
    my Str   $LongName    = "";

    $LongName = $FileName;
    if $FileName.chars >= MAX_PATH  { $LongName = Q[\\?\] ~ $FileName; }

    my CArray[uint8] $lpFileName = to-UTF8-c-str( $LongName );
    $RtnValue = DeleteFileA( $lpFileName );

    sub GetLastError() is native("Kernel32") is symbol("GetLastError") 
returns DWORD { * };


    if $RtnValue == 0  {
       $LastError   = GetLastError();
       $WinErrorMsg = WinFormatMessage( $LastError );
    }
    return $WinErrorMsg;

}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.