home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 6 File / 06-File.zip / ramfs102.zip / src / opencrea.c < prev    next >
C/C++ Source or Header  |  2002-09-28  |  9KB  |  352 lines

  1. #include "includes.h"
  2.  
  3.  
  4.  
  5. /* static */
  6. void ShareAccess (USHORT usOpenMode, USHORT _ss *pfShare, USHORT _ss *pfAccess)
  7. {
  8.   switch (usOpenMode & 0x0070)
  9.   {
  10.     case OPEN_SHARE_DENYREADWRITE:
  11.        *pfShare = SHARE_DENYREAD | SHARE_DENYWRITE;
  12.        break;
  13.  
  14.     case OPEN_SHARE_DENYWRITE:
  15.        *pfShare = SHARE_DENYWRITE;
  16.        break;
  17.  
  18.     case OPEN_SHARE_DENYREAD:
  19.        *pfShare = SHARE_DENYREAD;
  20.        break;
  21.  
  22.     case OPEN_SHARE_DENYNONE:
  23.        *pfShare = 0;
  24.        break;
  25.   }
  26.  
  27.   switch (usOpenMode & 0x0007)
  28.   {
  29.     case OPEN_ACCESS_READONLY:
  30.        *pfAccess = ACCESS_READ;
  31.        break;
  32.  
  33.     case OPEN_ACCESS_WRITEONLY:
  34.        *pfAccess = ACCESS_WRITE;
  35.        break;
  36.  
  37.     case OPEN_ACCESS_READWRITE:
  38.        *pfAccess = ACCESS_READ | ACCESS_WRITE;
  39.        break;
  40.   }
  41. }
  42.  
  43.  
  44.  
  45.  
  46. /* static */
  47. int CreateFile (
  48.     PDIRENTRY     pEntry,
  49.     FLAT          flatBlkDir,
  50.     FLAT          flatEntry,
  51.     struct sffsi *psffsi,
  52.     struct sffsd *psffsd,
  53.     PVOLUME       pVolume,
  54.     USHORT      usAttr,
  55.     PEAOP      pEABuf )
  56. {
  57.   int       rc;
  58.   USHORT    fShare;
  59.   USHORT    fAccess;
  60.   POPENFILE pOpenfile;
  61.  
  62.   ShareAccess ((USHORT) psffsi->sfi_mode, &fShare, &fAccess);
  63.  
  64.   psffsi->sfi_DOSattr = (UCHAR) usAttr;
  65.   pEntry->fDOSattr    = (UCHAR) usAttr;
  66.   pEntry->datiCreate = pEntry->datiAccess = pEntry->datiWrite =
  67.     psffsi->sfi_mdate + ((ULONG)psffsi->sfi_mtime << 16);
  68.  
  69.   rc = fblock_init(&pEntry->fblkFile);
  70.   if (rc)  goto backout1;
  71.  
  72.   rc = chsize_helper(&pEntry->fblkFile, psffsi->sfi_size);
  73.   if (rc)  goto backout2;
  74.  
  75.   pEntry->blkEA.flatAddr = 0;
  76.   pEntry->blkEA.cbSize   = 0;
  77.   rc = EaAddList (&pEntry->blkEA, pEABuf);
  78.   if (rc)  goto backout2;
  79.  
  80.   rc = NearAlloc ((PNEARBLOCK *) &pOpenfile, sizeof(OPENFILE) + pEntry->cbName);
  81.   if (rc)  goto backout3;
  82.  
  83.   rc = UtilInsertEntry (pVolume, flatBlkDir, pEntry, &flatEntry);
  84.   if (rc)  goto backout4;
  85.  
  86.   pOpenfile->pNextOpenfile = pVolume->pFirstOpenfile;
  87.   pVolume->pFirstOpenfile = pOpenfile;
  88.   pOpenfile->flatEntry = flatEntry;
  89.   pOpenfile->fShare    = fShare;
  90.   memcpy (pOpenfile->szName, pEntry->achName, pEntry->cbName+1);
  91.   psffsd->pOpenfile = pOpenfile;
  92.  
  93.   return NO_ERROR;
  94.  
  95.  
  96. backout4:
  97.   NearFree (pOpenfile);
  98. backout3:
  99.   BlockFree (&pEntry->blkEA);
  100. backout2:
  101.   fblock_shutdown (&pEntry->fblkFile);
  102. backout1:
  103.   return rc;
  104. }
  105.  
  106.  
  107.  
  108.  
  109. /* static */
  110. int ReplaceFile (
  111.     PDIRENTRY     pEntry,
  112.     FLAT          flatEntry,
  113.     struct sffsi *psffsi,
  114.     struct sffsd *psffsd,
  115.     PVOLUME       pVolume,
  116.     USHORT        usAttr,
  117.     PEAOP      pEABuf )
  118. {
  119.   int       rc;
  120.   USHORT    fShare;
  121.   USHORT    fAccess;
  122.   POPENFILE pOpenfile;
  123.   FBLOCK    fblkFile;
  124.   BLOCK     blkEA;
  125.  
  126.   ShareAccess ((USHORT)psffsi->sfi_mode, &fShare, &fAccess);
  127.  
  128.   /* attempting to overwrite a read-only file? */
  129.   if (usAttr & DOSATTR_READONLY)
  130.     return ERROR_ACCESS_DENIED;
  131.  
  132.   /* any open instances of this file? */
  133.   pOpenfile = pVolume->pFirstOpenfile;
  134.   while (pOpenfile != 0)
  135.   {
  136.     if (pOpenfile->flatEntry == flatEntry)
  137.       return ERROR_SHARING_VIOLATION;
  138.     pOpenfile = pOpenfile->pNextOpenfile;
  139.   }
  140.  
  141.   rc = NearAlloc ((PNEARBLOCK *) &pOpenfile, sizeof(OPENFILE) + pEntry->cbName);
  142.   if (rc)  goto backout1;
  143.  
  144.   blkEA.flatAddr = 0;
  145.   blkEA.cbSize   = 0;
  146.   rc = EaAddList (&blkEA, pEABuf);
  147.   if (rc)  goto backout2;
  148.  
  149.   rc = fblock_init (&fblkFile);
  150.   if (rc)  goto backout3;
  151.  
  152.   rc = chsize_helper(&fblkFile, psffsi->sfi_size);
  153.   if (rc)
  154.   {
  155.    fblock_shutdown(&fblkFile);
  156.    goto backout3;
  157.   }
  158.   
  159.   /* everything that could go wrong has now been done. commit the changes. */
  160.   fblock_shutdown (&pEntry->fblkFile);
  161.   BlockFree (&pEntry->blkEA);
  162.  
  163.   pEntry->fblkFile       = fblkFile;
  164.   pEntry->blkEA.flatAddr = blkEA.flatAddr;
  165.   pEntry->blkEA.cbSize   = blkEA.cbSize;
  166.  
  167.   pEntry->fDOSattr    = (UCHAR) usAttr;
  168.   psffsi->sfi_DOSattr = (UCHAR) usAttr;
  169.   pEntry->datiCreate = pEntry->datiAccess = pEntry->datiWrite =
  170.     psffsi->sfi_mdate + ((ULONG)psffsi->sfi_mtime << 16);
  171.   VMWrite (flatEntry, pEntry, sizeof(DIRENTRY)-sizeof(pEntry->achName) + pEntry->cbName);
  172.  
  173.   pOpenfile->pNextOpenfile = pVolume->pFirstOpenfile;
  174.   pVolume->pFirstOpenfile = pOpenfile;
  175.   pOpenfile->flatEntry = flatEntry;
  176.   pOpenfile->fShare    = fShare;
  177.   memcpy (pOpenfile->szName, pEntry->achName, pEntry->cbName+1);
  178.   psffsd->pOpenfile = pOpenfile;
  179.  
  180.   return NO_ERROR;
  181.  
  182. backout3:
  183.   BlockFree (&blkEA);
  184. backout2:
  185.   NearFree (pOpenfile);
  186. backout1:
  187.   return rc;
  188. }
  189.  
  190.  
  191.  
  192.  
  193. /* static */
  194. int OpenFile (
  195.     PDIRENTRY     pEntry,
  196.     FLAT          flatEntry,
  197.     struct sffsi *psffsi,
  198.     struct sffsd *psffsd,
  199.     PVOLUME       pVolume )
  200. {
  201.   USHORT    fShare;
  202.   USHORT    fAccess;
  203.   POPENFILE pOpenfile;
  204.   POPENFILE pCurOpenfile;
  205.   int       rc;
  206.  
  207.   ShareAccess ((USHORT)psffsi->sfi_mode, &fShare, &fAccess);
  208.  
  209.   /* writing to a read-only file? */
  210.   if ((fAccess & ACCESS_WRITE)  &&  (pEntry->fDOSattr & DOSATTR_READONLY))
  211.     return ERROR_ACCESS_DENIED;
  212.  
  213.   /* conflicting sharing with another open instance of this file? */
  214.   pCurOpenfile = pVolume->pFirstOpenfile;
  215.   while (pCurOpenfile != NULL)
  216.   {
  217.     if (pCurOpenfile->flatEntry == flatEntry  &&  (pCurOpenfile->fShare & fAccess))
  218.       return ERROR_SHARING_VIOLATION;
  219.     pCurOpenfile = pCurOpenfile->pNextOpenfile;
  220.   }
  221.  
  222.   rc = NearAlloc ((PNEARBLOCK *) &pOpenfile, sizeof(OPENFILE) + pEntry->cbName);
  223.   if (rc)
  224.     return rc;
  225.  
  226.   /* all ok, open the file */
  227.   psffsi->sfi_ctime = (USHORT) (pEntry->datiCreate >> 16);
  228.   psffsi->sfi_cdate = (USHORT) (pEntry->datiCreate);
  229.   psffsi->sfi_atime = (USHORT) (pEntry->datiAccess >> 16);
  230.   psffsi->sfi_adate = (USHORT) (pEntry->datiAccess);
  231.   psffsi->sfi_mtime = (USHORT) (pEntry->datiWrite >> 16);
  232.   psffsi->sfi_mdate = (USHORT) (pEntry->datiWrite);
  233.   psffsi->sfi_size  = pEntry->fblkFile.fSize;
  234.   psffsi->sfi_DOSattr = pEntry->fDOSattr;
  235.   psffsi->sfi_type = (psffsi->sfi_type & STYPE_FCB) | STYPE_FILE;
  236.  
  237.   pOpenfile->pNextOpenfile = pVolume->pFirstOpenfile;
  238.   pVolume->pFirstOpenfile = pOpenfile;
  239.   pOpenfile->flatEntry = flatEntry;
  240.   pOpenfile->fShare    = fShare;
  241.   memcpy (pOpenfile->szName, pEntry->achName, pEntry->cbName+1);
  242.   psffsd->pOpenfile = pOpenfile;
  243.  
  244.   return NO_ERROR;
  245. }
  246.  
  247.  
  248.  
  249.  
  250.  
  251.  
  252. APIRET EXPENTRY FS_OPENCREATE (
  253.     struct cdfsi *pcdfsi,
  254.     struct cdfsd *pcdfsd,
  255.     PSZ        pName,
  256.     USHORT    iCurDirEnd,
  257.     struct sffsi *psffsi,
  258.     struct sffsd *psffsd,
  259.     ULONG    ulOpenMode,
  260.     USHORT    usOpenFlag,
  261.     PUSHORT    pusAction,
  262.     USHORT    usAttr,
  263.     PEAOP    pEABuf,
  264.     PUSHORT    pfgenflag )    /* not used */
  265. {
  266.   int      rc;
  267.   PVOLUME  pVolume;
  268.   DIRENTRY Entry;
  269.   FLAT     flatEntry;
  270.   FLAT     flatBlkDir;
  271.   struct vpfsi *pvpfsi;
  272.   struct vpfsd *pvpfsd;
  273.  
  274.   UtilEnterRamfs();
  275.   DEBUG_PRINTF3 ("FS_OPENCREATE  sfn=%d pName='%s' usAttr=0x%04X",
  276.          psffsi->sfi_selfsfn, pName, usAttr);
  277.  
  278.   FSH_GETVOLPARM (pcdfsi->cdi_hVPB, &pvpfsi, &pvpfsd);
  279.   pVolume = pvpfsd->pVolume;
  280.   flatBlkDir = pVolume->flatBlkRootDir;
  281.   pName += 3;
  282.   if (iCurDirEnd != 0xFFFF)
  283.   {
  284.     flatBlkDir = pcdfsd->pCurdir->flatBlkDir;
  285.     pName += iCurDirEnd-3;
  286.   }
  287.  
  288.   if (ulOpenMode & OPEN_FLAGS_DASD)
  289.   {
  290.     rc = ERROR_NOT_SUPPORTED;
  291.     goto end;
  292.   }
  293.  
  294.   switch (UtilLocate (&flatBlkDir, &flatEntry, &Entry, pName))
  295.   {
  296.     case LOC_NOPATH:
  297.        rc = ERROR_PATH_NOT_FOUND;
  298.        break;
  299.  
  300.  
  301.     case LOC_DIRENTRY:
  302.        rc = ERROR_ACCESS_DENIED;
  303.        break;
  304.  
  305.  
  306.     case LOC_NOENTRY:
  307.        switch (usOpenFlag & 0x00F0)
  308.        {
  309.          case OPEN_ACTION_CREATE_IF_NEW:
  310.             /* create a new file */
  311.             *pusAction = FILE_CREATED;
  312.             rc = CreateFile (&Entry, flatBlkDir, flatEntry, psffsi,
  313.                      psffsd, pVolume, usAttr, pEABuf);
  314.             break;
  315.  
  316.          case OPEN_ACTION_FAIL_IF_NEW:
  317.             rc = ERROR_OPEN_FAILED;
  318.             break;
  319.        }
  320.        break;
  321.  
  322.  
  323.     case LOC_FILEENTRY:
  324.        switch (usOpenFlag & 0x000F)
  325.        {
  326.          case OPEN_ACTION_OPEN_IF_EXISTS:
  327.             /* open an existing file */
  328.             *pusAction = FILE_EXISTED;
  329.             rc = OpenFile (&Entry, flatEntry, psffsi, psffsd, pVolume);
  330.             break;
  331.  
  332.          case OPEN_ACTION_REPLACE_IF_EXISTS:
  333.             /* replace an existing file */
  334.             *pusAction = FILE_TRUNCATED;
  335.             rc = ReplaceFile (&Entry, flatEntry, psffsi, psffsd,
  336.                       pVolume, usAttr, pEABuf);
  337.             break;
  338.  
  339.          case OPEN_ACTION_FAIL_IF_EXISTS:
  340.             rc = ERROR_OPEN_FAILED;
  341.             break;
  342.        }
  343.        break;
  344.   }
  345.  
  346. end:
  347.  
  348.   DEBUG_PRINTF1 (" => %d\r\n", rc);
  349.   UtilExitRamfs();
  350.   return rc;
  351. }
  352.