CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Dec 1999
    Location
    Israel
    Posts
    14

    Check if a sector is marked as bad

    How may I check if a certain sector is a bad sector?

    Form Niztan Aviram.
    Any help whould be highly appreciated.

  2. #2
    Join Date
    Oct 1999
    Location
    WA
    Posts
    2,393

    Re: Check if a sector is marked as bad

    It used to be you can use BIOS to read/write/format sectors/tracks. With Win32 API, the right way is to use CreateFile and DeviceIoControl.

    If you can format a sector, then you can write bad formating data into it. If you can read a sector, you only succeed when the sector is good.

    Long time ago, I wrote a program to format a track of floopy disk to contain two more sectors ( 18 instead of 16 ). So my special program can detect it's a special disk, while other program will treat it as normal disk.


  3. #3
    Join Date
    Dec 1999
    Location
    Israel
    Posts
    14

    Re: Check if a sector is marked as bad

    Hye
    First of all thanks for your help about the bad sectors. A I want to ask if it is not to much bother for u' to write me a short example code that tries to read a sector and check for an error. Thanks for your time man.

    Form Niztan Aviram.
    Any help whould be highly appreciated.

  4. #4
    Join Date
    Oct 1999
    Location
    WA
    Posts
    2,393

    Re: Check if a sector is marked as bad

    From Platform SDK


    /*++

    Module Name:

    mfmt.c

    Abstract:

    This program is designed to show how to access a physical floppy
    disk using the Win32 API set.

    This program has two major functions.

    - It can be used to display the geometry of a disk

    mfmt -g a:

    - It can be used to produce a disk image, or to write a disk
    image to a floppy.

    mfmt -c a: bootdisk - produce a disk image of a:

    mfmt -c bootdisk a: - make a: identical to bootdisk image

    This program is very very simple. Minimal error checking is done. It is
    meant to provide an example of how to:

    - Open a physical disk

    - Read a disk's geometry

    - Perform a low level format operation

    - read and write physical sectors

    --*/

    #include <stdlib.h>
    #include <stdio.h>
    #include <windows.h>
    #include <winioctl.h>
    #include <string.h>
    #include <ctype.h>
    #include <memory.h>

    DISK_GEOMETRY SupportedGeometry[20];
    DWORD SupportedGeometryCount;

    BOOL
    GetDiskGeometry(
    HANDLE hDisk,
    PDISK_GEOMETRY lpGeometry
    )

    {
    DWORD ReturnedByteCount;

    return DeviceIoControl(
    hDisk,
    IOCTL_DISK_GET_DRIVE_GEOMETRY,
    NULL,
    0,
    lpGeometry,
    sizeof(*lpGeometry),
    &ReturnedByteCount,
    NULL
    );
    }

    DWORD
    GetSupportedGeometrys(
    HANDLE hDisk
    )
    {
    DWORD ReturnedByteCount;
    BOOL b;
    DWORD NumberSupported;

    b = DeviceIoControl(
    hDisk,
    IOCTL_DISK_GET_MEDIA_TYPES,
    NULL,
    0,
    SupportedGeometry,
    sizeof(SupportedGeometry),
    &ReturnedByteCount,
    NULL
    );
    if ( b ) {
    NumberSupported = ReturnedByteCount / sizeof(DISK_GEOMETRY);
    }
    else {
    NumberSupported = 0;
    }
    SupportedGeometryCount = NumberSupported;

    return NumberSupported;
    }

    VOID
    PrintGeometry(
    LPSTR lpDriveName,
    PDISK_GEOMETRY lpGeometry
    )
    {
    LPSTR MediaType;

    if (lpDriveName) {
    printf("Geometry for Drive %s\n",lpDriveName);
    }

    switch ( lpGeometry->MediaType ) {
    case F5_1Pt2_512: MediaType = "5.25, 1.2MB, 512 bytes/sector";break;
    case F3_1Pt44_512: MediaType = "3.5, 1.44MB, 512 bytes/sector";break;
    case F3_2Pt88_512: MediaType = "3.5, 2.88MB, 512 bytes/sector";break;
    case F3_20Pt8_512: MediaType = "3.5, 20.8MB, 512 bytes/sector";break;
    case F3_720_512: MediaType = "3.5, 720KB, 512 bytes/sector";break;
    case F5_360_512: MediaType = "5.25, 360KB, 512 bytes/sector";break;
    case F5_320_512: MediaType = "5.25, 320KB, 512 bytes/sector";break;
    case F5_320_1024: MediaType = "5.25, 320KB, 1024 bytes/sector";break;
    case F5_180_512: MediaType = "5.25, 180KB, 512 bytes/sector";break;
    case F5_160_512: MediaType = "5.25, 160KB, 512 bytes/sector";break;
    case RemovableMedia: MediaType = "Removable media other than floppy";break;
    case FixedMedia: MediaType = "Fixed hard disk media";break;
    default: MediaType = "Unknown";break;
    }
    printf(" Media Type %s\n",MediaType);
    printf(" Cylinders %d Tracks/Cylinder %d Sectors/Track %d\n",
    lpGeometry->Cylinders.LowPart,
    lpGeometry->TracksPerCylinder,
    lpGeometry->SectorsPerTrack
    );
    }

    BOOL
    LowLevelFormat(
    HANDLE hDisk,
    PDISK_GEOMETRY lpGeometry
    )
    {
    FORMAT_PARAMETERS FormatParameters;
    PBAD_TRACK_NUMBER lpBadTrack;
    UINT i;
    BOOL b;
    DWORD ReturnedByteCount;

    FormatParameters.MediaType = lpGeometry->MediaType;
    FormatParameters.StartHeadNumber = 0;
    FormatParameters.EndHeadNumber = lpGeometry->TracksPerCylinder - 1;
    lpBadTrack = (PBAD_TRACK_NUMBER) LocalAlloc(LMEM_ZEROINIT,lpGeometry->TracksPerCylinder*sizeof(*lpBadTrack));

    for (i = 0; i < lpGeometry->Cylinders.LowPart; i++) {

    FormatParameters.StartCylinderNumber = i;
    FormatParameters.EndCylinderNumber = i;

    b = DeviceIoControl(
    hDisk,
    IOCTL_DISK_FORMAT_TRACKS,
    &FormatParameters,
    sizeof(FormatParameters),
    lpBadTrack,
    lpGeometry->TracksPerCylinder*sizeof(*lpBadTrack),
    &ReturnedByteCount,
    NULL
    );

    if (!b ) {
    LocalFree(lpBadTrack);
    return b;
    }
    }

    LocalFree(lpBadTrack);

    return TRUE;
    }

    BOOL
    LockVolume(
    HANDLE hDisk
    )
    {
    DWORD ReturnedByteCount;

    return DeviceIoControl(
    hDisk,
    FSCTL_LOCK_VOLUME,
    NULL,
    0,
    NULL,
    0,
    &ReturnedByteCount,
    NULL
    );
    }

    BOOL
    UnlockVolume(
    HANDLE hDisk
    )
    {
    DWORD ReturnedByteCount;

    return DeviceIoControl(
    hDisk,
    FSCTL_UNLOCK_VOLUME,
    NULL,
    0,
    NULL,
    0,
    &ReturnedByteCount,
    NULL
    );
    }

    BOOL
    DismountVolume(
    HANDLE hDisk
    )
    {
    DWORD ReturnedByteCount;

    return DeviceIoControl(
    hDisk,
    FSCTL_DISMOUNT_VOLUME,
    NULL,
    0,
    NULL,
    0,
    &ReturnedByteCount,
    NULL
    );
    }

    DWORD
    _cdecl
    main(
    int argc,
    char *argv[],
    char *envp[]
    )
    {
    char Drive[MAX_PATH];
    HANDLE hDrive, hDiskImage;
    DISK_GEOMETRY Geometry;
    UINT i;
    char c, *p;
    LPSTR DriveName;
    BOOL fUsage = TRUE;
    BOOL fShowGeometry = FALSE;
    BOOL fDiskImage = FALSE;
    BOOL SourceIsDrive;
    LPSTR Source, Destination, DiskImage;

    if ( argc > 1 ) {
    fUsage = FALSE;
    while (--argc > 0 ) {
    p = *++argv;
    if (*p == '/' || *p == '-') {
    while (c = *++p)
    switch (toupper( c )) {
    case '?':
    fUsage = TRUE;
    break;

    case 'C':
    fDiskImage = TRUE;
    argc--, argv++;
    Source = *argv;
    argc--, argv++;
    Destination = *argv;
    break;

    case 'G':
    argc--, argv++;
    if ( (DriveName = *argv ) && *DriveName &&
    isalpha(*DriveName) )
    fShowGeometry = TRUE;
    else
    {
    printf( "MFMT: Missing drive letter after -G\n" );
    DriveName = NULL;
    fUsage = TRUE;
    }
    break;

    default:
    printf("MFMT: Invalid switch - /%c\n", c );
    fUsage = TRUE;
    break;
    }
    }
    }
    }

    if ( fUsage ) {
    printf("usage: MFMT switches \n" );
    printf(" [-?] display this message\n" );
    printf(" [-g drive] shows disk geometry\n" );
    printf(" [-c source destination] produce diskimage\n" );
    ExitProcess(1);
    }

    if ( fShowGeometry ) {
    sprintf(Drive,"\\\\.\\%s",DriveName);
    hDrive = CreateFile(
    Drive,
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ|FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    0,
    NULL
    );
    if ( hDrive == INVALID_HANDLE_VALUE ) {
    printf("MFMT: Open %s failed %d\n",DriveName,GetLastError());
    ExitProcess(1);
    }

    if ( LockVolume(hDrive) == FALSE ) {
    printf("MFMT:Locking volume %s failed %d\n", DriveName, GetLastError());
    ExitProcess(1);
    }

    if ( !GetDiskGeometry(hDrive,&Geometry) ) {
    printf("MFMT: GetDiskGeometry %s failed %d\n",DriveName,GetLastError());
    ExitProcess(1);
    }
    PrintGeometry(DriveName,&Geometry);

    if ( !GetSupportedGeometrys(hDrive) ) {
    printf("MFMT: GetSupportedGeometrys %s failed %d\n",DriveName,GetLastError());
    ExitProcess(1);
    }
    printf("\nDrive %s supports the following disk geometries\n",DriveName);

    for(i=0;i<SupportedGeometryCount;i++) {
    printf("\n");
    PrintGeometry(NULL,&SupportedGeometry[i]);
    }

    printf("\n");
    ExitProcess(0);
    }

    if ( fDiskImage ) {
    SourceIsDrive = FALSE;
    if ( Source[strlen(Source)-1] == ':' ) {
    SourceIsDrive = TRUE;
    sprintf(Drive,"\\\\.\\%s",Source);
    DriveName=Source;
    DiskImage = Destination;
    }
    if ( Destination[strlen(Destination)-1] == ':' ) {
    if ( SourceIsDrive ) {
    printf("MFMT: Source and Destination cannot both be drives\n");
    ExitProcess(1);
    }
    SourceIsDrive = FALSE;
    sprintf(Drive,"\\\\.\\%s",Destination);
    DriveName=Destination;
    DiskImage = Source;
    }
    else {
    if ( !SourceIsDrive ) {
    printf("MFMT: Either Source or Destination must be a drive\n");
    ExitProcess(1);
    }
    }

    //
    // Open and Lock the drive
    //

    hDrive = CreateFile(
    Drive,
    GENERIC_READ | GENERIC_WRITE,
    FILE_SHARE_READ|FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    0,
    NULL
    );
    if ( hDrive == INVALID_HANDLE_VALUE ) {
    printf("MFMT: Open %s failed %d\n",DriveName,GetLastError());
    ExitProcess(1);
    }
    if ( LockVolume(hDrive) == FALSE ) {
    printf("MFMT: LockVolume %s failed %d\n",DriveName,GetLastError());
    ExitProcess(1);
    }

    if ( !GetDiskGeometry(hDrive,&Geometry) ) {
    printf("MFMT: GetDiskGeometry %s failed %d\n",DriveName,GetLastError());
    ExitProcess(1);
    }

    if ( !GetSupportedGeometrys(hDrive) ) {
    printf("MFMT: GetSupportedGeometrys %s failed %d\n",DriveName,GetLastError());
    ExitProcess(1);
    }

    //
    // Open the disk image file
    //

    hDiskImage = CreateFile(
    DiskImage,
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    SourceIsDrive ? CREATE_ALWAYS : OPEN_EXISTING,
    0,
    NULL
    );
    if ( hDiskImage == INVALID_HANDLE_VALUE ) {
    printf("MFMT: Open %s failed %d\n",DiskImage,GetLastError());
    ExitProcess(1);
    }

    //
    // Now do the copy
    //
    {
    LPVOID IoBuffer;
    BOOL b;
    DWORD BytesRead, BytesWritten;
    DWORD FileSize;
    DWORD VirtBufSize;
    DWORD NumBufs;

    //
    // If we are copying from floppy to file, just do the copy
    // Otherwise, we might have to format the floppy first
    //

    if ( SourceIsDrive ) {

    //
    // Device reads must be sector aligned. VirtualAlloc will
    // garuntee alignment
    //

    NumBufs = Geometry.Cylinders.LowPart;
    VirtBufSize = Geometry.TracksPerCylinder *
    Geometry.SectorsPerTrack *
    Geometry.BytesPerSector;

    IoBuffer = VirtualAlloc(NULL,VirtBufSize,MEM_COMMIT,PAGE_READWRITE);

    if ( !IoBuffer ) {
    printf("MFMT: Buffer Allocation Failed\n");
    ExitProcess(1);
    }

    for ( ;NumBufs > 0; NumBufs-- )
    {
    b = ReadFile(hDrive,IoBuffer, VirtBufSize, &BytesRead, NULL);
    if (b && BytesRead){
    b = WriteFile(hDiskImage,IoBuffer, BytesRead, &BytesWritten, NULL);
    if ( !b || ( BytesRead != BytesWritten ) ) {
    printf("MFMT: Fatal Write Error %d\n",GetLastError());
    ExitProcess(1);
    }
    }
    else {
    printf("MFMT: Fatal Read Error %d\n",GetLastError());
    ExitProcess(1);
    }
    }
    }
    else {

    //
    // Check to see if the image will fit on the floppy. If it
    // will, then LowLevelFormat the floppy and press on
    //

    FileSize = GetFileSize(hDiskImage,NULL);

    b = FALSE;
    for(i=0;i<SupportedGeometryCount;i++) {
    NumBufs = SupportedGeometry[i].Cylinders.LowPart;
    VirtBufSize = SupportedGeometry[i].TracksPerCylinder *
    SupportedGeometry[i].SectorsPerTrack *
    SupportedGeometry[i].BytesPerSector;
    if ( VirtBufSize*NumBufs >= FileSize ) {

    IoBuffer = VirtualAlloc(NULL,VirtBufSize,MEM_COMMIT,PAGE_READWRITE);

    if ( !IoBuffer ) {
    printf("MFMT: Buffer Allocation Failed\n");
    ExitProcess(1);
    }

    //
    // Format the floppy
    //

    LowLevelFormat(hDrive,&SupportedGeometry[i]);

    for ( ;NumBufs > 0; NumBufs-- )
    {
    b = ReadFile(hDiskImage,IoBuffer, VirtBufSize, &BytesRead, NULL);
    if (b && BytesRead){
    b = WriteFile(hDrive,IoBuffer, BytesRead, &BytesWritten, NULL);
    if ( !b || ( BytesRead != BytesWritten ) ) {
    printf("MFMT: Fatal Write Error %d\n",GetLastError());
    ExitProcess(1);
    }
    }
    else {
    printf("MFMT: Fatal Read Error %d\n",GetLastError());
    ExitProcess(1);
    }
    }
    b = TRUE;
    break;
    }
    }

    if ( !b ) {
    printf("MFMT: FileSize %d is not supported on drive %s\n",FileSize,DriveName);
    ExitProcess(1);
    }
    }
    }

    //
    // Dismounting forces the filesystem to re-evaluate the media id
    // and geometry. This is the same as popping the floppy in and out
    // of the disk drive
    //

    DismountVolume(hDrive);
    UnlockVolume(hDrive);

    ExitProcess(0);
    }
    return (0);
    }





Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured