Jump to content











Photo
- - - - -

How to read-out FAT12 lookup-table?

grub4dos

  • Please log in to reply
43 replies to this topic

#26 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16047 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 24 February 2022 - 02:51 PM

Yes and no, it is is "implied" in the way these numbers are interpreted, two's complement:

https://en.wikipedia...wo's_complement

 

Try this:

calc 0x7FFFFFFF

echo %@retval%

calc 0x7FFFFFFF+1

echo %@retval%

calc 0x7FFFFFFF+1

calc %@retval%-1

 

calc 0x7FFFFFFF+2

calc %@retval%

 

calc 0xFFFFFFFF

calc %@retval%

 

 

calc 0xFFFFFFFF+1

calc %@retval%

 

 

calc 0xFFFFFFFF+42

calc %@retval%

 

the rightmost 8 characters (4 bytes) in the hex representation remain the same, they are only "interpreted" differently in decimal and of course they "wrap around" at the 32 bit limit, so the &0xFFFFFFFF does the trick.

 

:duff:

Wonko



#27 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 25 February 2022 - 11:49 AM

Thanks for the link and the NICE exercise. You are a great teacher!

However I still do not understand why 'standalone' %@retval% gives the 'two's complement' output above 0x7FFFFFFF. Is there any use for it in grub4dos scripting?

#28 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16047 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 25 February 2022 - 03:49 PM

I don't know *why*, at least initially also some other commands had 32 bit values only, and if you are limited to 32 bit, it actually makes sense.

 

As said, just like it is in DOS/Windows batch command line, you need to lower the max positive value to allow for negative numbers, otherwise you wouldn't be able to do some operations, let's assume that it is/was for compatibility.

 

Now, that 0x7FFFFFFF i.e. 2,147,483,647 is a too small number for many uses is obvious but if you think about it, it wasn't that bad in the '80's or '90's, I remember buying in 1995 a Compaq desktop that should have had a 300 MB disk but (probably because they had not available that size) arrived with a 500 MB disk (with a 300 MB partition, likely because they imaged the disk in manufacturing), and if I recall correctly first 2.1 GB disks were end 1995 or 1996.

 

JFYI/as a side note, I had to write my own batches to do multiply and divisions on larger numbers in Windows NT batch:

http://reboot.pro/in...?showtopic=2986

 

:duff:

Wonko



#29 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 26 February 2022 - 11:25 PM

Nice, I tested DIVIDER.CMD

 

Wonko's limit of DIVIDER.CMD almost 1 biljard.jpg



#30 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 03 March 2022 - 08:01 AM

About dividing: I found calc can not divide 2GB+ values. I think I reported earlier.

Also using unsigned values does not give meaningfull results.

CALC_cannot_divide_2GB+.png

In the past I wrote my own divider: calc seems to have no problems with multiplication, addition and substraction.

Divider-subroutine.png

But my primary school-approach is not so fast.

Maybe you can 'port' your script to grub4dos? So I can compare speed of calculation..

#31 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 09 March 2022 - 06:19 PM

Currently I am trying to add free clusters to a directory cluster-chain to write Long File Names to an already written Short File Name, if last directory cluster is 'full'.

I first write the Long File Name in free directory entries, then I copy the entry of the corresponding Short File Name to the entry just 'after' the Long File Name and 'delete' the original Short File Name entry by writing E5 to first byte. As such successfull. But Long File Names + Short File Name entry can use a maximum of 21 directory entries. On my 160KB test-floppy image clustersize is one sector, so reaching cluster-borders is rather common. So I have to write to the FAT(s).

My question is if the next cluster in a directory cluster-chain always must have a higher cluster number too?

#32 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 21 April 2022 - 09:34 PM

With a generalized approach I made a simple script to get/ set attributes on FAT12/16/32 file-systems

https://github.com/deomsh/ATTRIB.G4B

BTW I added ATTRIB.ZIP to the Repository (right-click to save files can give bad html, sorry, is my first github-project ever).

Screenshots:

Screenshot_use_ATTRIB.G4B.png Screenshot_II_use_ATTRIB.G4B.jpg

Running ATTRIB.G4B on a grub4dos command-line WITHOUT arguments will show some HELP :ph34r:

#33 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 23 April 2022 - 08:32 PM

BUG FOUND, please use new release V0.4.1 of ATTRIB.G4B.

 

Also some echos added if PATH or ENTRY is not found.

 

Further changing Archive-attribute on directories now allowed.

 

https://github.com/d...ases/tag/V0.4.1

 

Print-screens to compare MS-DOS' ATTRIB.EXE and ATTRIB.G4B

 

Screenshot attrib MS-DOS.jpg Screenshot ATTRIB.G4B.jpg

 

Although ATTRIB.EXE of course have much more possibilities than ATTRIB.G4B, I do not understand WHY ATTRIB.EXE do not show the Directory attribute.

 

Is there some special (historical) reason?



#34 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 11 May 2022 - 06:08 PM

Because I was not fully satisfied with the echo-output of ATTRIB.G4B, I made some changes in the direction of a collumn-style.

 

Further: full DEVICE+PATH is shown, but only if DEVICE was not given on the command-line.

 

Version 0.4.2: https://github.com/d...ases/tag/V0.4.2

 

The new look:

 

ATTRIB.G4B v0.4.2 Changed echo-output if not-on-ROOT or if on-ROOT BEST=III.jpg

 

I found an interesting not-fatal omission in my earlier script: echo -n > (md)%mdbase%+%clussect% && raw dd (......) while %clussect% was not declared (anymore). However grub4dos didn't take notice and happily continued this script-line.

 

In the newer version of the grub4dos debugger can be seen only echo -n is noted as executed, the part: > (md)%mdbase%+%clussect% is not expanded. Can be seen in the print-screen below just below the middle.

 

ATTRIB.G4B v0.4.1 Harmless error with echo -n redirect (md)%mdbase%+%clussect% && raw dd with not existing var %clussect% II.jpg

 

Question: is this normal behavior of the grub4dos debugger, any explanation?



#35 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 26 May 2022 - 02:13 PM

Although ATTRIB.G4B contains protection, and will not change the directory-attribute and volume-attribute, I found out that changing attributes (A R S H) on a volume-name is possible by accident in the following case:

 

1) Volume-name (Label) is in high-case written to disk

2) The Volume-name is given is 8+3 File-name format

 

See first print-screen for an example.

 

ATTRIB.G4B v0.4.2 Volume label 8+3  - attributes A R S H can be set IV.jpg

 

So I changed ATTRIB.G4B in version 0.4.3 to prevent this happening. https://github.com/d...ases/tag/V0.4.3

 

However, I added read-out of attributes if the Volume-name is given is 8+3 File-name format, but high-case only

 

See next print-screens for using version 0.4.3 with a Volume-names

 

ATTRIB.G4B v0.4.3 Volume label 8+3  - attributes A R S H cannot be set anymore I.jpg ATTRIB.G4B v0.4.3 Volume label 8+3  - low-case LABELS cannot be found I.jpg

 

BTW be aware Windows Defender does not like this script, on my Windows 10 system copy-operations takes a bit longer. I found out with help of Task Manager. No idea why. :crazy:

See last print-screen.

 

ATTRIB.G4B v0.4.3 Windows Defender is very active during copying I.jpg

 



#36 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 05 June 2022 - 11:06 PM

I finished a generalized version to get/ set (most) attributes on FAT12, FAT16 and FAT32. Including making and deleting Long File Names, in the broadest attribute-sense. The script is written as a Loosely Linked Library, in Wonko's way (I hope), and named: ATTRIBFT.LLL. I included a simple command-line utility too: ATTRIBFT.G4B.

 

https://github.com/deomsh/ATTRIBFT.LLL

 

There are about 30 primary and 15 derived function exported, no other external programs are used, just internal Grub4Dos functions. On each function there is 'help' available, including one or more examples.

 

See next three print screens for whats going on:

 

ATTRIBFT.LLL help.jpg ATTRIBFT.LLL.jpg ATTRIBFT.LLL help attrib setattrib setdatetime setaccdate.jpg

 

Apart from the 'normal' attributes all dates and times can be get/ set. I call normal MS-DOS date and time 'moddate' and 'modtime': means date/ time of last modification, but not in their function-name for simplicity. Date of last access is 'accdate' and date and time of creation on disk 'creadate' and 'creatime'. Last three are normally NOT set by MS-DOS, as far as I know.

 

A few examples using functions from the third print-screen above. Be aware I use further the command-line front-end ATTRIBFT.G4B (G4B is a known command-extension set by my MENU.LST):

 

ATTRIBFT attribecho setattrib attriballecho setdatetime setaccdate getdatetimeattriball.jpg

 

BTW the last used function in the print-screen before is showed to introduce an instance the 'result-variable' contains so-called 'set-variables'. Also can be seen set date is protected (set time too).

 

