home bbs files messages ]

Just a sample of the Echomail archive

Cooperative anarchy at its finest, still active today. Darkrealms is the Zone 1 Hub.

   OS2      Fidonet International OS/2 Conference      3,371 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 755 of 3,371   
   Jonathan de Boyne Pollard to All   
   Re: formatting to FAT32   
   02 Apr 11 15:16:45   
   
   Gecko/20110303 Thunderbird/3.1.9   
   rogrammer.misc,comp.os.os2.misc   
   UTC)   
   os2.utilities:156 comp.os.os2.programmer.misc:2071 comp.os.os2.misc:3118   
   From: Jonathan de Boyne Pollard    
      
    These bugs have been known for years, as you can see on the data of    
   > the msgs. Doesn't look like anyone has been working on it.   
   >   
   Well M. Ko has the ability to modify, recompile, and use FAT32.IFS, so    
   let's introduce FS_CHGFILEPTRL and see whether it fixes the problem M.    
   Ko stated that xe didn't know why this was happening. Here's a    
   hypothesis that seems reasonable. The data that we have are these:   
      
   * Raw access with DosRead/DosWrite/DosSetFilePtr works just fine on your    
   ~4GiB FAT32 volume.   
   * DosSetFilePtr() returns ERROR_SEEK on larger FAT32 volumes.   
   * M. Ko reports that the FS_CHGFILEPTR function of the IFS isn't even    
   being called in such circumstances.   
      
   The thing to remember, to start with, is that the whole "sector mode"    
   thing is a red herring. That's purely within the IFS driver itself. The    
   kernel knows nothing of it. As far as the kernel is concerned raw access    
   is *always* byte-by-byte and offsets are byte offsets. Once one gets    
   one's head around that, then a hypothesis positively leaps out. The OS/2    
   version 4.5 kernel, remember, has 64-bit file pointer support. So it's a    
   fair chance that what's happening is that the kernel is saying "Oho! The    
   application is trying to move the file pointer about, and this disc    
   volume is larger than 4GiB. So I'll use 64-bit file pointer    
   mechanisms.". The problem in such a circumstance is that FAT32.IFS    
   doesn't have a FS_CHGFILEPTRL entrypoint. The kernel sees a non-existent    
   entrypoint, and rather than falling back to the 32-bit one it simply    
   returns ERROR_SEEK.   
      
   By the way, in answer to the other question that came up all those years    
   ago: If you look at the VirtualBox shared folders OS/2 IFS driver    
   skeleton code, you'll see three out of four entrypoints complete with    
   function signatures. The four entrypoints are thus FS_CHGFILEPTR,    
   FS_CHGFILEPTRL, FS32_CHGFILEPTR, and FS32_CHGFILEPTRL. The entrypoints    
   ending in "L" take a 64-bit file offset value instead of a 32-bit one,    
   and the entrypoints beginning "FS32_" are 32-bit functions instead of    
   16-bit ones.   
      
   If this hypothesis is correct — and it's a fairly credible one — then    
   giving the kernel an actual "L" entrypoint to call when it wants to seek    
   around within a >4GiB volume will stop the ERROR_SEEKs. Making such a    
   function is dead easy. Just copy FS_CHGFILEPTRL, change the lOffset    
   parameter to a 64-bit signed integer, and (for now) add a check on the    
   desired to position to ensure that it is less than 0x1_0000_0000. Then    
   set the FSA_LARGEFILE attribute. This might necessitate doing    
   FS_NEWSIZEL, FS_CANCELLOCKREQUESTL, and FS_FILELOCKSL, as well; but the    
   same approach applies. Indeed, one could *rename* the non-"L" functions    
   to the "L" functions and then make the non-"L" functions into wrappers    
   that call the "L" functions. Something like the code at the end of this    
   message, which is off the top of my head, perhaps. (I suggest that those    
   with JFS source code access check what SFFSI structure is passed to an    
   "L" function.)   
      
   M. Ko has the ability to modify, recompile, and use FAT32.IFS, and you    
   apparently have JFS source code access. If xe does that, and you check    
   the SFFSI structure, I can supply CHKVOL to test against a >4GiB volume.   
      
   int far pascal FS_CHGFILEPTRL(   
        struct sffsi far * psffsi,		/* psffsi	*/   
        struct sffsd far * psffsd,		/* psffsd	*/   
        LONGLONG lOffset,			/* offset	*/   
        unsigned short usType,		/* type		*/   
        unsigned short IOFlag		/* IOflag	*/   
   )   
   {   
   PVOLINFO pVolInfo;   
   POPENINFO pOpenInfo = GetOpenInfo(psffsd);   
   LONGLONG  lNewOffset;   
   USHORT rc;   
      
       if (f32Parms.fMessageActive&  LOG_FS)   
          Message("FS_CHGFILEPTRL, Mode %d - offset %lld, current offset=%lu",   
          usType, lOffset, psffsi->sfi_position);   
      
       pVolInfo = GetVolInfo(psffsi->sfi_hVPB);   
       if (IsDriveLocked(pVolInfo))   
          return ERROR_DRIVE_LOCKED;   
      
       switch (usType)   
          {   
          case CFP_RELBEGIN :   
             if (lOffset<  0)   
                {   
                rc = ERROR_NEGATIVE_SEEK;   
                goto FS_CHGFILEPTRLEXIT;   
                }   
             lNewOffset = lOffset;   
             break;   
          case CFP_RELCUR  :   
             lNewOffset = psffsi->sfi_position + lOffset;   
             break;   
          case CFP_RELEND	:   
             lNewOffset = psffsi->sfi_size + lOffset;   
             break;   
          }   
       if (!IsDosSession()&&  lNewOffset<  0)   
          {   
          rc = ERROR_NEGATIVE_SEEK;   
          goto FS_CHGFILEPTRLEXIT;   
          }   
       /* This ensures that all positions are in the first 4GiB, preserving   
          the semantics of 32-bit file pointers.  Of course, with true large   
          file support, this test is unnecessary and wrong.  But we're not   
          setting out to do that at the moment.  */   
       if (lNewOffset>  (ULONGLONG)0xFFFFFFFF)   
          {   
          rc = ERROR_NEGATIVE_SEEK;   
          goto FS_CHGFILEPTRLEXIT;   
          }   
      
       /* Yes, we're casting to a ULONGLONG and then assigning into a ULONG.   
          This is so that we don't have to revisit this down the line.  */   
       if (psffsi->sfi_position != (ULONGLONG)lNewOffset)   
          {   
          psffsi->sfi_position = (ULONGLONG)lNewOffset;   
          pOpenInfo->ulCurCluster = FAT_EOF;   
          }   
       rc = 0;   
      
   FS_CHGFILEPTRLEXIT:   
       if (f32Parms.fMessageActive&  LOG_FS)   
          Message("FS_CHGFILEPTRL returned %u", rc);   
       return rc;   
   }   
      
   int far pascal FS_CHGFILEPTR(   
        struct sffsi far * psffsi,		/* psffsi	*/   
        struct sffsd far * psffsd,		/* psffsd	*/   
        LONG lOffset,			/* offset	*/   
        unsigned short usType,		/* type		*/   
        unsigned short IOFlag		/* IOflag	*/   
   )   
   {   
        /* The 32-bit function simply devolves to the 64-bit one.   
           If the SFFFSI structures differ, we might not be able to   
           do things this simply, and might have to cut and paste   
           instead.  */   
        return FS_CHGFILEPTRL(psffsi, psffsd, lOffset, usType, IOFlag);   
   }   
      
      
      
   --- Internet Rex 2.31   
    * Origin: virginmedia.com (1:261/20.999)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca