home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 552.lha / Format / EraseDisk.c next >
C/C++ Source or Header  |  1991-09-08  |  10KB  |  444 lines

  1. #include <devices/trackdisk.h>
  2. #include <dos/filehandler.h>
  3. #include <dos/dosextens.h>
  4. #include <exec/memory.h>
  5.  
  6. #include <clib/alib_protos.h>
  7. #include <clib/exec_protos.h>
  8. #include <clib/dos_protos.h>
  9.  
  10. extern struct DosLibrary *DOSBase;
  11.  
  12. struct BitmapBlock
  13. {
  14.     ULONG            Checksum;
  15.     ULONG            Bitmap[127];
  16. };
  17.  
  18. struct BitmapExtension
  19. {
  20.     ULONG            BitmapPointers[127];
  21.     ULONG            BitmapExtension;
  22. };
  23.  
  24. struct RootDirectory
  25. {
  26.     ULONG            PrimaryType;
  27.     ULONG            HeaderKey;
  28.  
  29.     ULONG            WhoKnows0;
  30.     ULONG            HashTableSize;
  31.     ULONG            WhoKnows1;
  32.  
  33.     ULONG            Checksum;
  34.  
  35.     ULONG            HashTable[72];
  36.  
  37.     ULONG            BitmapFlag;
  38.  
  39.     ULONG            BitmapPointers[25];
  40.     ULONG            BitmapExtension;
  41.  
  42.     struct DateStamp    LastRootChange;
  43.  
  44.     UBYTE            DiskName[32];
  45.  
  46.     ULONG            WhoKnows2[2];
  47.  
  48.     struct DateStamp    LastDiskChange;
  49.     struct DateStamp    CreationDate;
  50.  
  51.     ULONG            NextHash;
  52.     ULONG            ParentDir;
  53.  
  54.     ULONG            WhoKnows3;
  55.  
  56.     ULONG            SecondaryType;
  57. };
  58.  
  59. ULONG Bits[32] =
  60. {
  61.     0xFFFFFFFE,0xFFFFFFFD,0xFFFFFFFB,0xFFFFFFF7,
  62.     0xFFFFFFEF,0xFFFFFFDF,0xFFFFFFBF,0xFFFFFF7F,
  63.     0xFFFFFEFF,0xFFFFFDFF,0xFFFFFBFF,0xFFFFF7FF,
  64.     0xFFFFEFFF,0xFFFFDFFF,0xFFFFBFFF,0xFFFF7FFF,
  65.     0xFFFEFFFF,0xFFFDFFFF,0xFFFBFFFF,0xFFF7FFFF,
  66.     0xFFEFFFFF,0xFFDFFFFF,0xFFBFFFFF,0xFF7FFFFF,
  67.     0xFEFFFFFF,0xFDFFFFFF,0xFBFFFFFF,0xF7FFFFFF,
  68.     0xEFFFFFFF,0xDFFFFFFF,0xBFFFFFFF,0x7FFFFFFF
  69. };
  70.  
  71. UBYTE
  72. Local2Upper(UBYTE c)
  73. {
  74.     return((UBYTE)((((c) >= 224 && (c) <= 254) || ((c) >= 'a' && (c) <= 'z')) ? (c) - 32 : (c)));
  75. }
  76.  
  77. LONG
  78. Strcmp(UBYTE *a,UBYTE *b)
  79. {
  80.     for( ; Local2Upper(*a) == Local2Upper(*b) ; a++, b++)
  81.     {
  82.         if(!(*a))
  83.             return(0);
  84.     }
  85.  
  86.     return((LONG)(Local2Upper(*a) - Local2Upper(*b)));
  87. }
  88.  
  89. ULONG
  90. Checksum(ULONG *DiskSector)
  91. {
  92.     ULONG Sum;
  93.     SHORT i;
  94.  
  95.     for(Sum = 0, i = 0 ; i < (TD_SECTOR >> 2) ; i++)
  96.         Sum += DiskSector[i];
  97.  
  98.     return(Sum);
  99. }
  100.  
  101. LONG
  102. WriteBlock(struct IOExtTD *DevRequest,APTR Buffer,ULONG Offset)
  103. {
  104.     DevRequest -> iotd_Req . io_Command    = CMD_WRITE;
  105.     DevRequest -> iotd_Req . io_Data    = Buffer;
  106.     DevRequest -> iotd_Req . io_Length    = TD_SECTOR;
  107.     DevRequest -> iotd_Req . io_Offset    = Offset * TD_SECTOR;
  108.  
  109.     return((LONG)DoIO(DevRequest));
  110. }
  111.  
  112. LONG
  113. EraseDisk(UBYTE *DiskName,struct IOExtTD *DevRequest,ULONG FirstBlock,ULONG Blocks,ULONG Reserved,ULONG DosType)
  114. {
  115.     ULONG            *Bitmap,AllocSize;
  116.     APTR             Buffer;
  117.     struct BitmapBlock    *BitmapBlock;
  118.     struct BitmapExtension    *BitmapExtension;
  119.     struct RootDirectory    *RootDirectory;
  120.     LONG             i,Count,Root,Len;
  121.     LONG             BitmapCount,BitmapBlocks;
  122.     LONG             ExtensionCount,ExtensionBlocks = 0;
  123.     LONG             Error;
  124.  
  125.         /* Number of long words to allocate for the bitmap. */
  126.  
  127.     AllocSize = (Blocks - Reserved + 31) / 32;
  128.  
  129.         /* Allocate a block-sized buffer. */
  130.  
  131.     if(Buffer = AllocMem(TD_SECTOR,MEMF_PUBLIC|MEMF_CHIP))
  132.     {
  133.             /* Clear the buffer. */
  134.  
  135.         memset(Buffer,0,TD_SECTOR);
  136.  
  137.             /* Put the DOS type field into the first longword. */
  138.  
  139.         *(ULONG *)Buffer = DosType;
  140.  
  141.             /* And write it. */
  142.  
  143.         if(Error = WriteBlock(DevRequest,Buffer,0 + FirstBlock))
  144.             return(Error);
  145.  
  146.             /* Clear the other half. */
  147.  
  148.         memset(Buffer,0,TD_SECTOR);
  149.  
  150.             /* And write it. */
  151.  
  152.         if(Error = WriteBlock(DevRequest,Buffer,1 + FirstBlock))
  153.             return(Error);
  154.  
  155.             /* Allocate space for the bitmap. */
  156.  
  157.         if(Bitmap = (ULONG *)AllocMem(sizeof(ULONG) * AllocSize,MEMF_PUBLIC))
  158.         {
  159.                 /* Mark all blocks as `unused'. */
  160.  
  161.             for(i = 0 ; i < AllocSize ; i++)
  162.                 Bitmap[i] = ~0;
  163.  
  164.                 /* Determine number of bitmap blocks. */
  165.  
  166.             Count = BitmapBlocks = (AllocSize + 126) / 127;
  167.  
  168.                 /* If there are more than 25 bitmap blocks to create,
  169.                  * we will need at least one bitmap extension block.
  170.                  */
  171.  
  172.             if(Count > 25)
  173.             {
  174.                     /* The old filing system doesn't support bitmap
  175.                      * extension blocks.
  176.                      */
  177.  
  178.                 if(DosType == ID_DOS_DISK)
  179.                     return(-1);
  180.  
  181.                     /* Subtract 25 blocks since they will fit into the
  182.                      * root block.
  183.                      */
  184.  
  185.                 Count -= 25;
  186.  
  187.                     /* Add the extension blocks. */
  188.  
  189.                 do
  190.                 {
  191.                     ExtensionBlocks++;
  192.  
  193.                         /* Subtract the blocks that will fit into the
  194.                          * extension block.
  195.                          */
  196.  
  197.                     if(Count > 127)
  198.                         Count -= 127;
  199.                     else
  200.                         Count = 0;
  201.                 }
  202.                 while(Count);
  203.             }
  204.  
  205.                 /* Calculate the root block offset. */
  206.  
  207.             Root = Blocks >> 1;
  208.  
  209.             RootDirectory = Buffer;
  210.  
  211.             memset(RootDirectory,0,TD_SECTOR);
  212.  
  213.                 /* Fill in the root directory data. */
  214.  
  215.             RootDirectory -> PrimaryType    = 2;
  216.             RootDirectory -> HashTableSize    = 128 - 56;
  217.             RootDirectory -> BitmapFlag    = DOSTRUE;
  218.  
  219.             DateStamp(&RootDirectory -> LastRootChange);
  220.  
  221.             if((Len = strlen(DiskName)) > 31)
  222.                 Len = 31;
  223.  
  224.             RootDirectory -> DiskName[0]    = Len;
  225.  
  226.             CopyMem(DiskName,&RootDirectory -> DiskName[1],Len);
  227.  
  228.             DateStamp(&RootDirectory -> LastDiskChange);
  229.             DateStamp(&RootDirectory -> CreationDate);
  230.  
  231.             RootDirectory -> SecondaryType    = 1;
  232.  
  233.                 /* Fill in the bitmap block pointers. */
  234.  
  235.             for(i = 0 ; i < BitmapBlocks ; i++)
  236.             {
  237.                 if(i == 25)
  238.                     break;
  239.                 else
  240.                     RootDirectory -> BitmapPointers[i] = Root + 1 + i + FirstBlock;
  241.             }
  242.  
  243.                 /* If there are more than 25 bitmap blocks, fill in the
  244.                  * pointer to the first bitmap extension block.
  245.                  */
  246.  
  247.             if(BitmapBlocks > 25)
  248.                 RootDirectory -> BitmapExtension = Root + 1 + 25 + FirstBlock;
  249.  
  250.                 /* Calculate the block checksum. */
  251.  
  252.             RootDirectory -> Checksum = - Checksum((ULONG *)RootDirectory);
  253.  
  254.                 /* And write the block. */
  255.  
  256.             if(Error = WriteBlock(DevRequest,RootDirectory,Root + FirstBlock))
  257.                 return(Error);
  258.  
  259.                 /* The blocks to be occupied by the root block, the bitmap
  260.                  * blocks and the extension blocks are to be marked as
  261.                  * being `in use'.
  262.                  */
  263.  
  264.             for(i = Root - Reserved ; i < Root - Reserved + 1 + BitmapBlocks + ExtensionBlocks ; i++)
  265.                 Bitmap[i / 32] &= Bits[i % 32];
  266.  
  267.             BitmapBlock = Buffer;
  268.  
  269.                 /* The root block has been written, now continue with the
  270.                  * bitmap blocks.
  271.                  */
  272.  
  273.             for(i = 0 ; i < BitmapBlocks ; i++)
  274.             {
  275.                     /* Copy the bitmap data. */
  276.  
  277.                 CopyMem(&Bitmap[127 * i],&BitmapBlock -> Bitmap[0],127 * sizeof(ULONG));
  278.  
  279.                     /* Calculate the block checksum. */
  280.  
  281.                 BitmapBlock -> Checksum = 0;
  282.                 BitmapBlock -> Checksum = - Checksum((ULONG *)BitmapBlock);
  283.  
  284.                     /* And write the block. */
  285.  
  286.                 if(Error = WriteBlock(DevRequest,BitmapBlock,Root + 1 + i + FirstBlock))
  287.                     return(Error);
  288.             }
  289.  
  290.             BitmapExtension = Buffer;
  291.  
  292.                 /* If there are any bitmap extension blocks, create them. */
  293.  
  294.             if(ExtensionBlocks)
  295.             {
  296.                     /* Remember the first blocks to deal with. */
  297.  
  298.                 BitmapCount    = Root + 1 + FirstBlock;
  299.                 ExtensionCount    = BitmapCount + BitmapBlocks;
  300.  
  301.                     /* Subtract the first 25 blocks. */
  302.  
  303.                 BitmapBlocks -= 25;
  304.  
  305.                     /* As long as there are any blocks, put them into
  306.                      * the extension blocks.
  307.                      */
  308.  
  309.                 while(BitmapBlocks)
  310.                 {
  311.                     memset(BitmapExtension,0,TD_SECTOR);
  312.  
  313.                         /* Fill in the bitmap pointers. */
  314.  
  315.                     for(i = 0 ; i < (BitmapBlocks < 127 ? BitmapBlocks : 127) ; i++)
  316.                         BitmapExtension -> BitmapPointers[i] = BitmapCount++;
  317.  
  318.                         /* Subtract the bitmap blocks bound to the extension
  319.                          * block.
  320.                          */
  321.  
  322.                     if(BitmapBlocks > 127)
  323.                         BitmapBlocks -= 127;
  324.                     else
  325.                         BitmapBlocks = 0;
  326.  
  327.                         /* If there are any bitmap blocks left, chain
  328.                          * this bitmap extension block to the next one.
  329.                          */
  330.  
  331.                     if(BitmapBlocks)
  332.                         BitmapExtension -> BitmapExtension = ExtensionCount + 1;
  333.  
  334.                         /* And write it. */
  335.  
  336.                     if(Error = WriteBlock(DevRequest,BitmapExtension,ExtensionCount++))
  337.                         return(Error);
  338.                 }
  339.             }
  340.  
  341.                 /* Free the data. */
  342.  
  343.             FreeMem(Bitmap,sizeof(ULONG) * AllocSize);
  344.             FreeMem(Buffer,TD_SECTOR);
  345.  
  346.             return(0);
  347.         }
  348.  
  349.         FreeMem(Buffer,TD_SECTOR);
  350.     }
  351.  
  352.     return(-1);
  353. }
  354.  
  355. struct FileSysStartupMsg *
  356. FindDevice(UBYTE *DevName)
  357. {
  358.     UBYTE            *Pointer,i,Name[40];
  359.     struct DeviceNode    *DevInfo;
  360.  
  361.     Forbid();
  362.  
  363.     DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct RootNode *)DOSBase -> dl_Root) -> rn_Info)) -> di_DevInfo);
  364.  
  365.     while(DevInfo)
  366.     {
  367.         if(DevInfo -> dn_Type == DLT_DEVICE && DevInfo -> dn_Task)
  368.         {
  369.             Pointer = (UBYTE *)BADDR(DevInfo -> dn_Name);
  370.  
  371.             for(i = 0 ; i < Pointer[0] ; i++)
  372.                 Name[i] = Pointer[i + 1];
  373.  
  374.             Name[Pointer[0]    ] = ':';
  375.             Name[Pointer[0] + 1] = 0;
  376.  
  377.             if(!Strcmp(Name,DevName))
  378.             {
  379.                 Permit();
  380.  
  381.                 return(BADDR(DevInfo -> dn_Startup));
  382.             }
  383.         }
  384.  
  385.         DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
  386.     }
  387.  
  388.     Permit();
  389.  
  390.     return(NULL);
  391. }
  392.  
  393. VOID
  394. main(int argc,char **argv)
  395. {
  396.     struct FileSysStartupMsg    *Startup;
  397.     struct DosEnvec            *DosEnvec;
  398.  
  399.     if(Startup = FindDevice(argv[1]))
  400.     {
  401.         struct IOExtTD    *DevRequest;
  402.         struct MsgPort    *DevPort;
  403.  
  404.         if(DevPort = CreatePort(NULL,0))
  405.         {
  406.             if(DevRequest = (struct IOExtTD *)CreateExtIO(DevPort,sizeof(struct IOExtTD)))
  407.             {
  408.                 if(!OpenDevice(&((UBYTE *)BADDR(Startup -> fssm_Device))[1],Startup -> fssm_Unit,DevRequest,Startup -> fssm_Flags))
  409.                 {
  410.                     printf("Opened \"%s\" unit %d.\n",&((UBYTE *)BADDR(Startup -> fssm_Device))[1],Startup -> fssm_Unit);
  411.  
  412.                     DosEnvec = (struct DosEnvec *)BADDR(Startup -> fssm_Environ);
  413.  
  414.                     DevRequest -> iotd_Req . io_Command    = TD_MOTOR;
  415.                     DevRequest -> iotd_Req . io_Length    = 1;
  416.  
  417.                     DoIO(DevRequest);
  418.  
  419.                     EraseDisk("Blank",DevRequest,DosEnvec -> de_LowCyl * DosEnvec -> de_BlocksPerTrack * DosEnvec -> de_Surfaces,(DosEnvec -> de_HighCyl - DosEnvec -> de_LowCyl + 1) * DosEnvec -> de_BlocksPerTrack * DosEnvec -> de_Surfaces,DosEnvec -> de_Reserved,DosEnvec -> de_DosType);
  420.  
  421.                     DevRequest -> iotd_Req . io_Command    = TD_MOTOR;
  422.                     DevRequest -> iotd_Req . io_Length    = 0;
  423.  
  424.                     DoIO(DevRequest);
  425.  
  426.                     CloseDevice(DevRequest);
  427.                 }
  428.                 else
  429.                     printf("Failed to open \"%s\" unit %d.\n",&((UBYTE *)BADDR(Startup -> fssm_Device))[1],Startup -> fssm_Unit);
  430.  
  431.                 DeleteExtIO(DevRequest);
  432.             }
  433.             else
  434.                 puts("Failed to create IORequest.");
  435.  
  436.             DeletePort(DevPort);
  437.         }
  438.         else
  439.             puts("Failed to create MsgPort.");
  440.     }
  441.     else
  442.         printf("Unable to find device \"%s\".\n",argv[1]);
  443. }
  444.