For curiosity I included read-out of the byte used by Windows-NT to give case-information of the name-part and the extension-part of a 8+3 file-name. Also the value of the pointer to Extended Attribute (if non-zero. These EA's can not exist on FAT32).

 

The main part however is related to Long File Names, which was very heavy to get them 'near' with a Grub4Dos-script. The get-functions will not write anything to disk, but 'makelfn' and 'dellfn' will do.

 

See next print-screens for some examples, but keep in mind corresponding 8+3 file/ directory names must exist already on disk. I use grubutil 'FAT' for this purpose.

 

ÃTTRIBFT getsfn getsfnfile getsfnpath.jpg ATTRIBFT getlfn.jpg ATTRIBFT makelfn II.jpg ATTIBFT dellfn II.jpg

 

BTW I tried to protect every 'write to disk' heavily, Grub4dos has no internal protection. Although I even hard-coded in the script not to write below 0x200, there are always other risks than just overwriting your Partition Boot Record. So if you would like to try set/ make/ del-functions: better not on your main FAT-OS, but best on an image, or even mapped to memory, or in a virtualised environment (I used Virtual Box and Qemu for Android). Always back-up first!

 

I am highly indebted to Wonko the Sane, as can be seen 'higher' in this thread. I used his version for sub-routine ':checksumSFN' and a simplified version of his ideas for the 'help-system', as can be seen in the print-screens above.

 

A small note about my structure of loosely linked library: I started with 'goto :%~1' instead of calling. So addressed label is starting point of a function and has full access to all command-line arguments, including %0, and can have their own goto :eof and own return-values.

ATTRIBFT.LLL is using two return values: 1) the variable 'result' OR the variable 'message', containing some text if there is no result. 2) Always the variable 'output', containing set variables like filesystem and (partial) read-out of the Partition Boot Record.

 

A few notes about scripting:

One of my test VHD's was 40GB (FAT32 of course) and filled with about 17GB of files. Searching with 'cat' and using '%?%' to get the offset on disk seems to be limited to 32-bits values. So I had to use lines like these:

 

raw cat --skip=%bytedone% --locate="%ENTRY%" --length=%dirlen% --number=1 %device%%0+%devsect% | set entry= &; if exist entry && set /A entry=0x%entry%

 

Maybe the part '&; if exist entry &&' is not needed, I am just used to it. :ph34r:

 

This gives a serious limitation, only '--number=1' can be used. In case of finding a directory-entry like in the line above, the first entry is searched only, so no problem. However when I had to search for contiguous deleted directory-entries (E5 on first byte), 'things' became more difficult. Although luckily clusters start always on a sector-border, so E5-not-on-first-byte can be sorted out by calc and set a higher offset for next search-loop, calc is limited to 0x7FFFFFFF regarding dividing operations. So from 2GB on I had to insert in my lines scripting like: 

 

'calc 0x%skipbyte:~-2,2% % 0x20 &; set /A skipbyte=%skipbyte%-%@retval%+0x20 &; ....

 

So only last two bytes are evaluated by calc (be aware directory-entries are always 32 byte-units, so there is a remainer only if the evaluated value is not a multiple of 0x20 = 32)



#37 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 15 June 2022 - 01:26 PM

deomsh, on 06 Jun - 1:06 AM, said:

A few notes about scripting:
One of my test VHD's was 40GB (FAT32 of course) and filled with about 17GB of files. Searching with 'cat' and using '%?%' to get the offset on disk seems to be limited to 32-bits values. So I had to use lines like these:

raw cat --skip=%bytedone% --locate="%ENTRY%" --length=%dirlen% --number=1 %device%%0+%devsect% | set entry= &; if exist entry && set /A entry=0x%entry%
 

Maybe the part '&; if exist entry &&' is not needed, I am just used to it. :ph34r:

 

This gives a serious limitation, only '--number=1' can be used. In case of finding a directory-entry like in the line above, the first entry is searched only, so no problem.

 

Sadly this appears not to be true. In certain cases there can exist collisions! Although I didn't find them 'in the wild' they appear if I 'construct' some file/ directory names.

A bad find would occur if two Short File Names are on the same cluster and if the second in the directory is a subset of the first AND the last of the eleven (8+3) bytes of the second name on disk is same as the attribute-byte.

 

See print-screen the case of file-names 'LNAME' and 'NAME', before and after repair:

ATTRIBFT collision if filename is subset and last of 11 chars is same as attribute-value + repair in v0.6 II.jpg

BTW directories will behave in the same way only if attribute contains the 'Archive-bit' (possible range (0x)30-37)

 

So in the end I have to add my calc-trick (and some more for adjusting search-region +security):

raw cat --skip=%offset% --locate="%ENTRY%" --length=%search% --number=1 %device%%0+%devsect% | set entry= &; if exist entry && set /A entry=0x%entry% &; if %entry%>=%offset% && calc 0x%entry:~-2,2% % 0x20 &; set /A offset=%entry%-%@retval%+0x20 &; if %offset%<=%endentry% && set /A search=%bytedone%-%offset%+%dirlen% && goto :skipcopygetlfn ! set entry=

Because earlier ATTRIB.G4B used same sub-routine, I had to make a bug-fix: https://github.com/d...ases/tag/V0.4.4

BTW I also corrected a bug in ATTRIB.G4B: first directory (directory-entry in root-directory) not found on FAT32-devices with small clustersize (NOT a bug on ATTRIBFT.LLL v.0.5.1).

For ATTRIBFT.LLL is added the bugfix for collisions too. Further following changes of functionality:

