home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / hpfsut02.zip / source.zip / DiskFunctions.c < prev    next >
Text File  |  1999-11-27  |  35KB  |  1,328 lines

  1. #define INCL_DOSDEVICES
  2. #define INCL_DOSDEVIOCTL
  3. #define INCL_DOSFILEMGR
  4. #define INCL_DOSERRORS
  5. #define INCL_DOSMISC
  6. #include <os2.h>
  7. #include <string.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <ctype.h>
  11.  
  12. #include "Defines.h"
  13. #include "Structures.h"
  14. #include "SupportFunctions.h"
  15. #include "DiskFunctions.h"
  16.  
  17. USHORT setHeadCyl(ULONG secNum, PTRACKLAYOUT tl, USHORT trackPerCyl, USHORT secPerTrack)
  18. {
  19.     ULONG secPerCyl=trackPerCyl*secPerTrack;
  20.     ULONG wSecNum=secNum+1;
  21.  
  22.     tl->usCylinder=wSecNum/secPerCyl;
  23.     tl->usHead=(wSecNum%secPerCyl)/secPerTrack;
  24.  
  25.     return (USHORT)((wSecNum%secPerCyl)%secPerTrack);
  26. }
  27.  
  28. PFUNCRETURN GetRealFreeSpace(PUCHAR driveString, PFREESPACEINFO fsi)
  29. {
  30.     static FUNCRETURN fr;
  31.     UCHAR currFunc[]="GetRealFreeSpace";
  32.     PFUNCRETURN pfr;
  33.     FSALLOCATE fsa;
  34.     ULONG driveNum, freeSectCount, hiddenSectors, bmpListLoc, bmpLoc,
  35.           i, j, k, bmpListSectCount, bmpData, fsArray[32];
  36.     APIRET rc;
  37.     PUCHAR bmpList, bmpSect, tSect;
  38.     PSUPERBLOCK sub;
  39.     PSPAREBLOCK spb;
  40.     HFILE driveHandle;
  41.  
  42.     memset(&fr, 0, sizeof(fr));
  43.  
  44.     pfr=OpenDrive(driveString, &driveHandle, 0L);
  45.     if (!pfr->success)
  46.         {
  47.         fr.success=FALSE;
  48.         strcpy(fr.errorFunc, pfr->errorFunc);
  49.         strcpy(fr.errorHome, pfr->errorHome);
  50.         fr.errorCode=pfr->errorCode;
  51.         return &fr;
  52.         }
  53.  
  54.     pfr=GetDriveSpecs(driveHandle, &fsi->sectorSize, &hiddenSectors);
  55.     if (!pfr->success)
  56.         {
  57.         DosClose(driveHandle);
  58.         fr.success=FALSE;
  59.         strcpy(fr.errorFunc, pfr->errorFunc);
  60.         strcpy(fr.errorHome, pfr->errorHome);
  61.         fr.errorCode=pfr->errorCode;
  62.         return &fr;
  63.         }
  64.  
  65.     spb=(PSPAREBLOCK)malloc(fsi->sectorSize);
  66.     if (spb==NULL)
  67.         {
  68.         DosClose(driveHandle);
  69.         fr.success=FALSE;
  70.         strcpy(fr.errorFunc, "malloc");
  71.         strcpy(fr.errorHome, currFunc);
  72.         fr.errorCode=0;
  73.         return &fr;
  74.         }
  75.  
  76.     pfr=ReadSpareBlock(driveHandle, spb);
  77.     if (!pfr->success)
  78.         {
  79.         free(spb);
  80.         DosClose(driveHandle);
  81.         fr.success=FALSE;
  82.         strcpy(fr.errorFunc, pfr->errorFunc);
  83.         strcpy(fr.errorHome, pfr->errorHome);
  84.         fr.errorCode=pfr->errorCode;
  85.         return &fr;
  86.         }
  87.  
  88.     if (spb->partStatus & 0x10)
  89.         {
  90.         free(spb);
  91.         DosClose(driveHandle);
  92.         fr.success=FALSE;
  93.         strcpy(fr.errorFunc, "badbitmapsexist");
  94.         strcpy(fr.errorHome, currFunc);
  95.         fr.errorCode=0;
  96.         return &fr;
  97.         }
  98.  
  99.     driveNum=(ULONG)(toupper(driveString[0])-64);
  100.  
  101.     memset(&fsa, 0, sizeof(fsa));
  102.  
  103.     rc=DosQueryFSInfo(driveNum, FSIL_ALLOC, &fsa, sizeof(fsa));
  104.     if (rc!=NO_ERROR)
  105.         {
  106.         free(spb);
  107.         fr.success=FALSE;
  108.         strcpy(fr.errorFunc, "DosQueryFSInfo");
  109.         strcpy(fr.errorHome, currFunc);
  110.         fr.errorCode=rc;
  111.         return &fr;
  112.         }
  113.  
  114.     fsi->totalSectors=fsa.cUnit;
  115.     fsi->reportedFreeSectors=fsa.cUnitAvail;
  116.  
  117.     sub=(PSUPERBLOCK)malloc(fsi->sectorSize);
  118.     if (sub==NULL)
  119.         {
  120.         free(spb);
  121.         DosClose(driveHandle);
  122.         fr.success=FALSE;
  123.         strcpy(fr.errorFunc, "malloc");
  124.         strcpy(fr.errorHome, currFunc);
  125.         fr.errorCode=0;
  126.         return &fr;
  127.         }
  128.  
  129.     pfr=ReadSuperBlock(driveHandle, sub);
  130.     if (!pfr->success)
  131.         {
  132.         free(spb);
  133.         free(sub);
  134.         DosClose(driveHandle);
  135.         fr.success=FALSE;
  136.         strcpy(fr.errorFunc, pfr->errorFunc);
  137.         strcpy(fr.errorHome, pfr->errorHome);
  138.         fr.errorCode=pfr->errorCode;
  139.         return &fr;
  140.         }
  141.  
  142.     bmpListLoc=sub->bitmapList;
  143.  
  144.     /*
  145.         Each bitmap covers 16384 sectors, and each bitmap list sector
  146.         covers 128 bitmaps.  This calculates how many list sectors are
  147.         required for the number of sectors on the drive.  While this value
  148.         has a granularity of one, since it's not necessary to read more
  149.         sectors than this determins, the actual space reserved is a
  150.         multiple of four sectors.
  151.     */
  152.  
  153.     bmpListSectCount=fsi->totalSectors/16384+(fsi->totalSectors%16384>0?1:0);
  154.     bmpListSectCount=bmpListSectCount*4;
  155.     bmpListSectCount=bmpListSectCount/fsi->sectorSize+(bmpListSectCount%fsi->sectorSize>0?1:0);
  156.  
  157.     bmpList=(PUCHAR)malloc(bmpListSectCount*fsi->sectorSize);
  158.     if (bmpList==NULL)
  159.         {
  160.         free(spb);
  161.         free(sub);
  162.         DosClose(driveHandle);
  163.         fr.success=FALSE;
  164.         strcpy(fr.errorFunc, "malloc");
  165.         strcpy(fr.errorHome, currFunc);
  166.         fr.errorCode=0;
  167.         return &fr;
  168.         }
  169.  
  170.     bmpSect=(PUCHAR)malloc(fsi->sectorSize*4);
  171.     if (bmpList==NULL)
  172.         {
  173.         free(spb);
  174.         free(sub);
  175.         free(bmpList);
  176.         DosClose(driveHandle);
  177.         fr.success=FALSE;
  178.         strcpy(fr.errorFunc, "malloc");
  179.         strcpy(fr.errorHome, currFunc);
  180.         fr.errorCode=0;
  181.         return &fr;
  182.         }
  183.  
  184.     tSect=(PUCHAR)malloc(fsi->sectorSize);
  185.     if (tSect==NULL)
  186.         {
  187.         free(bmpSect);
  188.         free(spb);
  189.         free(sub);
  190.         free(bmpList);
  191.         DosClose(driveHandle);
  192.         fr.success=FALSE;
  193.         strcpy(fr.errorFunc, "malloc");
  194.         strcpy(fr.errorHome, currFunc);
  195.         fr.errorCode=0;
  196.         return &fr;
  197.         }
  198.  
  199.  
  200.     for (i=0; i<bmpListSectCount; i++)
  201.         {
  202.         pfr=ReadSector(driveHandle, hiddenSectors+bmpListLoc+i, tSect);
  203.         if (!pfr->success)
  204.             {
  205.             free(spb);
  206.             free(bmpList);
  207.             free(bmpSect);
  208.             free(sub);
  209.             DosClose(driveHandle);
  210.             fr.success=FALSE;
  211.             strcpy(fr.errorFunc, pfr->errorFunc);
  212.             strcpy(fr.errorHome, pfr->errorHome);
  213.             fr.errorCode=pfr->errorCode;
  214.             return &fr;
  215.             }
  216.         memcpy(bmpList+(fsi->sectorSize*i), tSect, fsi->sectorSize);
  217.         }
  218.  
  219.     freeSectCount=0;
  220.  
  221.     for (i=0; i<32; i++)
  222.         {
  223.         fsArray[i]=0x00000001 << i;
  224.         }
  225.  
  226.     for (i=0; i<fsi->sectorSize*bmpListSectCount; i+=4)
  227.         {
  228.         memcpy(&bmpLoc, &bmpList[i], 4);
  229.         if (bmpLoc==0x00000000)
  230.             break;
  231.  
  232.         for (j=0; j<4; j++)
  233.             {
  234.             pfr=ReadSector(driveHandle, hiddenSectors+bmpLoc+j, tSect);
  235.             if (!pfr->success)
  236.                 {
  237.                 free(spb);
  238.                 free(bmpList);
  239.                 free(bmpSect);
  240.                 free(sub);
  241.                 free(tSect);
  242.                 DosClose(driveHandle);
  243.                 fr.success=FALSE;
  244.                 strcpy(fr.errorFunc, pfr->errorFunc);
  245.                 strcpy(fr.errorHome, pfr->errorHome);
  246.                 fr.errorCode=pfr->errorCode;
  247.                 return &fr;
  248.                 }
  249.             memcpy(bmpSect+(fsi->sectorSize*j), tSect, fsi->sectorSize);
  250.             }
  251.  
  252.         for (j=0; j<fsi->sectorSize*4; j+=4)
  253.             {
  254.             memcpy(&bmpData, &bmpSect[j], 4);
  255.  
  256.             if (bmpData!=0x00000000)
  257.                 {
  258.                 if (bmpData==0xFFFFFFFF)
  259.                     {
  260.                     freeSectCount+=32;
  261.                     }
  262.                 else
  263.                     {
  264.                     for (k=0; k<32; k++)
  265.                         {
  266.                         if ((bmpData & fsArray[k])>0)
  267.                             freeSectCount++;
  268.                         }
  269.                     }
  270.                 }
  271.             }
  272.         }
  273.  
  274.     fsi->actualFreeSectors=freeSectCount;
  275.  
  276.     DosClose(driveHandle);
  277.  
  278.     free(bmpList);
  279.     free(bmpSect);
  280.     free(sub);
  281.     free(spb);
  282.  
  283.     fr.success=TRUE;
  284.     return &fr;
  285. }
  286.  
  287. PFUNCRETURN GetSystemUsage(PUCHAR driveString, PSYSTEMUSAGE suInfo)
  288. {
  289.     static FUNCRETURN fr;
  290.     UCHAR currFunc[]="GetSystemUsage";
  291.     PFUNCRETURN pfr;
  292.     PSPAREBLOCK spb;
  293.     PSUPERBLOCK sub;
  294.     ULONG sectorSize;
  295.     HFILE driveHandle;
  296.  
  297.     memset(&fr, 0, sizeof(fr));
  298.  
  299.     pfr=OpenDrive(driveString, &driveHandle, 0L);
  300.     if (!pfr->success)
  301.         {
  302.         fr.success=FALSE;
  303.         strcpy(fr.errorFunc, pfr->errorFunc);
  304.         strcpy(fr.errorHome, pfr->errorHome);
  305.         fr.errorCode=pfr->errorCode;
  306.         return &fr;
  307.         }
  308.  
  309.     pfr=GetDriveSpecs(driveHandle, §orSize, NULL);
  310.     if (!pfr->success)
  311.         {
  312.         fr.success=FALSE;
  313.         strcpy(fr.errorFunc, pfr->errorFunc);
  314.         strcpy(fr.errorHome, pfr->errorHome);
  315.         fr.errorCode=pfr->errorCode;
  316.         return &fr;
  317.         }
  318.  
  319.     spb=(PSPAREBLOCK)malloc(sectorSize);
  320.     if (spb==NULL)
  321.         {
  322.         DosClose(driveHandle);
  323.         fr.success=FALSE;
  324.         strcpy(fr.errorFunc, "malloc");
  325.         strcpy(fr.errorHome, currFunc);
  326.         fr.errorCode=0;
  327.         return &fr;
  328.         }
  329.  
  330.     sub=(PSUPERBLOCK)malloc(sectorSize);
  331.     if (spb==NULL)
  332.         {
  333.         free(spb);
  334.         DosClose(driveHandle);
  335.         fr.success=FALSE;
  336.         strcpy(fr.errorFunc, "malloc");
  337.         strcpy(fr.errorHome, currFunc);
  338.         fr.errorCode=0;
  339.         return &fr;
  340.         }
  341.  
  342.     pfr=ReadSpareBlock(driveHandle, spb);
  343.     if (!pfr->success)
  344.         {
  345.         free(spb);
  346.         free(sub);
  347.         DosClose(driveHandle);
  348.         fr.success=FALSE;
  349.         strcpy(fr.errorFunc, pfr->errorFunc);
  350.         strcpy(fr.errorHome, pfr->errorHome);
  351.         fr.errorCode=pfr->errorCode;
  352.         return &fr;
  353.         }
  354.  
  355.     pfr=ReadSuperBlock(driveHandle, sub);
  356.     if (!pfr->success)
  357.         {
  358.         free(spb);
  359.         free(sub);
  360.         DosClose(driveHandle);
  361.         fr.success=FALSE;
  362.         strcpy(fr.errorFunc, pfr->errorFunc);
  363.         strcpy(fr.errorHome, pfr->errorHome);
  364.         fr.errorCode=pfr->errorCode;
  365.         return &fr;
  366.         }
  367.  
  368.     DosClose(driveHandle);
  369.  
  370.     suInfo->sectorSize=sectorSize;
  371.     suInfo->totalSectors=sub->sectorCount;
  372.     suInfo->dirBandSectors=sub->dirBandSectorCount;
  373.     suInfo->dirBandBitmapSectors=4;
  374.     suInfo->frontStructures=20;
  375.     suInfo->codePageSectors=2;
  376.     suInfo->spareDirBlockSectors=spb->spareDirBlockCount*4;
  377.     suInfo->hotfixSectors=spb->hotfixTotal;
  378.     suInfo->hotfixListSectors=4;
  379.     suInfo->bitmapListSectors=sub->sectorCount/16384+(sub->sectorCount%16384>0?1:0);
  380.     suInfo->bitmapListSectors=suInfo->bitmapListSectors*4;
  381.     suInfo->bitmapListSectors=suInfo->bitmapListSectors/sectorSize+
  382.                               (suInfo->bitmapListSectors%sectorSize>0?1:0);
  383.     suInfo->bitmapListSectors=(suInfo->bitmapListSectors/4*4)+
  384.                               (suInfo->bitmapListSectors%4>0?4:0);
  385.     suInfo->bitmapSectors=(sub->sectorCount/16384*4)+(sub->sectorCount%16384>0?4:0);
  386.     suInfo->badSectorListSectors=((((sub->badSectorCount>>14)+2)*4)/sectorSize)+1;
  387.     suInfo->badSectorListSectors=(suInfo->badSectorListSectors/4)+
  388.                                  (suInfo->badSectorListSectors%4>0?4:0);
  389.     suInfo->securityBlockSectors=8;
  390.     suInfo->rootDirBlock=4;
  391.     suInfo->rootFNode=1;
  392.  
  393.     suInfo->totalSystemSectors=
  394.         suInfo->dirBandSectors+
  395.         suInfo->dirBandBitmapSectors+
  396.         suInfo->frontStructures+
  397.         suInfo->codePageSectors+
  398.         suInfo->spareDirBlockSectors+
  399.         suInfo->hotfixSectors+
  400.         suInfo->hotfixListSectors+
  401.         suInfo->bitmapListSectors+
  402.         suInfo->bitmapSectors+
  403.         suInfo->badSectorListSectors+
  404.         suInfo->rootDirBlock+
  405.         suInfo->rootFNode+
  406.         suInfo->securityBlockSectors;
  407.  
  408.     free(sub);
  409.     free(spb);
  410.  
  411.     fr.success=TRUE;
  412.     return &fr;
  413. }
  414.  
  415. PFUNCRETURN GetDirtyStatus(PUCHAR driveString, PBOOL dirtyFlag)
  416. {
  417.     static FUNCRETURN fr;
  418.     UCHAR currFunc[]="GetDirtyStatus";
  419.     ULONG sectorSize;
  420.     PFUNCRETURN pfr;
  421.     PSPAREBLOCK spb;
  422.     HFILE driveHandle;
  423.     BYTEBITFIELD partStatus;
  424.  
  425.     memset(&fr, 0, sizeof(fr));
  426.  
  427.     pfr=OpenDrive(driveString, &driveHandle, 0L);
  428.     if (!pfr->success)
  429.         {
  430.         fr.success=FALSE;
  431.         strcpy(fr.errorFunc, pfr->errorFunc);
  432.         strcpy(fr.errorHome, pfr->errorHome);
  433.         fr.errorCode=pfr->errorCode;
  434.         return &fr;
  435.         }
  436.  
  437.     pfr=GetDriveSpecs(driveHandle, §orSize, NULL);
  438.     if (!pfr->success)
  439.         {
  440.         fr.success=FALSE;
  441.         strcpy(fr.errorFunc, pfr->errorFunc);
  442.         strcpy(fr.errorHome, pfr->errorHome);
  443.         fr.errorCode=pfr->errorCode;
  444.         return &fr;
  445.         }
  446.  
  447.     spb=(PSPAREBLOCK)malloc(sectorSize);
  448.     if (spb==NULL)
  449.         {
  450.         DosClose(driveHandle);
  451.         fr.success=FALSE;
  452.         strcpy(fr.errorFunc, "malloc");
  453.         strcpy(fr.errorHome, currFunc);
  454.         fr.errorCode=0;
  455.         return &fr;
  456.         }
  457.  
  458.     pfr=ReadSpareBlock(driveHandle, spb);
  459.     if (!pfr->success)
  460.         {
  461.         free(spb);
  462.         DosClose(driveHandle);
  463.         fr.success=FALSE;
  464.         strcpy(fr.errorFunc, pfr->errorFunc);
  465.         strcpy(fr.errorHome, pfr->errorHome);
  466.         fr.errorCode=pfr->errorCode;
  467.         return &fr;
  468.         }
  469.  
  470.     DosClose(driveHandle);
  471.  
  472.     memcpy(&partStatus, &spb->partStatus, 1);
  473.  
  474.     *dirtyFlag=(BOOL)partStatus.bit0;
  475.  
  476.     free(spb);
  477.  
  478.     fr.success=TRUE;
  479.     return &fr;
  480. }
  481.  
  482. PFUNCRETURN SetDirtyStatus(PUCHAR driveString, BOOL newDirtyFlag)
  483. {
  484.     static FUNCRETURN fr;
  485.     UCHAR currFunc[]="SetDirtyStatus";
  486.     ULONG sectorSize;
  487.     PFUNCRETURN pfr;
  488.     PSPAREBLOCK spb;
  489.     HFILE driveHandle;
  490.     BYTEBITFIELD partStatus;
  491.  
  492.     memset(&fr, 0, sizeof(fr));
  493.  
  494.     pfr=OpenDrive(driveString, &driveHandle, OPEN_ACCESS_READWRITE);
  495.     if (!pfr->success)
  496.         {
  497.         fr.success=FALSE;
  498.         strcpy(fr.errorFunc, pfr->errorFunc);
  499.         strcpy(fr.errorHome, pfr->errorHome);
  500.         fr.errorCode=pfr->errorCode;
  501.         return &fr;
  502.         }
  503.  
  504.     pfr=LockDrive(driveHandle);
  505.     if (!pfr->success)
  506.         {
  507.         DosClose(driveHandle);
  508.         fr.success=FALSE;
  509.         strcpy(fr.errorFunc, "nolockdrive");
  510.         strcpy(fr.errorHome, pfr->errorHome);
  511.         fr.errorCode=pfr->errorCode;
  512.         return &fr;
  513.         }
  514.  
  515.     pfr=GetDriveSpecs(driveHandle, §orSize, NULL);
  516.     if (!pfr->success)
  517.         {
  518.         fr.success=FALSE;
  519.         strcpy(fr.errorFunc, pfr->errorFunc);
  520.         strcpy(fr.errorHome, pfr->errorHome);
  521.         fr.errorCode=pfr->errorCode;
  522.         return &fr;
  523.         }
  524.  
  525.     spb=(PSPAREBLOCK)malloc(sectorSize);
  526.     if (spb==NULL)
  527.         {
  528.         DosClose(driveHandle);
  529.         fr.success=FALSE;
  530.         strcpy(fr.errorFunc, "malloc");
  531.         strcpy(fr.errorHome, currFunc);
  532.         fr.errorCode=0;
  533.         return &fr;
  534.         }
  535.  
  536.     pfr=ReadSpareBlock(driveHandle, spb);
  537.     if (!pfr->success)
  538.         {
  539.         free(spb);
  540.         DosClose(driveHandle);
  541.         fr.success=FALSE;
  542.         strcpy(fr.errorFunc, pfr->errorFunc);
  543.         strcpy(fr.errorHome, pfr->errorHome);
  544.         fr.errorCode=pfr->errorCode;
  545.         return &fr;
  546.         }
  547.  
  548.     memcpy(&partStatus, &spb->partStatus, 1);
  549.  
  550.     partStatus.bit0=newDirtyFlag;
  551.  
  552.     memcpy(&spb->partStatus, &partStatus, 1);
  553.  
  554.     pfr=WriteSpareBlock(driveHandle, spb);
  555.     if (!pfr->success)
  556.         {
  557.         free(spb);
  558.         DosClose(driveHandle);
  559.         fr.success=FALSE;
  560.         strcpy(fr.errorFunc, pfr->errorFunc);
  561.         strcpy(fr.errorHome, pfr->errorHome);
  562.         fr.errorCode=pfr->errorCode;
  563.         return &fr;
  564.         }
  565.  
  566.     DosClose(driveHandle);
  567.  
  568.     free(spb);
  569.  
  570.     fr.success=TRUE;
  571.     return &fr;
  572. }
  573.  
  574. PFUNCRETURN ToggleDirtyStatus(PUCHAR driveString, PBOOL newStatus)
  575. {
  576.     static FUNCRETURN fr;
  577.     UCHAR currFunc[]="ToggleDirtyStatus";
  578.     ULONG sectorSize;
  579.     PFUNCRETURN pfr;
  580.     PSPAREBLOCK spb;
  581.     HFILE driveHandle;
  582.     BYTEBITFIELD partStatus;
  583.  
  584.     memset(&fr, 0, sizeof(fr));
  585.  
  586.     pfr=OpenDrive(driveString, &driveHandle, OPEN_ACCESS_READWRITE);
  587.     if (!pfr->success)
  588.         {
  589.         fr.success=FALSE;
  590.         strcpy(fr.errorFunc, pfr->errorFunc);
  591.         strcpy(fr.errorHome, pfr->errorHome);
  592.         fr.errorCode=pfr->errorCode;
  593.         return &fr;
  594.         }
  595.  
  596.     pfr=LockDrive(driveHandle);
  597.     if (!pfr->success)
  598.         {
  599.         DosClose(driveHandle);
  600.         fr.success=FALSE;
  601.         strcpy(fr.errorFunc, "nolockdrive");
  602.         strcpy(fr.errorHome, pfr->errorHome);
  603.         fr.errorCode=pfr->errorCode;
  604.         return &fr;
  605.         }
  606.  
  607.     pfr=GetDriveSpecs(driveHandle, §orSize, NULL);
  608.     if (!pfr->success)
  609.         {
  610.         fr.success=FALSE;
  611.         strcpy(fr.errorFunc, pfr->errorFunc);
  612.         strcpy(fr.errorHome, pfr->errorHome);
  613.         fr.errorCode=pfr->errorCode;
  614.         return &fr;
  615.         }
  616.  
  617.     spb=(PSPAREBLOCK)malloc(sectorSize);
  618.     if (spb==NULL)
  619.         {
  620.         DosClose(driveHandle);
  621.         fr.success=FALSE;
  622.         strcpy(fr.errorFunc, "malloc");
  623.         strcpy(fr.errorHome, currFunc);
  624.         fr.errorCode=0;
  625.         return &fr;
  626.         }
  627.  
  628.     pfr=ReadSpareBlock(driveHandle, spb);
  629.     if (!pfr->success)
  630.         {
  631.         free(spb);
  632.         DosClose(driveHandle);
  633.         fr.success=FALSE;
  634.         strcpy(fr.errorFunc, pfr->errorFunc);
  635.         strcpy(fr.errorHome, pfr->errorHome);
  636.         fr.errorCode=pfr->errorCode;
  637.         return &fr;
  638.         }
  639.  
  640.     memcpy(&partStatus, &spb->partStatus, 1);
  641.  
  642.     if (partStatus.bit0)
  643.         {
  644.         *newStatus=FALSE;
  645.         partStatus.bit0=0;
  646.         }
  647.     else
  648.         {
  649.         *newStatus=TRUE;
  650.         partStatus.bit0=1;
  651.         }
  652.  
  653.     memcpy(&spb->partStatus, &partStatus, 1);
  654.  
  655.     pfr=WriteSpareBlock(driveHandle, spb);
  656.     if (!pfr->success)
  657.         {
  658.         free(spb);
  659.         DosClose(driveHandle);
  660.         fr.success=FALSE;
  661.         strcpy(fr.errorFunc, pfr->errorFunc);
  662.         strcpy(fr.errorHome, pfr->errorHome);
  663.         fr.errorCode=pfr->errorCode;
  664.         return &fr;
  665.         }
  666.  
  667.     DosClose(driveHandle);
  668.  
  669.     free(spb);
  670.  
  671.     fr.success=TRUE;
  672.     return &fr;
  673. }
  674.  
  675. PFUNCRETURN GetBadSectorCount(PUCHAR driveString, PULONG bsCount)
  676. {
  677.     static FUNCRETURN fr;
  678.     UCHAR currFunc[]="GetBadSectorCount";
  679.     PFUNCRETURN pfr;
  680.     PSUPERBLOCK sub;
  681.     ULONG sectorSize;
  682.     HFILE driveHandle;
  683.     BYTEBITFIELD partStatus;
  684.  
  685.     memset(&fr, 0, sizeof(fr));
  686.  
  687.     pfr=OpenDrive(driveString, &driveHandle, 0L);
  688.     if (!pfr->success)
  689.         {
  690.         fr.success=FALSE;
  691.         strcpy(fr.errorFunc, pfr->errorFunc);
  692.         strcpy(fr.errorHome, pfr->errorHome);
  693.         fr.errorCode=pfr->errorCode;
  694.         return &fr;
  695.         }
  696.  
  697.     pfr=GetDriveSpecs(driveHandle, §orSize, NULL);
  698.     if (!pfr->success)
  699.         {
  700.         fr.success=FALSE;
  701.         strcpy(fr.errorFunc, pfr->errorFunc);
  702.         strcpy(fr.errorHome, pfr->errorHome);
  703.         fr.errorCode=pfr->errorCode;
  704.         return &fr;
  705.         }
  706.  
  707.     sub=(PSUPERBLOCK)malloc(sectorSize);
  708.     if (sub==NULL)
  709.         {
  710.         fr.success=FALSE;
  711.         strcpy(fr.errorFunc, "malloc");
  712.         strcpy(fr.errorHome, currFunc);
  713.         fr.errorCode=0;
  714.         return &fr;
  715.         }
  716.  
  717.     pfr=ReadSuperBlock(driveHandle, sub);
  718.     if (!pfr->success)
  719.         {
  720.         free(sub);
  721.         fr.success=FALSE;
  722.         strcpy(fr.errorFunc, pfr->errorFunc);
  723.         strcpy(fr.errorHome, pfr->errorHome);
  724.         fr.errorCode=pfr->errorCode;
  725.         return &fr;
  726.         }
  727.  
  728.     *bsCount=sub->badSectorCount;
  729.  
  730.     free(sub);
  731.  
  732.     fr.success=TRUE;
  733.     return &fr;
  734. }
  735.  
  736. PFUNCRETURN DumpSectorData(PUCHAR driveString, ULONG begin, ULONG end, FILE *outFile, PULONG secSize)
  737. {
  738.     static FUNCRETURN fr;
  739.     UCHAR currFunc[]="DumpSectorData";
  740.     PFUNCRETURN pfr;
  741.     ULONG sectorSize, hiddenSectors, secCount, i;
  742.     PUCHAR sdata;
  743.     PSUPERBLOCK sub;
  744.     HFILE driveHandle;
  745.  
  746.     memset(&fr, 0, sizeof(fr));
  747.  
  748.     pfr=OpenDrive(driveString, &driveHandle, 0L);
  749.     if (!pfr->success)
  750.         {
  751.         fr.success=FALSE;
  752.         strcpy(fr.errorFunc, pfr->errorFunc);
  753.         strcpy(fr.errorHome, pfr->errorHome);
  754.         fr.errorCode=pfr->errorCode;
  755.         return &fr;
  756.         }
  757.  
  758.     pfr=GetDriveSpecs(driveHandle, §orSize, &hiddenSectors);
  759.     if (!pfr->success)
  760.         {
  761.         DosClose(driveHandle);
  762.         fr.success=FALSE;
  763.         strcpy(fr.errorFunc, pfr->errorFunc);
  764.         strcpy(fr.errorHome, pfr->errorHome);
  765.         fr.errorCode=pfr->errorCode;
  766.         return &fr;
  767.         }
  768.  
  769.     if (secSize!=NULL)
  770.         *secSize=sectorSize;
  771.  
  772.     sub=(PSUPERBLOCK)malloc(sectorSize);
  773.     if (sub==NULL)
  774.         {
  775.         DosClose(driveHandle);
  776.         fr.success=FALSE;
  777.         strcpy(fr.errorFunc, "malloc");
  778.         strcpy(fr.errorHome, currFunc);
  779.         fr.errorCode=0;
  780.         return &fr;
  781.         }
  782.  
  783.     pfr=ReadSuperBlock(driveHandle, sub);
  784.     if (!pfr->success)
  785.         {
  786.         free(sub);
  787.         DosClose(driveHandle);
  788.         fr.success=FALSE;
  789.         strcpy(fr.errorFunc, pfr->errorFunc);
  790.         strcpy(fr.errorHome, pfr->errorHome);
  791.         fr.errorCode=pfr->errorCode;
  792.         return &fr;
  793.         }
  794.  
  795.     if (end>sub->sectorCount)
  796.         {
  797.         free(sub);
  798.         DosClose(driveHandle);
  799.         fr.success=FALSE;
  800.         strcpy(fr.errorFunc, "endpastend");
  801.         strcpy(fr.errorHome, currFunc);
  802.         fr.errorCode=0;
  803.         return &fr;
  804.         }
  805.  
  806.     secCount=end-begin+1;
  807.  
  808.     sdata=(PUCHAR)malloc(sectorSize);
  809.     if (sdata==NULL)
  810.         {
  811.         free(sub);
  812.         DosClose(driveHandle);
  813.         fr.success=FALSE;
  814.         strcpy(fr.errorFunc, "malloc");
  815.         strcpy(fr.errorHome, currFunc);
  816.         fr.errorCode=0;
  817.         return &fr;
  818.         }
  819.  
  820.     printf("\nBytes dumped:                ");
  821.     fflush(stdout);
  822.  
  823.     for (i=0; i<secCount; i++)
  824.         {
  825.         pfr=ReadSector(driveHandle, hiddenSectors+begin+i, sdata);
  826.         if (!pfr->success)
  827.             {
  828.             free(sub);
  829.             free(sdata);
  830.             printf("\n");
  831.             DosClose(driveHandle);
  832.             fr.success=FALSE;
  833.             strcpy(fr.errorFunc, pfr->errorFunc);
  834.             strcpy(fr.errorHome, pfr->errorHome);
  835.             fr.errorCode=pfr->errorCode;
  836.             return &fr;
  837.             }
  838.         if (fwrite(sdata, sectorSize, 1, outFile)<1)
  839.             {
  840.             free(sub);
  841.             free(sdata);
  842.             printf("\n");
  843.             DosClose(driveHandle);
  844.             fr.success=FALSE;
  845.             strcpy(fr.errorFunc, "fwrite");
  846.             strcpy(fr.errorHome, currFunc);
  847.             fr.errorCode=0;
  848.             return &fr;
  849.             }
  850.         printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%15s", fCodel((double)(i+1)*(double)sectorSize));
  851.         fflush(stdout);
  852.         }
  853.     printf("\n");
  854.  
  855.     DosClose(driveHandle);
  856.  
  857.     free(sdata);
  858.     free(sub);
  859.  
  860.     fr.success=TRUE;
  861.     return &fr;
  862. }
  863.  
  864. PFUNCRETURN OpenDrive(PUCHAR driveString, PHFILE driveHandle, ULONG openFlags)
  865. {
  866.     static FUNCRETURN fr;
  867.     UCHAR currFunc[]="OpenDrive";
  868.     ULONG openAction, openMode;
  869.     APIRET rc;
  870.  
  871.     openMode=0;
  872.     openMode=openMode | OPEN_FLAGS_DASD | OPEN_ACCESS_READONLY | OPEN_SHARE_DENYNONE
  873.                       | OPEN_FLAGS_NO_CACHE;
  874.     openMode=openMode | openFlags;
  875.     rc=DosOpen(driveString, driveHandle, &openAction, 0L, 0L, FILE_OPEN, openMode, 0L);
  876.     if (rc!=NO_ERROR)
  877.         {
  878.         fr.success=FALSE;
  879.         strcpy(fr.errorFunc, "DosOpen");
  880.         strcpy(fr.errorHome, currFunc);
  881.         fr.errorCode=rc;
  882.         return &fr;
  883.         }
  884.  
  885.     fr.success=TRUE;
  886.     return &fr;
  887. }
  888.  
  889. PFUNCRETURN LockDrive(HFILE driveHandle)
  890. {
  891.     static FUNCRETURN fr;
  892.     UCHAR currFunc[]="LockDrive";
  893.     APIRET rc;
  894.  
  895.     memset(&fr, 0, sizeof(fr));
  896.  
  897.     rc=DosDevIOCtl(driveHandle, IOCTL_DISK, DSK_LOCKDRIVE, 0, 0, 0, 0, 0, 0);
  898.     if (rc!=NO_ERROR)
  899.         {
  900.         fr.success=FALSE;
  901.         strcpy(fr.errorFunc, "DosDevIOCtl");
  902.         strcpy(fr.errorHome, currFunc);
  903.         fr.errorCode=rc;
  904.         return &fr;
  905.         }
  906.  
  907.     fr.success=TRUE;
  908.     return &fr;
  909. }
  910.  
  911. PFUNCRETURN DriveIsHPFS(PUCHAR driveString, PBOOL isHPFS, PUCHAR fsInUse)
  912. {
  913.     static FUNCRETURN fr;
  914.     UCHAR currFunc[]="DriveIsHPFS";
  915.     PFSQBUFFER2 fsBuffer;
  916.     ULONG bufLen;
  917.     APIRET rc;
  918.     PUCHAR fsStuff;
  919.  
  920.     memset(&fr, 0, sizeof(fr));
  921.  
  922.     fsBuffer=(PFSQBUFFER2)malloc(2048);
  923.     if (fsBuffer==NULL)
  924.         {
  925.         fr.success=FALSE;
  926.         strcpy(fr.errorFunc, "malloc");
  927.         strcpy(fr.errorHome, currFunc);
  928.         fr.errorCode=0;
  929.         return &fr;
  930.         }
  931.     memset(fsBuffer, 0, 2048);
  932.     bufLen=2048;
  933.     DosError(FERR_DISABLEHARDERR);
  934.     rc=DosQueryFSAttach(driveString, 0, FSAIL_QUERYNAME, fsBuffer, &bufLen);
  935.     DosError(FERR_ENABLEHARDERR);
  936.     if (rc!=NO_ERROR)
  937.         {
  938.         free(fsBuffer);
  939.         fr.success=FALSE;
  940.         strcpy(fr.errorFunc, "DosQueryFSAttach");
  941.         strcpy(fr.errorHome, currFunc);
  942.         fr.errorCode=rc;
  943.         return &fr;
  944.         }
  945.     fsStuff=(PUCHAR)(fsBuffer->szName+fsBuffer->cbName+1);
  946.  
  947.     strcpy(fsInUse, fsStuff);
  948.  
  949.     if (!strcmp(fsInUse, "HPFS"))
  950.         *isHPFS=TRUE;
  951.     else
  952.         *isHPFS=FALSE;
  953.  
  954.     free(fsBuffer);
  955.  
  956.     fr.success=TRUE;
  957.     return &fr;
  958. }
  959.  
  960. PFUNCRETURN GetBPB(HFILE driveHandle, PBIOSPARAMETERBLOCK bpb)
  961. {
  962.     static FUNCRETURN fr;
  963.     UCHAR currFunc[]="GetBPB";
  964.     PUCHAR bpParm, bpData;
  965.     ULONG bpParmLen, bpDataLen;
  966.     APIRET rc;
  967.  
  968.     memset(&fr, 0, sizeof(fr));
  969.  
  970.     bpParm=(PUCHAR)malloc(2);
  971.     if (bpParm==NULL)
  972.         {
  973.         fr.success=FALSE;
  974.         strcpy(fr.errorFunc, "malloc");
  975.         strcpy(fr.errorHome, currFunc);
  976.         fr.errorCode=0;
  977.         return &fr;
  978.         }
  979.  
  980.     bpData=(PUCHAR)malloc(40);
  981.     if (bpData==NULL)
  982.         {
  983.         free(bpParm);
  984.         fr.success=FALSE;
  985.         strcpy(fr.errorFunc, "malloc");
  986.         strcpy(fr.errorHome, currFunc);
  987.         fr.errorCode=0;
  988.         return &fr;
  989.         }
  990.  
  991.     memset(bpParm, 0, 2);
  992.     memset(bpData, 0, 40);
  993.     bpParmLen=2;
  994.     bpDataLen=40;
  995.     rc=DosDevIOCtl(driveHandle, IOCTL_DISK, DSK_GETDEVICEPARAMS,
  996.                    bpParm, bpParmLen, &bpParmLen,
  997.                    bpData, bpDataLen, &bpDataLen);
  998.  
  999.     if (rc!=NO_ERROR)
  1000.         {
  1001.         free(bpParm);
  1002.         free(bpData);
  1003.         fr.success=FALSE;
  1004.         strcpy(fr.errorFunc, "DosDevIOCtl");
  1005.         strcpy(fr.errorHome, currFunc);
  1006.         fr.errorCode=rc;
  1007.         return &fr;
  1008.         }
  1009.  
  1010.     memset(bpb, 0, sizeof(BIOSPARAMETERBLOCK));
  1011.     memcpy(bpb, bpData, sizeof(BIOSPARAMETERBLOCK));
  1012.  
  1013.     free(bpParm);
  1014.     free(bpData);
  1015.  
  1016.     fr.success=TRUE;
  1017.     return &fr;
  1018. }
  1019.  
  1020. PFUNCRETURN GetDriveSpecs(HFILE driveHandle, PULONG sectorSize, PULONG hiddenSectors)
  1021. {
  1022.     static FUNCRETURN fr;
  1023.     UCHAR currFunc[]="GetDriveSpecs";
  1024.     PFUNCRETURN pfr;
  1025.     ULONG i;
  1026.     PBIOSPARAMETERBLOCK bpb;
  1027.  
  1028.     memset(&fr, 0, sizeof(fr));
  1029.  
  1030.     bpb=(PBIOSPARAMETERBLOCK)malloc(sizeof(BIOSPARAMETERBLOCK));
  1031.     if (bpb==NULL)
  1032.         {
  1033.         fr.success=FALSE;
  1034.         strcpy(fr.errorFunc, "malloc");
  1035.         strcpy(fr.errorHome, currFunc);
  1036.         fr.errorCode=0;
  1037.         return &fr;
  1038.         }
  1039.  
  1040.     pfr=GetBPB(driveHandle, bpb);
  1041.     if (!pfr->success)
  1042.         {
  1043.         free(bpb);
  1044.         fr.success=FALSE;
  1045.         strcpy(fr.errorFunc, pfr->errorFunc);
  1046.         strcpy(fr.errorHome, pfr->errorHome);
  1047.         fr.errorCode=0;
  1048.         return &fr;
  1049.         }
  1050.  
  1051.     if (sectorSize!=NULL)
  1052.         *sectorSize=bpb->usBytesPerSector;
  1053.  
  1054.     if (hiddenSectors!=NULL)
  1055.         *hiddenSectors=bpb->cHiddenSectors;
  1056.  
  1057.     fr.success=TRUE;
  1058.     return &fr;
  1059. }
  1060.  
  1061. PFUNCRETURN ReadSuperBlock(HFILE driveHandle, PSUPERBLOCK sub)
  1062. {
  1063.     static FUNCRETURN fr;
  1064.     UCHAR currFunc[]="ReadSuperBlock";
  1065.     PFUNCRETURN pfr;
  1066.     PBIOSPARAMETERBLOCK bpb;
  1067.  
  1068.     bpb=(PBIOSPARAMETERBLOCK)malloc(sizeof(BIOSPARAMETERBLOCK));
  1069.     if (bpb==NULL)
  1070.         {
  1071.         fr.success=FALSE;
  1072.         strcpy(fr.errorFunc, "malloc");
  1073.         strcpy(fr.errorHome, currFunc);
  1074.         fr.errorCode=0;
  1075.         return &fr;
  1076.         }
  1077.  
  1078.     pfr=GetBPB(driveHandle, bpb);
  1079.     if (!pfr->success)
  1080.         {
  1081.         fr.success=FALSE;
  1082.         strcpy(fr.errorFunc, pfr->errorFunc);
  1083.         strcpy(fr.errorHome, pfr->errorFunc);
  1084.         fr.errorCode=0;
  1085.         return &fr;
  1086.         }
  1087.  
  1088.     pfr=ReadSector(driveHandle, bpb->cHiddenSectors+SUPERLOC, (PUCHAR)sub);
  1089.     if (!pfr->success)
  1090.         {
  1091.         fr.success=FALSE;
  1092.         strcpy(fr.errorFunc, pfr->errorFunc);
  1093.         strcpy(fr.errorHome, pfr->errorFunc);
  1094.         fr.errorCode=0;
  1095.         return &fr;
  1096.         }
  1097.  
  1098.     fr.success=TRUE;
  1099.     return &fr;
  1100. }
  1101.  
  1102. PFUNCRETURN ReadSpareBlock(HFILE driveHandle, PSPAREBLOCK spb)
  1103. {
  1104.     static FUNCRETURN fr;
  1105.     UCHAR currFunc[]="ReadSpareBlock";
  1106.     PFUNCRETURN pfr;
  1107.     PBIOSPARAMETERBLOCK bpb;
  1108.  
  1109.     bpb=(PBIOSPARAMETERBLOCK)malloc(sizeof(BIOSPARAMETERBLOCK));
  1110.     if (bpb==NULL)
  1111.         {
  1112.         fr.success=FALSE;
  1113.         strcpy(fr.errorFunc, "malloc");
  1114.         strcpy(fr.errorHome, currFunc);
  1115.         fr.errorCode=0;
  1116.         return &fr;
  1117.         }
  1118.  
  1119.     pfr=GetBPB(driveHandle, bpb);
  1120.     if (!pfr->success)
  1121.         {
  1122.         fr.success=FALSE;
  1123.         strcpy(fr.errorFunc, pfr->errorFunc);
  1124.         strcpy(fr.errorHome, pfr->errorFunc);
  1125.         fr.errorCode=0;
  1126.         return &fr;
  1127.         }
  1128.  
  1129.     pfr=ReadSector(driveHandle, bpb->cHiddenSectors+SPARELOC, (PUCHAR)spb);
  1130.     if (!pfr->success)
  1131.         {
  1132.         fr.success=FALSE;
  1133.         strcpy(fr.errorFunc, pfr->errorFunc);
  1134.         strcpy(fr.errorHome, pfr->errorFunc);
  1135.         fr.errorCode=0;
  1136.         return &fr;
  1137.         }
  1138.  
  1139.     fr.success=TRUE;
  1140.     return &fr;
  1141. }
  1142.  
  1143. PFUNCRETURN WriteSpareBlock(HFILE driveHandle, PSPAREBLOCK spb)
  1144. {
  1145.     static FUNCRETURN fr;
  1146.     PFUNCRETURN pfr;
  1147.     ULONG hiddenSectors;
  1148.  
  1149.     pfr=GetDriveSpecs(driveHandle, NULL, &hiddenSectors);
  1150.     if (!pfr->success)
  1151.         {
  1152.         fr.success=FALSE;
  1153.         strcpy(fr.errorFunc, pfr->errorFunc);
  1154.         strcpy(fr.errorHome, pfr->errorHome);
  1155.         fr.errorCode=pfr->errorCode;
  1156.         return &fr;
  1157.         }
  1158.  
  1159.     pfr=WriteSector(driveHandle, hiddenSectors+SPARELOC, (PUCHAR)spb);
  1160.     if (!pfr->success)
  1161.         {
  1162.         fr.success=FALSE;
  1163.         strcpy(fr.errorFunc, pfr->errorFunc);
  1164.         strcpy(fr.errorHome, pfr->errorHome);
  1165.         fr.errorCode=pfr->errorCode;
  1166.         return &fr;
  1167.         }
  1168.  
  1169.     fr.success=TRUE;
  1170.     return &fr;
  1171. }
  1172.  
  1173. PFUNCRETURN ReadSector(HFILE driveHandle, ULONG lsNum, PUCHAR secData)
  1174. {
  1175.     static FUNCRETURN fr;
  1176.     UCHAR currFunc[]="ReadSectorData";
  1177.     PFUNCRETURN pfr;
  1178.     PTRACKLAYOUT tl;
  1179.     PBIOSPARAMETERBLOCK bpb;
  1180.     ULONG bpParmLen, bpDataLen, i;
  1181.     APIRET rc;
  1182.  
  1183.     memset(&fr, 0, sizeof(fr));
  1184.  
  1185.     bpb=(PBIOSPARAMETERBLOCK)malloc(sizeof(BIOSPARAMETERBLOCK));
  1186.     if (bpb==NULL)
  1187.         {
  1188.         fr.success=FALSE;
  1189.         strcpy(fr.errorFunc, "malloc");
  1190.         strcpy(fr.errorHome, currFunc);
  1191.         fr.errorCode=0;
  1192.         return &fr;
  1193.         }
  1194.  
  1195.     pfr=GetBPB(driveHandle, bpb);
  1196.     if (!pfr->success)
  1197.         {
  1198.         free(bpb);
  1199.         fr.success=FALSE;
  1200.         strcpy(fr.errorFunc, pfr->errorFunc);
  1201.         strcpy(fr.errorHome, pfr->errorHome);
  1202.         fr.errorCode=pfr->errorCode;
  1203.         return &fr;
  1204.         }
  1205.  
  1206.     bpParmLen=sizeof(TRACKLAYOUT)+sizeof(ULONG);
  1207.     bpDataLen=bpb->usBytesPerSector;
  1208.  
  1209.     tl=(PTRACKLAYOUT)malloc(bpParmLen);
  1210.     if (tl==NULL)
  1211.         {
  1212.         free(bpb);
  1213.         fr.success=FALSE;
  1214.         strcpy(fr.errorFunc, "malloc");
  1215.         strcpy(fr.errorHome, currFunc);
  1216.         fr.errorCode=0;
  1217.         return &fr;
  1218.         }
  1219.  
  1220.     tl->bCommand=0;
  1221.     tl->usHead=0;
  1222.     tl->usCylinder=0;
  1223.     tl->usFirstSector=0;
  1224.     tl->cSectors=1;
  1225.  
  1226.     tl->TrackTable[0].usSectorNumber=setHeadCyl(lsNum, tl, bpb->cHeads,
  1227.                                                 bpb->usSectorsPerTrack);
  1228.     tl->TrackTable[0].usSectorSize=bpb->usBytesPerSector;
  1229.  
  1230.     rc=DosDevIOCtl(driveHandle, IOCTL_DISK, DSK_READTRACK, tl,
  1231.                    bpParmLen, &bpParmLen, secData, bpDataLen, &bpDataLen);
  1232.  
  1233.     if (rc!=NO_ERROR)
  1234.         {
  1235.         free(bpb);
  1236.         free(tl);
  1237.         fr.success=FALSE;
  1238.         strcpy(fr.errorFunc, "DosDevIOCtl");
  1239.         strcpy(fr.errorHome, currFunc);
  1240.         fr.errorCode=rc;
  1241.         return &fr;
  1242.         }
  1243.  
  1244.     free(tl);
  1245.     free(bpb);
  1246.  
  1247.     fr.success=TRUE;
  1248.     return &fr;
  1249. }
  1250.  
  1251. PFUNCRETURN WriteSector(HFILE driveHandle, ULONG lsNum, PUCHAR secData)
  1252. {
  1253.     static FUNCRETURN fr;
  1254.     UCHAR currFunc[]="WriteSectorData";
  1255.     PFUNCRETURN pfr;
  1256.     PTRACKLAYOUT tl;
  1257.     PBIOSPARAMETERBLOCK bpb;
  1258.     ULONG bpParmLen, bpDataLen, i;
  1259.     APIRET rc;
  1260.  
  1261.     memset(&fr, 0, sizeof(fr));
  1262.  
  1263.     bpb=(PBIOSPARAMETERBLOCK)malloc(sizeof(BIOSPARAMETERBLOCK));
  1264.     if (bpb==NULL)
  1265.         {
  1266.         fr.success=FALSE;
  1267.         strcpy(fr.errorFunc, "malloc");
  1268.         strcpy(fr.errorHome, currFunc);
  1269.         fr.errorCode=0;
  1270.         return &fr;
  1271.         }
  1272.  
  1273.     pfr=GetBPB(driveHandle, bpb);
  1274.     if (!pfr->success)
  1275.         {
  1276.         free(bpb);
  1277.         fr.success=FALSE;
  1278.         strcpy(fr.errorFunc, pfr->errorFunc);
  1279.         strcpy(fr.errorHome, pfr->errorHome);
  1280.         fr.errorCode=pfr->errorCode;
  1281.         return &fr;
  1282.         }
  1283.  
  1284.     bpParmLen=sizeof(TRACKLAYOUT)+sizeof(ULONG);
  1285.     bpDataLen=bpb->usBytesPerSector;
  1286.  
  1287.     tl=(PTRACKLAYOUT)malloc(bpParmLen);
  1288.     if (tl==NULL)
  1289.         {
  1290.         free(bpb);
  1291.         fr.success=FALSE;
  1292.         strcpy(fr.errorFunc, "malloc");
  1293.         strcpy(fr.errorHome, currFunc);
  1294.         fr.errorCode=0;
  1295.         return &fr;
  1296.         }
  1297.  
  1298.     tl->bCommand=0;
  1299.     tl->usHead=0;
  1300.     tl->usCylinder=0;
  1301.     tl->usFirstSector=0;
  1302.     tl->cSectors=1;
  1303.  
  1304.     tl->TrackTable[0].usSectorNumber=setHeadCyl(lsNum, tl, bpb->cHeads,
  1305.                                                 bpb->usSectorsPerTrack);
  1306.     tl->TrackTable[0].usSectorSize=bpb->usBytesPerSector;
  1307.  
  1308.     rc=DosDevIOCtl(driveHandle, IOCTL_DISK, DSK_WRITETRACK, tl,
  1309.                    bpParmLen, &bpParmLen, secData, bpDataLen, &bpDataLen);
  1310.  
  1311.     if (rc!=NO_ERROR)
  1312.         {
  1313.         free(bpb);
  1314.         free(tl);
  1315.         fr.success=FALSE;
  1316.         strcpy(fr.errorFunc, "DosDevIOCtl");
  1317.         strcpy(fr.errorHome, currFunc);
  1318.         fr.errorCode=rc;
  1319.         return &fr;
  1320.         }
  1321.  
  1322.     free(tl);
  1323.     free(bpb);
  1324.  
  1325.     fr.success=TRUE;
  1326.     return &fr;
  1327. }
  1328.