Jump to content











Photo
- - - - -

How to read-out FAT12 lookup-table?

grub4dos

  • Please log in to reply
37 replies to this topic

#26 Wonko the Sane

Wonko the Sane

    The Finder

  • Advanced user
  • 16027 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
  • 139 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
  • 16027 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
  • 139 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
  • 139 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
  • 139 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
  • 139 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
  • 139 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
  • 139 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
  • 139 posts
  •  
    Netherlands

Posted 4 weeks ago

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
  • 139 posts
  •  
    Netherlands

Posted 2 weeks ago

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
  • 139 posts
  •  
    Netherlands

Posted A week ago

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
  • 139 posts
  •  
    Netherlands

Posted 4 days ago

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.







Also tagged with one or more of these keywords: grub4dos

2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users