1) faster execution of function 'getlfn'
2) new function 'setlabelattrib'. For specs use: ATTRIBFT.LLL help setlabelattrib
3) dropped function 'getnumclus', is contained in set-variable %output% anyway

https://github.com/d...leases/tag/V0.6



#38 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 21 June 2022 - 04:19 PM

I am afraid, I introduced a potential bug in ATTRIBFT.LLL version 0.6

 

It is all about adding a line to read-out a variable from the command-line, sent by another sub-routine. If this variable contains spaces at the end, it is possible they will be deleted by grub4dos.

 

So far I could test only the function 'getsfn' is involved. Be aware this function is designed to read-out only a (valid) Short File Name for the corresponding Long File Name, if a Long File Name is input AND both exist on disk.

 

First print-screen shows the potentially buggy line I added in version 0.6 (selected black line). More upwards the call can de identified.

 

ATTRIBFT ONLY v6.0 BUG in getsfn if name is less than 8 chars long because of missing DBQ's in sub checklfnentry 'set sfn=%~1' IV.jpg

 

BTW as can be seen in case of function 'getsfn' checksum-check is not for all entries of the Long File Name, only the directory-entry just 'before' the entry of the corresponding Short File Name. So not fully safe.  :)

Function 'getlfn' was already upgraded in version 0.6 to do this check check if sfn-checksum is valid for all entries of the corresponding Long File Name. edit: I fooled myself; shown is the first check, if the Long File Name uses more entries, the checksum is included in the search-loop (at least since unpublished version 0.0.4). Function 'getlfn' checks all Long File Name entries too.

 

Next print-screen shows the bug in action, but watch the grub4dos version. :angry:

At the end of the print screen can be seen the bug is 'healed': I just added double-quotes around set "sfn=%~1"  Also continuing the line with &; some-cmd  will do the trick, even without double-quotes. :confused1:

 

ATTRIBFT ONLY v6.0 BUG grub4dos version 20211217 in getsfn if name is less than 8 chars long because of missing DBQ's in sub checklfnentry 'set sfn=%~1' NOT if afterwards ' &; + cmd' VII.jpg

 

BTW Function 'getlfn' shown before is safe, because the variable 'sfn' contains escaped ASCII-spaces.

 

It appears that newer grub4dos versions tend to remove spaces at the end of a line/ variable. I remember @steve6375 raised an issue about it.

However there seems to be no issue with piping, like the line: raw cat --skip=%entry% --length=11 %device%%0+%devsect% | set sfn=

 

On older grub4dos versions the bug is not there:

 

ATTRIBFT ONLY v6.0 BUG in getsfn if name is less than 8 chars long because of missing DBQ's in sub checklfnentry 'set sfn=%~1' NOT with Grub4dos v 20190909 VI.jpg

 

BTW last print-screen is older than the print-screen just before.

 

If I have finished next version 0.6.1, potential bug will be fixed too.



#39 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 28 June 2022 - 06:33 PM

Changes V0.7:

 

1) Bugfix in function 'getsfn' in case Long File Name < 11 chars (fix needed in 'newer' Grub4dos versions)
2) Bugfix in function 'getsfn' in case Long File Name in path, but file is Short File Name
3) Bugfix in function 'getlfn' for root (fat12/ FAT16)
4) Bugfix for function 'getchainclus'
5) Function 'dellfn' will search full cluster-chain in a directory and delete ALL entries of searched Long File Name (Short File Name entry still untouched!)
6) Function 'setlabelattrib': label now new argument after DEVICE, instead DEVICE/LABEL
7) Starting spaces allowed in Long File Name in all functions of relevance, EXCEPT function 'makelfn'
8) Some protection of command-line, most functions will abort if too many arguments are used
9) Grub4dos operators ' && ', ' &; ', ' ;; ' and ' ! ' can be used in Long File Names (full FILE between double-qoutes mandatory: "FILE")

 

https://github.com/d...eases/tag/v_0.7

 

About function 'dellfn': in an ideal FAT-world there are no duplicates, but non-Long File Name aware OS's/ utilities can easily create 'orphaned' Long File Names. For instance grubutil 'FAT' (functions 'ren' and 'del') and even MS-DOS 7 (only safe in a Windows' MS-DOS box).

 

 

About 'starting spaces' in Long File Names: I made them unintentionally with Total Commander. I first thought something has been changed in Windows 10, but it seems to be a 'private action'. Windows Explorer still removes 'starting spaces'. So I added this possibility to ATTRIBFT.LLL, except for function 'makelfn', because I will (try to) follow Microsoft's FAT32 specification.

 

On the print-screen the results of both can be seen, on my 2880K floppy image in VBox, accessed from Windows 10 with help of ImDisk to make the LFN's.

 

LFN TEST starting spaces removed by Windows Explorer, not by Total Commander I.jpg

 

