OS/2 codes: How to manipulate FAT32 paritions
On OS/2, in general, it's possible to access to any partitions in DASD mode. This is true for FAT32 partitions. Unfortunately, however, accessing in DASD mode may not work on FAT32 partitions, especially writing to them. Instead, FAT32.IFS provides special ioctl commands. Let's see the way accessing to FAT32 partitions.
1. Accessing FAT32 partitions in DASD mode
Accessing in DASD mode is the general ways on OS/2. Unfortunately, however, FAT32.IFS does not allow to access the areas beyond 2GB by default. This is true for HPFS.IFS. To overcome this problem, FAT32.IFS provides a special mode, SECTOR IO mode, like HPFS.IFS. If the sector io mode is enabled, accessing in DASD mode is performed in sectors not in bytes. To enable sector io mode, you should call DosFSCtl(), and pass 0xDEADFACE as a parameter list like this:
Here, FAT32_SECTORIO is 0x9014, and hfat32io is a handle for FAT32 partition opened in DASD mode.
Unfortunately, however, write access in DASD mode may fail due to ERROR_ACCESS_DENIED( error code 5 ) even if locking a partition succeeds. As well as, seeking may also fail. It seems a bug of FAT32.IFS.
After all, it's not recommended to use DASD mode to access FAT32 partitions.
2. Acessing FAT32 partitions with ioctl commands
Instead, FAT32.IFS provides special ioctl commands for reading from/writing to FAT32 partitions.
2.1. Reading sectors from FAT32 partitions
For reading sectors, you should call DosDevIOCtl() like this:
Here, rsd.ulSector is absolute sector number to read from and rsd.nSectors is sector count to read. SECTOR_SIZE is 512, hfat32io is a handle for FAT32 partition opened in DASD mode, IOCTL_FAT32 is IOCTL_GENERAL, and FAT32_READSECTOR is 0xFD.
2.2. Writing sectors to FAT32 partitions
For writing sectors, you should call DosDevIOCtl() like reading sectors:
Here, wsd.ulSector is absolute sector number to write to and wsd.nSectors is sector count to write. FAT32_WRITESECTOR is 0xFF. Others are the same values as reading sectors.
3. Locking/Unlocking FAT32 partitions
To access FAT32 partitions, it's required to lock/unlock them to prevent data corruptions due to accesses of another processes.
Locking and unlocking uses a generic ioctl command. They are IOCTL_DISK( 0x08 ) category, DSK_LOCKDRIVE( 0x00 )/DSK_UNLOCKDRIVE( 0x01 ) function.
Locking codes:
Unlocking codes:
4. Conclusion
FAT32.IFS provides two ways to access FAT32 partitions. One is to use DASD mode, the other one is to use ioctl commands. Out of these, using ioctl commands is recommended because FAT32.IFS does not support DASD mode access correctly.
When accessing to FAT32 partitions, do not forget to lock and to unlock them.
Here is the implementation of accessing FAT32 partitions.
1. Accessing FAT32 partitions in DASD mode
Accessing in DASD mode is the general ways on OS/2. Unfortunately, however, FAT32.IFS does not allow to access the areas beyond 2GB by default. This is true for HPFS.IFS. To overcome this problem, FAT32.IFS provides a special mode, SECTOR IO mode, like HPFS.IFS. If the sector io mode is enabled, accessing in DASD mode is performed in sectors not in bytes. To enable sector io mode, you should call DosFSCtl(), and pass 0xDEADFACE as a parameter list like this:
1 2 3 4 5 6 7 | ULONG cbData = 0; ULONG ulDeadFace = 0xDEADFACE; ULONG cbParam = sizeof( ulDeadFace ); DosFSCtl( NULL, cbData, &cbData, &ulDeadFace, cbParam, &cbParam, FAT32_SECTORIO, NULL, ( HFILE )hfat32io, FSCTL_HANDLE ); |
Here, FAT32_SECTORIO is 0x9014, and hfat32io is a handle for FAT32 partition opened in DASD mode.
Unfortunately, however, write access in DASD mode may fail due to ERROR_ACCESS_DENIED( error code 5 ) even if locking a partition succeeds. As well as, seeking may also fail. It seems a bug of FAT32.IFS.
After all, it's not recommended to use DASD mode to access FAT32 partitions.
2. Acessing FAT32 partitions with ioctl commands
Instead, FAT32.IFS provides special ioctl commands for reading from/writing to FAT32 partitions.
2.1. Reading sectors from FAT32 partitions
For reading sectors, you should call DosDevIOCtl() like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #pragma pack( 1 ) struct { ULONG ulSector; USHORT nSectors; } rsd; #pragma pack() ULONG cbParam; ULONG cbData; rsd.ulSector = iSector; rsd.nSectors = nSectors; cbParam = sizeof( rsd ); cbData = rsd.nSectors * SECTOR_SIZE; DosDevIOCtl(( HFILE )hfat32io, IOCTL_FAT32, FAT32_READSECTOR, &rsd, cbParam, &cbParam, pSectors, cbData, &cbData )); |
Here, rsd.ulSector is absolute sector number to read from and rsd.nSectors is sector count to read. SECTOR_SIZE is 512, hfat32io is a handle for FAT32 partition opened in DASD mode, IOCTL_FAT32 is IOCTL_GENERAL, and FAT32_READSECTOR is 0xFD.
2.2. Writing sectors to FAT32 partitions
For writing sectors, you should call DosDevIOCtl() like reading sectors:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #pragma pack( 1 ) struct { ULONG ulSector; USHORT nSectors; } wsd; #pragma pack() ULONG cbParam; ULONG cbData; wsd.ulSector = iSector; wsd.nSectors = nSectors; cbParam = sizeof( wsd ); cbData = wsd.nSectors * SECTOR_SIZE; DosDevIOCtl(( HFILE )hfat32io, IOCTL_FAT32, FAT32_WRITESECTOR, &wsd, cbParam, &cbParam, pSectors, cbData, &cbData )); |
Here, wsd.ulSector is absolute sector number to write to and wsd.nSectors is sector count to write. FAT32_WRITESECTOR is 0xFF. Others are the same values as reading sectors.
3. Locking/Unlocking FAT32 partitions
To access FAT32 partitions, it's required to lock/unlock them to prevent data corruptions due to accesses of another processes.
Locking and unlocking uses a generic ioctl command. They are IOCTL_DISK( 0x08 ) category, DSK_LOCKDRIVE( 0x00 )/DSK_UNLOCKDRIVE( 0x01 ) function.
Locking codes:
1 2 3 4 5 6 7 8 9 10 11 12 | BYTE bParam; BYTE bData; ULONG ulParamLen = sizeof( bParam ); ULONG ulDataLen = sizeof( bData );; bParam = 0; bData = 0; DosDevIOCtl(( HFILE )hfat32io, IOCTL_DISK, DSK_LOCKDRIVE, &bParam, ulParamLen, &ulParamLen, &bData, ulDataLen, &ulDataLen ); |
Unlocking codes:
1 2 3 4 5 6 7 8 9 10 11 12 | BYTE bParam; BYTE bData; ULONG ulParamLen = sizeof( bParam ); ULONG ulDataLen = sizeof( bData ); bParam = 0; bData = 0; DosDevIOCtl(( HFILE )hfat32io, IOCTL_DISK, DSK_UNLOCKDRIVE, &bParam, ulParamLen, &ulParamLen, &bData, ulDataLen, &ulDataLen ); |
4. Conclusion
FAT32.IFS provides two ways to access FAT32 partitions. One is to use DASD mode, the other one is to use ioctl commands. Out of these, using ioctl commands is recommended because FAT32.IFS does not support DASD mode access correctly.
When accessing to FAT32 partitions, do not forget to lock and to unlock them.
Here is the implementation of accessing FAT32 partitions.
- source: https://github.com/komh/os2codes/blob/master/system/fat32io.c
- header: https://github.com/komh/os2codes/blob/master/system/fat32io.h
- test: https://github.com/komh/os2codes/blob/master/system/fat32io-test.c
댓글
댓글 쓰기