/* * This is distributed as part of ODS2, originally written by * Paul Nankervis, email address: Paulnank@au1.ibm.com * * ODS2 is distributed freely for all members of the * VMS community to use. However all derived works * must maintain comments in their source to acknowledge * the contributions of the original author and * subsequent contributors. This is free software; no * warranty is offered, and while we believe it to be useful, * you use it at your own risk. */ #include #include #include #define VWIN32_DIOC_DOS_IOCTL 1 #pragma pack( 1 ) typedef struct _DEVIOCTL_REGISTERS { DWORD reg_EBX; DWORD reg_EDX; DWORD reg_ECX; DWORD reg_EAX; DWORD reg_EDI; DWORD reg_ESI; DWORD reg_Flags; } DEVIOCTL_REGISTERS, *PDEVIOCTL_REGISTERS; typedef struct _MID { WORD midInfoLevel; DWORD midSerialNum; BYTE midVolLabel[11]; BYTE midFileSysType[8]; } MID, *PMID; typedef struct _DPARAMS { BYTE special_functions; BYTE device_type; WORD device_attributes; WORD no_of_cylinders; BYTE media_type; struct { WORD bytes_per_sector; BYTE sectors_per_cluster; WORD reserved_sectors; BYTE no_of_FATs; WORD root_entries; WORD small_sectors; /* FAT12/16 iff < 65536, else =0 and number */ /* of sectors is in large_sectors */ BYTE media_descriptor; WORD sectors_per_FAT; WORD sectors_per_track; WORD no_of_heads; DWORD hidden_sectors; DWORD large_sectors; /* FAT32 */ BYTE reserved[6]; } BPB; } DPARAMS, *PDPARAMS; #pragma pack( ) int main( ) { UINT nDrive; MID mid; DPARAMS dparams; char RootPathName[3] = "X:"; // root path DWORD SectorsPerCluster; // sectors per cluster DWORD BytesPerSector; // bytes per sector DWORD NumberOfFreeClusters; // free clusters DWORD TotalNumberOfClusters; // total clusters for ( nDrive = 1; nDrive <= 26; nDrive++ ) { RootPathName[0] = nDrive - 1 + 'A'; memset( &mid, 0, sizeof( mid ) ); if ( GetMediaID( &mid, nDrive ) && mid.midFileSysType[0] != '\0' ) { printf( "Drive %s %8.8s %11.11s\n", RootPathName, mid.midFileSysType, mid.midVolLabel ); memset( &dparams, 0, sizeof( dparams ) ); if ( GetDeviceParams( &dparams, nDrive ) ) { printf( " Device Type: 0x%1.1x\n", dparams.device_type ); printf( " No. of Cylinders %d\n", dparams.no_of_cylinders ); printf( " BPB: Bytes Per Sector: %5d", dparams.BPB.bytes_per_sector ); printf( " Sectors Per Track %5d\n", dparams.BPB.sectors_per_track ); printf( " Sectors Per Cluster %5d", dparams.BPB.sectors_per_cluster ); printf( " No. of Heads %5d\n", dparams.BPB.no_of_heads ); printf( " Sectors Per Track %5d", dparams.BPB.sectors_per_track ); printf( " Large Sectors: %8lu\n", dparams.BPB.large_sectors ); if ( GetDiskFreeSpace( RootPathName, // root path &SectorsPerCluster, // sects per clustr &BytesPerSector, // bytes per sector &NumberOfFreeClusters,// free clusters &TotalNumberOfClusters// total clusters ) ) { printf( " Sectors Per Cluster: %8lu", SectorsPerCluster ); printf( " BytesPerSector: %8lu\n", BytesPerSector ); printf( " NumberOfFreeClusters: %8lu", NumberOfFreeClusters ); printf( " TotalNumberOfClusters: %8lu\n", TotalNumberOfClusters ); } else { printf( "GetDiskFreeSpace() error %d.\n", GetLastError() ); } } else { printf( "GetDeviceParams() error %d.\n", GetLastError() ); } } } } BOOL GetMediaID(PMID pmid, UINT nDrive) { DEVIOCTL_REGISTERS reg; reg.reg_EAX = 0x440D; // IOCTL for block devices reg.reg_EBX = nDrive; // zero-based drive ID reg.reg_ECX = 0x0866; // Get Media ID command reg.reg_EDX = (DWORD) pmid; // receives media ID info if (!DoIOCTL(®)) return FALSE; if (reg.reg_Flags & 0x8000) // error if carry flag set return FALSE; return TRUE; } BOOL GetDeviceParams(PDPARAMS pdparams, UINT nDrive) { DEVIOCTL_REGISTERS reg; reg.reg_EAX = 0x440D; // IOCTL for block devices reg.reg_EBX = nDrive; // zero-based drive ID reg.reg_ECX = 0x0860; // Get Device Parameters command reg.reg_EDX = (DWORD) pdparams; // receives media ID info if (!DoIOCTL(®)) return FALSE; if (reg.reg_Flags & 0x8000) // error if carry flag set return FALSE; return TRUE; } BOOL DoIOCTL(PDEVIOCTL_REGISTERS preg) { HANDLE hDevice; BOOL fResult; DWORD cb; preg->reg_Flags = 0x8000; // assume error (carry flag set) hDevice = CreateFile("\\\\.\\vwin32", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, (LPSECURITY_ATTRIBUTES) NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if (hDevice == (HANDLE) INVALID_HANDLE_VALUE) return FALSE; else { fResult = DeviceIoControl(hDevice, VWIN32_DIOC_DOS_IOCTL, preg, sizeof(*preg), preg, sizeof(*preg), &cb, 0); } CloseHandle(hDevice); return fResult; }