BTW I changed original scripting lines in :main to not auto-remove 'starting spaces' anymore (except 'makelfn'):

 

echo -e "%name%" | set name= &; set "name=%name:~1,-1%"
if exist ext && if "%ext%"=="." && set ext=
if exist ext && echo -e "%ext%" | set ext= &; set "ext=%ext:~1,-1%"

:nospacedotloop
if exist ext && call Fn.11 "%ext:~-1,1%" " " && set "ext=%ext:~0,-1%" && goto :nospacedotloop
if not exist ext && call Fn.11 "%name:~-1,1%" " " && set "name=%name:~0,-1%" && goto :nospacedotloop
if not exist ext && call Fn.11 "%name:~-1,1%" "." && set "name=%name:~0,-1%" && goto :nospacedotloop
if %mode%==makelfn && call Fn.11 "%name:~0,1%" " " && set "name=%name:~1%" && goto :nospacedotloop


I also found-out the existence of (last) dot in the command-line argument triggers %~x1 to 'see' an extension, chars behind are not tested. To be sure script will remove 'ext' in such a case (see second script-line above; if exist ext maybe superfluous because && set ext= already used).

 

edit: some changes added to make version 0.7 'good' (Github doesn't like this, so new tag 'v_0.7' introduced)



#40 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 06 July 2022 - 01:09 PM

While working on version v0.7.1 I run into problems. So I definite need some HELP :baby:

 

I was working on some loose ends regarding 'forbidden chars'. Long ago I routinely added '%' to this list, although NOT forbidden in FAT, but I will not support this char to avoid collisions with the Grub4dos scripting language.

 

An even number of chars on the command-line of ATTRIBFT.LLL (or ATTRIBFT.G4B) is not a real problem, if the variable exists the '%...%' are gone, otherwise rejected by my sub-routine :checkforbiddenchars. Same with %1-%9, so everything seemed to be 'good'.

 

In case of reading filenames from disk, I use piping from 'cat --hex FILE', so detecting '(\x)25' is not a problem either.

 

However when I checked routinely '%a'-'%z' and '%A'-'%Z' I found following five strange cases: '%c', '%s', '%u', '%x' and '%X'. See following print-screens.

 

ATTRIBFT checkforbiddenchars = behavior of %cfolder.h f%colder.h .%ch .%chh NO SOLUTION IX.jpg ATTRIBFT checkforbiddenchars = behavior of .%sh .%shh only NO SOLUTION V.jpg ATTRIBFT checkforbiddenchars = behavior of %ufolder.h f%uolder.h .%uh .%uhh only NO SOLUTION VI.jpg ATTRIBFT checkforbiddenchars = behavior of %xfolder.h f%xolder.h .%xh .%xhh NO SOLUTION VII.jpg ATTRIBFT checkforbiddenchars = behavior of %Xfolder.h f%Xolder.h .%Xh .%Xhh NO SOLUTION VIII.jpg

 

I solved the case of '%c' by adding if not %forbiden%==Y && call Fn.11 "%~1" "\x01" && set forbiden=Y to my sub-routine, result can be seen in first print-screen. But why '%c' is transformed to an ASCII-control code???

BTW variable name is not a political statement, although somehow 'funny', but just to stay within 8 chars.

 

About the other cases: I have no idea.

 

In cases '.%sh' and '.%shh', '%s' first vanishes, but later gave really strange results as can be seen in the 'message', number of chars 'h' is doubled, path too.

 

In cases '%u' and '%x' ('%X' seems to be identical to '%x') an unidentified hex numbers appears, and in case of '%x' with another number in 'message' ('%X' gives same numbers as '%x', only hex-chars in uppercase).

 

BTW ATTRIBFT.LLL 'sents' (sometimes) messages if there is no 'result', ATTRIBFT.G4B echos them.

 

While 'googling' I found '%c', '%s' and '%u' are used in C, same language Grub4dos is written in (as far as I know).

 

Any idea's? :sos:



#41 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16047 posts
  • Location:The Outside of the Asylum (gate is closed)
  •  
    Italy

Posted 06 July 2022 - 02:03 PM

I don't get it (as often happens).

 

If the percentage sign is not allowed (in your implementation, correctly as it will likely create havoc in grub4dos just as it may do in DOS or in Windows command line), it is not allowed, so there won't be any %C or %anyotherletter.

 

I can understand, and I am morally supporting those that really-really need to insert a % in a filename (all three of you) but life is tough, and  I sometimes dream about "offensive feedback",  computers/displays that would unfold a robotic arm and slap you (hard) in the face when you type something plainly stupid (the second time, the first time an on screen warning would suffice).

 

 

BTW variable name is not a political statement, although somehow 'funny', but just to stay within 8 chars.

Good one :smiling9:

notvalid would do as well, just in case.

 

:duff:

Wonko

 

 

 



#42 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 06 July 2022 - 07:50 PM

Thanks a lot for your feedback.

 

It is not the user-side I worries about, but more if output of ls or FAT is parsed. Maybe this should be not a problem to solve inside the Loosely Linked Library, but by 'Software' using the LLL. But problems should be solved somewhere.

 

I tested the %-thing inside Windows 10 CMD, but Microsoft does not seem to have a problem with it's own FAT32-specification. See first two print-screens:

 

CMD Windows 10 behavior of %c-%s-%u-%x I.jpg CMD + asterisk wildcard Windows 10 behavior of %c-%s-%u-%x II.jpg

 

I am working on a script named FATLFN.G4B. It's ment as a frontend to make grubutil' FAT Long File Name-aware, and some more. Of cause this script is 'loosely' (but in fact not so 'loosely') dependent on ATTRIBFT.LLL

 

In the next print-screen output of FAT dir and FATLFN dirx are compared (FATLFN dir is available too, but additional function dirx is more usefull here).

 

FAT dir + FATLFN dirx ATTRIB70 Function 'getlfn' behavior of %c-%s-%u-%x VI.jpg

 

BTW FAT dirx is a typo, but FAT does not care...

 

As can be seen on the print-screen, FAT dir has no troubles with '%', but FATLFN dirx shows <FOLDER.6A70H> instead of <FOLDER.%XH>. So no user input at all, except choosing DEVICE/PATH.

Further only one Long File Name is detected, even showing one '%' (in the test ATTRIBFT.LLL version 0.7.0 was used by FATLFN.G4B).

 

If I make a second folder and copy with Total Commander a rearranged set of same folders, with FOLDER.%XH last, things looks different in case of FATLFN dirx: three Long File Names detected:

 

FAT dir + FATLFN dirx ATTRIB70 Function 'getlfn' behavior of %c-%s-%u-%x BUT FOLDER.%XH is last in (fd1)-PROCENT2 VII.jpg

 

In case of using output of FAT dir 'things' are relatively safe, found associated Long File Names containing '%' can be skipped, and non-existent <FOLDER.6A70H> too.

 

But parsing output of LS containing Long File Names can give more serious problems in this respect.

 

About 'notvalid' instead of 'forbiden': thanks for the idea :)



