Author Topic: Question about getfile / ReadFile  (Read 128 times)

0 Members and 1 Guest are viewing this topic.

Arnold

  • Hero Member
  • *****
  • Posts: 809
Question about getfile / ReadFile
« on: May 13, 2019, 11:43:33 PM »
Hi Charles,

I am experimenting a bit with CreateFile and Readfile and try to compare with Oxygen's getfile function. I am able to load text with ReadFile into a buffer of type char* or zstring*, but it does not work with string or bstring. Is this possible in some way? There are some older postings dealing with ReadFile and strings, but they do not run with the latest version of Oxygen. Unfortunately Peter has deleted his messages, so it is a bit difficult to see the context.

Does getfile apply getmemory or freememory internally?

Roland

TestReadFile.o2bas:
Code: [Select]
$ filename "TestReadFile.exe"
'uses rtl32
'uses rtl64

uses corewin
uses console

function lof (string Fname) as int
   'length of file
   WIN32_FIND_DATA W32FD
   sys hFile
   int FSize
   if len(Fname) = 0 then return 0
   hFile=FindFirstFile(Fname, &W32FD)
   if hFile != INVALID_HANDLE_VALUE then
     FSize = W32FD.nFileSizeLow
     FindClose(hFile)
     return FSize
   end if
   
   return 0
end function

function LoadFile (string Fname, sys Buff) as int
   ' Assumes a valid existing file and Buff large enough to hold the content of the file
   sys Read
   sys hFile
   int Fsize
 
   Fsize = LOF(Fname) 
   hFile = CreateFile(Fname,GENERIC_READ,FILE_SHARE_READ,null,OPEN_EXISTING,0,0)
   if hFile != INVALID_HANDLE_VALUE then
     ReadFile (hFile,Buff,Fsize,&Read,null)
     CloseHandle(hFile)
   end if
   function = Read
end function

cls

int FileSize
string fn = "TestReadFile.o2bas"

sys buf = getmemory (lof(fn) +1)
'zstring *buffer : @buffer = buf
char *buffer : @buffer = buf

FileSize = LoadFile(fn, @buffer)

print fn
printl "LoadFile loaded " FileSize  " bytes into buffer"

string s=getfile(fn)
printl "Getfile loaded " len(s) " bytes into string"

printl "Press Enter to display contents of buffer"
waitkey
Cls

print buffer  's
freememory buf


printl "Enter..."
waitkey

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4033
    • Oxygen Basic
Re: Question about getfile / ReadFile
« Reply #1 on: May 14, 2019, 02:26:09 AM »
Hi Roland,

getfile uses SysAllocStringByteLen directly to create the bstring buffer.

getmemory also uses SysAllocStringByteLen

This is the function in RTL32. It would look much less intimidating in Basic :)

Code: [Select]
  function getfiles(string w) as sys external 'at [ebx+336]
  '========================================================
  '
  dim as sys b,h,p,pf,ph,le,leh
  '
  '
  'CHECK VALID NAME
  '
  cmp dword ptr [w],0
  jz ngetfile
  '
  'OPEN FILE
  '
  push 0             'HANDLE hTemplateFile OPT
  push 128           'FILE_ATTRIBUTE_NORMAL
  push 3             'CREATE (NEW 1) (ALWAYS 2) (OPEN 4) (OPEN EXISTING 3)
  push 0             'LP SECURITY  ATTRIBUTES OPT
  push 1             'SHARE MODE read(1) write(2)
  push 0x80000000    'GENERIC_READ (0x80000000) GENERIC_WRITE (0x40000000)
  push [w] 'name
  call Createfile
  mov [h],eax
  '
  'SET FILE POINTER
  '
  push 0              'DWORD dwMoveMethod 0,FILE_BEGIN(0) FILE_CURRENT(1) FILE_END (2)
  lea eax,[ph]        'PLONG lpDistanceToMoveHigh
  push eax
  push 0              'LONG lDistanceToMove
  push [h]            'DWORD HANDLE
  call SetFilePointer '
  mov [pf],eax        'File Pointer position low
  '
  'GET FILE SIZE
  '
  lea eax,[leh]       'PLONG lpFileSizeHigh
  push eax            '
  push [h]            'DWORD HANDLE
  call GetFileSize    '
  mov [le],eax        '
  '
  'CREATE STRING BUFFER
  '
  push [le]           'FILE LENGTH
  push 0              'OPTIONAL COPY POINTER
  call SysAllocStringByteLen 'CREATE BSTR
  mov [p],eax
  mov [function],eax
  '
  'READ FILE
  '
  push 0              'LPOVERLAPPED lpOverlapped
  lea eax,[b]         'lpNumberOfBytesRead
  push eax            '
  push [le]           'DWORD nNumberOfBytesToRead
  push [p]            'LPVOID lpBuffer
  push [h]            'DWORD HANDLE
  call ReadFile
  '
  push [h]
  call CloseHandle
  '
  ngetfile:
  '
  'CLOSE HANDLE
  '
  end function

Arnold

  • Hero Member
  • *****
  • Posts: 809
Re: Question about getfile / ReadFile
« Reply #2 on: May 15, 2019, 04:14:08 AM »
Hi Charles,

you opened the door to a new world for me and once again I see the complexity of OxygenBasic. I will need some time to understand the connections. Until now I have not paid much attention to bstrings.

Is Oxygen's bstr type different from the declaration which I found in MSDN info: typedef WCHAR* BSTR (can contain embedded null characters, 4 bytes length prefix)? Oxygen Helpfile: bstr - specify a bstring type with 8-bit characters.

Is there a relationship between bstr, bstring and bstring2 ? Can they contain embedded null characters and is there a count of chars prefix too?

Roland

Charles Pegge

  • Admin Support Member
  • *****
  • Posts: 4033
    • Oxygen Basic
Re: Question about getfile / ReadFile
« Reply #3 on: May 15, 2019, 06:00:10 AM »
Hi Roland,

In o2, all dynamic strings are based on getmemory which calls SysAllocStringByteLen. So they all have the 4 byte (int) length prefix, which means they are not dependent on null terminators and therefore can include null characters.

Arnold

  • Hero Member
  • *****
  • Posts: 809
Re: Question about getfile / ReadFile
« Reply #4 on: May 15, 2019, 07:35:17 AM »
Thank you Charles. This is a real eye-opener for me.