#43 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 4 weeks ago

Changes ATTRIBFT.LLL v0.7.1:
1) Bugfix in function 'getlfn' for Grub4dos operators ' && ', ' &; ', ' ;; ' and ' ! '
2) Bugfix for sub-routine ':lastcluster' if at FAT-end there are 1, 2 or 3 free clusters on FAT12 or 1 free cluster on FAT16/ FAT32: no addition of (emptied!) directory cluster to the directory-clusterchain
3) Bugfix for sub-routine ':lastcluster' if directory-clusterchain is already 2MB, no addition of (emptied!) directory cluster to the directory-clusterchain
4) More protection of command-line if arguments contains '%' (except %u, %s, %x and %X => these must be taken care of 'by Software')
5) Grub4dos color-codes (starting with '$[0x') added to list of forbidden chars (function 'getlfn' not affected, Software should take care if echoing!)
6) Grub4dos operators ' && ', ' &; ', ' ;; ' and ' ! ' also can be used in Long File Names in PATH (full FILE between double-qoutes mandatory: "FILE" OR use escaped '\ ' spaces)

https://github.com/d...ases/tag/v0.7.1

Print-screen about handling of Grub4dos color codes starting with '$[0x':

ATTRIBFT v0.7.1 Handling of Grub4dos color-codes starting with $0x.jpg


Print-screen about handling of Grub4dos operators in PATH (if chars are valid on FAT):


ATTRIBFT v0.7.1 Handling of Grub4dos operators in PATH (if chars are valid).jpg

#44 deomsh

deomsh

    Frequent Member

  • Advanced user
  • 144 posts
  •  
    Netherlands

Posted 3 weeks ago

I made some new functions using ATTRIBFT.LLL. I started trading less used functions, but because I can not 'grow' so much I added the new 'higher' functions to the front-end ATTRIBFT.G4B.

 

Next print-screen illustrates lack of space in ATTRIBFT.LLL, but plenty of space in ATTRIBFT.G4B :)

 

TEXTSTAT ATTRIBFT.LLL v0.8 and ATTRIBFT.G4B v0.4.jpg

 

I 'composed' the functions 'viewdir' and 'viewentry' using my personal 'API' :P

 

Following print-screens will tell the 'story':

 

ATTRIBFT.G4B function 'viewdir' on (hd3,0)-makelfn- begining of first directory cluster.jpg ATTRIBFT.G4B function 'viewentry' on (hd3,0)-makelfn-ABCDEF~1 + getlfn + LFN.jpg

 

Function 'viewdir' only imports getsfnpath and getchainclus (first time without number, then with ordinal number in the directory clusterchain and loops).

Function 'viewentry' imports getsfnpath, getsfnentry, attriballecho and getlfnentries.

 

I will add ATTRIBFT.G4B later on Github, if version 0.8 of ATTRIBFT.LLL is 'ready'. But if you like, you can already use:

!BAT
#-#+ ATTRIBFT.G4B v.0.4 (20220719), by deomsh
#-#+ Command-line frontend for ATTRIBFT.LLL
set result=
set message=
if "%~1"=="viewdir" && goto :viewdir
if "%~1"=="viewentry" && goto :viewentry
ATTRIBFT.LLL %*
#NOTNEEDEDANYMORE#if exist result && if "%~1"=="viewentry" &; %result% && goto :eof
if exist result &; if "%result:~0,1%"==" " && echo $[0x00]"$[0xF0]%result%
if exist result &; if not "%result:~0,1%"==" " && echo $[0x00]"$[0x07]%result%
#ORG#if exist result && echo $[0x00]"$[0x07]%result%
if exist message && echo $[0x00]"$[0x07]%message%
goto :eof

:viewdir
setlocal && set *
shift
pager status > nul ;; set /a pagerst=%@retval% > nul
pager on
call ATTRIBFT.LLL getsfnpath %* &; if not exist result && goto :endofviewdir ! set sfnpath=%result% && set result=
%output%
if "%sfnpath%"=="/" && if not /i %filesys%==fat32 && set sfnpath=
set /u filesys=%filesys%
if exist sfnpath && call ATTRIBFT.LLL getchainclus %* &; if not exist result && goto :endofviewdir ! set chainlen=%result% && set result=
set counter=1 && if not exist sfnpath && set chainlen=1
:viewdirloop
if not %counter%<=%chainlen% && goto :endofviewdir
if exist sfnpath && if %counter%<=%chainlen% && call ATTRIBFT.LLL getchainclus %* %counter% &; if not exist result && goto :endofviewdir ! set clusnum=%result% && set result=
if exist sfnpath && set /A skip=%clusnum% - 2 * %clussize% + %dataarea% > nul && set cluslen=%clussize%
if not exist sfnpath% && if exist root && set skip=%root% && set /A cluslen=%dataarea%-%root% > nul
if exist sfnpath && echo Cluster %counter%/%chainlen% Cluster-number %clusnum% (%filesys%)
if not exist sfnpath && if exist root && echo Root Directory (%filesys%)
raw cat --hex --skip=%skip% --length=%cluslen% %checkdev%%0+%devsect%
echo -n $[0x0F][Hit Q another time to quit 'viewdir', any other key to continue] && set keycode= &; pause --wait=180 --test-key > nul &; set /A keycode=%@retval% > nul
if not %keycode%==0x1051 if not %keycode%==0x1071 || goto :endofviewdir
call Fn.5 0 24 || echo -e -n \x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20 && echo
set /a counter=%counter%+1 > nul && goto :viewdirloop
:endofviewdir
if exist message && echo $[0x00]"$[0x07]%message%
if %pagerst%>=1 && pager on ! pager off
endlocal
goto :eof

:viewentry
setlocal && set *
shift
pager status > nul ;; set /a pagerst=%@retval% > nul
pager on
debug 1
call ATTRIBFT.LLL getsfnpath %* &; debug msg=0 &; if not exist result && goto :endofviewentry ! set sfnpath=%result% && set result=
%output%
call ATTRIBFT.LLL getsfnentry %* &; debug msg=0 &; if exist result && set sfnentry=%result% && set result= ! set "sfnmsg=%message%" && set message=
if exist sfnentry && setlocal && set * && set sfnentry=%sfnentry% && set "output=%output%" &; %output%
if exist sfnentry && if %sfnentry%>=%dataarea% && set /a cluster=%sfnentry%-%dataarea%/%clussize%+2 > nul
if exist sfnentry && set /A start=%cluster% - 2 * %clussize% + %dataarea% > nul
if exist sfnentry &; calc %sfnentry% % %clussize% > nul || set "echo=echo"
if exist sfnentry &; if exist root && set "clusmsg=echo ROOT starting at %root%" ! set "clusmsg=echo Cluster %cluster% starting at %start%"
if exist sfnentry && endlocal && set "echo=%echo%" && set "clusmsg=%clusmsg%" && set message=
if exist sfnentry && call ATTRIBFT.LLL attriballecho %* &; debug msg=0 &; if exist result && set "attrib=%result%" && set result= ! set "attrmsg=%message%" && set message=
if exist sfnentry &; setlocal && set * && set "output=%output%" && set sfnentry=%sfnentry% &; %output% &; set /A address=%sfnentry%+28 > nul && set device=%checkdev% &; call :readdisk "%address%" &; endlocal && set result=%result% &; set /A hexsize=%result%&0xffffffff > nul && set /a decisize=%result%&0xffffffff > nul && set result= && set message= &; %output% &; set /u filesys=%filesys%
if exist sfnentry && if not exist echo && set "catentry=raw cat --hex --skip=%sfnentry% --length=0x20 %checkdev%%0+%devsect% && echo %attrib% && echo Filesize %decisize% (HEX:%hexsize%) Byte(s)"
if exist sfnentry && if exist echo && set "catentry=%clusmsg% && raw cat --hex --skip=%sfnentry% --length=0x20 %checkdev%%0+%devsect% && echo %attrib% && echo Filesize %decisize% (HEX:%hexsize%) Byte(s)"
if not exist sfnentry && set "clusmsg=echo sfnentry of %~2 not found (%filesys%)"
call ATTRIBFT.LLL getlfnentries %* &; debug msg=0 &; if not exist result && set "lfnmsg=%message%" && set message=
%result% &; set result=
set /u filesys=%filesys%
if exist lfnentry && set /a cluster0=%lfnentry%-%dataarea%/%clussize%+2 &; set /A start0=%cluster0% - 2 * %clussize% + %dataarea% &; if %lfnentry%>=%dataarea% && set "clusmsg0=echo Cluster %cluster0% starting at %start0% (%filesys%)" ! set "clusmsg0=echo ROOT starting at %root% (%filesys%)"
if exist lfnentryA && set /a clusterA=%lfnbyteA%-%dataarea%/%clussize%+2 &; set /A startA=%clusterA% - 2 * %clussize% + %dataarea% &; set "clusmsgA=echo Cluster %clusterA% starting at %startA%"
if exist lfnentryB && set /a clusterB=%lfnbyteB%-%dataarea%/%clussize%+2 &; set /A startB=%clusterB% - 2 * %clussize% + %dataarea% &; set "clusmsgB=echo Cluster %clusterA% starting at %startB%"
if exist lfnentry && if not exist lfnbyteA && if not exist lfnbyteB && set /a length=%n% * 0x20 &; set "result=%clusmsg0% && raw cat --hex --skip=%lfnentry% --length=%length% %checkdev%%0+%devsect%"
if exist lfnentry && if exist lfnbyteA && if not exist lfnbyteB && set /a length2=%lfnent01%+0x20-%lfnbyteA% &; set /a length1=%n% * 0x20 - %length2% &; set "result=%clusmsg0% && raw cat --hex --skip=%lfnentry% --length=%length1% %checkdev%%0+%devsect% && %clusmsgA% && raw cat --hex --skip=%lfnbyteA% --length=%length2% %checkdev%%0+%devsect%"
if exist lfnentry && if exist lfnbyteA && if exist lfnbyteB && set /a length3=%lfnent01%+0x20-%lfnbyteA% &; set length2=%clussize% && set /a length1=%n% * 0x20 - %length3% - %length2% &; set "result=raw cat --hex --skip=%lfnentry% --length=%length1% %checkdev%%0+%devsect% && %clusmsgB% && raw cat --hex --skip=%lfnbyteB% --length=%length2% %checkdev%%0+%devsect% && %clusmsgA% && raw cat --hex --skip=%lfnbyteA% --length=%length3% %checkdev%%0+%devsect%"
if exist catentry && if exist lfnentry && set "result=%result% && %catentry%"
if exist catentry && if not exist lfnentry && set "result=%clusmsg% (%filesys%) && %catentry%" && set message=
if not exist catentry && if exist lfnentry && set "result=%result% && echo Orphaned Long File Name" && set message=
if /i %filesys:~0,3%==fat && if not exist catentry && if not exist lfnentry && set "result=%clusmsg% && echo %message% (%filesys%)"
%result%
:endofviewentry
if exist message && echo $[0x00]"$[0x07]%message%
if %pagerst%>=1 && pager on ! pager off
endlocal
goto :eof

:readdisk
setlocal && set * && set device=%device% && set devsect=%devsect%
raw cat --hex --skip=%~1 --length=4 %device%%0+%devsect% | set litleend=
set LE=%litleend:~10,11% &; set result=0x%LE:~9,2%%%LE:~6,2%%%LE:~3,2%%%LE:~0,2%
endlocal && set result=%result%
goto :eof

BTW: variable %output% is used, be aware 'device' is renamed to 'checkdev', needed if optional argument input="%output%" is used (only needed if speed is a real issue, so not in this case).

 

BTW2: sub-routine ':readdisk' is directly taken from ATTRIBFT.LLL (renamed only). Same functionality as Grub4dos internal function 'read', but you can read a 32 bit value directly from disk, with conversion from little-endian to hex (big-endian). Untested if there are less than 4 bytes left to read-out, but I expect no troubles.

 

In case copying of the script is a problem:

 

Attached File  ATTRIBFT.G4B_v0.4.ZIP   1.75KB   9 downloads







Also tagged with one or more of these keywords: grub4dos

2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users