/*++ Copyright (c) 1993 Microsoft Corporation Module Name: Drivesp.c Abstract: This module contains support for displaying the Drives dialog. Author: Scott B. Suhy (ScottSu) 6/1/93 Environment: User Mode --*/ #include "dialogsp.h" #include "drivesp.h" #include "msgp.h" #include "strtabp.h" #include "winmsdp.h" #include "printp.h" #include #include #include #include // // Macro to support freeing of NULL pointers. // #define Free( p ) \ { if(p) free(p); } // // Object used to pass information around about a logical drive. // typedef struct _DRIVE_INFO { DECLARE_SIGNATURE TCHAR DriveLetter[ 3 ]; UINT DriveType; LPTSTR RemoteNameBuffer; DWORD SectorsPerCluster; DWORD BytesPerSector; DWORD FreeClusters; DWORD Clusters; LPTSTR VolumeNameBuffer; DWORD VolumeSerialNumber; DWORD MaximumComponentLength; DWORD FileSystemFlags; LPTSTR FileSystemNameBuffer; BOOL ValidDetails; } DRIVE_INFO, *LPDRIVE_INFO; // // Internal function prototypes. // LPDRIVE_INFO CreateDriveInfo( IN LPTSTR Drive ); BOOL DestroyDriveInfo( IN LPDRIVE_INFO DriveInfo ); BOOL DriveDetailsProc( LPDRIVE_INFO DriveObject ); LPDRIVE_INFO CreateDriveInfo( IN LPTSTR Drive ) /*++ Routine Description: Create a DRIVE_INFO object for the supplied drive. Arguments: Drive - Supplies a pointer to a string which is the root directory of the drive (e.g. c:\). Return Value: LPDRIVE_INFO - Returns a pointer to a DRIVE_INFO object with information about the supplied drive. --*/ { UINT OldErrorMode; LPDRIVE_INFO DriveInfo; TCHAR FileSystemNameBuffer[ MAX_PATH ]; TCHAR VolumeNameBuffer[ MAX_PATH ]; TCHAR RemoteNameBuffer[ MAX_PATH ]; DWORD SizeOfRemoteNameBuffer; // // Allocate a DRIVE_INFO object. // DriveInfo = AllocateObject( DRIVE_INFO, 1 ); DbgPointerAssert( DriveInfo ); if( DriveInfo == NULL ) { return NULL; } SetSignature( DriveInfo ); // // Initialize buffers with empty strings. // FileSystemNameBuffer[ 0 ] = TEXT( '\0' ); VolumeNameBuffer[ 0 ] = TEXT( '\0' ); RemoteNameBuffer[ 0 ] = TEXT( '\0' ); // // Remember the drive letter. // DriveInfo->DriveLetter[ 0 ] = Drive[ 0 ]; DriveInfo->DriveLetter[ 1 ] = Drive[ 1 ]; DriveInfo->DriveLetter[ 2 ] = TEXT( '\0' ); // // Get the type of this drive. // DriveInfo->DriveType = GetDriveType( Drive ); // // If this is a network drive, get the share its connected to. // if( DriveInfo->DriveType == DRIVE_REMOTE ) { DWORD WNetError; // // WinNet APIs want the drive name w/o a trailing slash so use the // DriveLetter field in the DRIVE_INFO object. // SizeOfRemoteNameBuffer = sizeof( RemoteNameBuffer ); WNetError = WNetGetConnection( DriveInfo->DriveLetter, RemoteNameBuffer, &SizeOfRemoteNameBuffer ); DbgAssert( ( WNetError == NO_ERROR ) || ( WNetError == ERROR_VC_DISCONNECTED )); DriveInfo->RemoteNameBuffer = _tcsdup( RemoteNameBuffer ); DbgPointerAssert( DriveInfo->RemoteNameBuffer ); } // // Disable pop-ups (especially if there is no media in the // removable drives.) // OldErrorMode = SetErrorMode( SEM_FAILCRITICALERRORS ); // // Get the space statistics for this drive. // DriveInfo->ValidDetails = GetDiskFreeSpace( Drive, &DriveInfo->SectorsPerCluster, &DriveInfo->BytesPerSector, &DriveInfo->FreeClusters, &DriveInfo->Clusters ); if( DriveInfo->ValidDetails == FALSE ) { return DriveInfo; } // // Get information about the volume for this drive. // DriveInfo->ValidDetails = GetVolumeInformation( Drive, VolumeNameBuffer, sizeof( VolumeNameBuffer ), &DriveInfo->VolumeSerialNumber, &DriveInfo->MaximumComponentLength, &DriveInfo->FileSystemFlags, FileSystemNameBuffer, sizeof( FileSystemNameBuffer ) ); // // Reenable pop-ups. // SetErrorMode( OldErrorMode ); // // If no error occurred, make dynamic copies of the volume, // and file system name buffers. // if( DriveInfo->ValidDetails == TRUE ) { DriveInfo->VolumeNameBuffer = _tcsdup( VolumeNameBuffer ); DbgPointerAssert( DriveInfo->VolumeNameBuffer ); DriveInfo->FileSystemNameBuffer = _tcsdup( FileSystemNameBuffer ); DbgPointerAssert( DriveInfo->FileSystemNameBuffer ); } return DriveInfo; } BOOL DestroyDriveInfo( IN LPDRIVE_INFO DriveInfo ) /*++ Routine Description: Destroys a DRIVE_INFO object by deleting it and all resources associated with it. Arguments: LPDRIVE_INFO - Supplies a pointer to a DRIVE_INFO object. Return Value: BOOL - Returns TRUE if the DRIVE_OBJECT is succesfully destroyed --*/ { BOOL Success; // // 'free' the '_tcsdup'ed strings. // Free( DriveInfo->RemoteNameBuffer ); Free( DriveInfo->VolumeNameBuffer ); Free( DriveInfo->FileSystemNameBuffer ); // // Delete the DRIVE_INFO object itself. // Success = FreeObject( DriveInfo ); return TRUE; } BOOL DrivesProc() /*++ Routine Description: DrivesProc supports the display of the drives dialog which displays information about logical drives, including type, and connection of a remote drive. Arguments: None Return Value: BOOL - Depending on input message and processing options. --*/ { BOOL Success; TCHAR LogicalDrives[ MAX_PATH ]; LPTSTR Drive; DWORD Chars; DWORD Widths[ ] = { 5, ( DWORD ) -1 }; // // Retrieve the logical drive strings from the system. // Chars = GetLogicalDriveStrings( sizeof( LogicalDrives ), LogicalDrives ); Drive = LogicalDrives; // // For each logical drive, create a DRIVE_INFO object and display // its name and type. // while( *Drive ) { LPDRIVE_INFO DriveInfo; // // Create a DRIVE_INFO object for the current drive. // DriveInfo = CreateDriveInfo( Drive ); if( DriveInfo == NULL ) { return FALSE; } DriveDetailsProc(DriveInfo); // // Examine the next logical drive. // Drive += _tcslen( Drive ) + 1; DestroyDriveInfo(DriveInfo); }//end while return TRUE; } BOOL DriveDetailsProc(LPDRIVE_INFO DriveObject ) /*++ Routine Description: DriveDetailsProc supports the display of the drives detail dialog which displays information about a logical drive, including, label, serial number, file system information and a host of space statistics. Arguments: Return Value: BOOL - Depending on input message and processing options. --*/ { BOOL Success; INT i; TCHAR TitleBuffer[ MAX_PATH ]; LPDRIVE_INFO DriveInfo; VALUE_ID_MAP FSFlags[ ] = { FS_CASE_IS_PRESERVED, IDC_TEXT_CASE_IS_PRESERVED, FS_CASE_SENSITIVE, IDC_TEXT_CASE_SENSITIVE, FS_UNICODE_STORED_ON_DISK, IDC_TEXT_UNICODE_STORED_ON_DISK }; // // Retrieve and validate the DRIVE_INFO object. // DriveInfo = ( LPDRIVE_INFO ) DriveObject; // // If the drive is remote, display its connection name in the title. // if( DriveInfo->DriveType == DRIVE_REMOTE ) { PrintToFile((LPCTSTR)DriveInfo->DriveLetter,IDC_REMOTE_DRIVE_TITLE,TRUE); PrintToFile((LPCTSTR)DriveInfo->RemoteNameBuffer,IDC_REMOTE_DRIVE_TITLE,TRUE); PrintToFile((LPCTSTR)DriveInfo->VolumeNameBuffer,IDC_REMOTE_DRIVE_TITLE,TRUE); PrintToFile((LPCTSTR)FormatBigInteger(HIWORD (DriveInfo->VolumeSerialNumber),FALSE),IDC_REMOTE_DRIVE_TITLE,TRUE); PrintToFile((LPCTSTR)FormatBigInteger(LOWORD (DriveInfo->VolumeSerialNumber),FALSE),IDC_REMOTE_DRIVE_TITLE,TRUE); } else { PrintToFile((LPCTSTR)DriveInfo->DriveLetter,IDC_DRIVE_TITLE,TRUE); PrintToFile((LPCTSTR)DriveInfo->VolumeNameBuffer,IDC_DRIVE_TITLE,TRUE); PrintHexToFile(HIWORD (DriveInfo->VolumeSerialNumber),IDC_VOLUME_SN_TITLE); PrintHexToFile(LOWORD (DriveInfo->VolumeSerialNumber),IDC_VOLUME_SN_TITLE); } PrintToFile((LPCTSTR)FormatBigInteger(DriveInfo->SectorsPerCluster,FALSE),IDC_EDIT_SECTORS_PER_CLUSTER,TRUE); PrintToFile((LPCTSTR)FormatBigInteger(DriveInfo->BytesPerSector,FALSE),IDC_EDIT_BYTES_PER_SECTOR,TRUE); PrintToFile((LPCTSTR)FormatBigInteger(DriveInfo->FreeClusters,FALSE),IDC_EDIT_FREE_CLUSTERS,TRUE); PrintToFile((LPCTSTR)FormatBigInteger(DriveInfo->Clusters - DriveInfo->FreeClusters,FALSE),IDC_EDIT_USED_CLUSTERS,TRUE); PrintToFile((LPCTSTR)FormatBigInteger(DriveInfo->Clusters,FALSE),IDC_EDIT_TOTAL_CLUSTERS,TRUE); PrintToFile((LPCTSTR)FormatBigInteger(DriveInfo->FreeClusters * DriveInfo->SectorsPerCluster * DriveInfo->BytesPerSector,FALSE),IDC_EDIT_FREE_SPACE,TRUE); PrintToFile((LPCTSTR)FormatBigInteger((DriveInfo->Clusters - DriveInfo->FreeClusters ) * DriveInfo->SectorsPerCluster * DriveInfo->BytesPerSector,FALSE),IDC_EDIT_USED_SPACE,TRUE); PrintToFile((LPCTSTR)FormatBigInteger(DriveInfo->Clusters * DriveInfo->SectorsPerCluster * DriveInfo->BytesPerSector,FALSE),IDC_EDIT_TOTAL_SPACE,TRUE); // // Display the file system information. // PrintToFile((LPCTSTR)DriveInfo->FileSystemNameBuffer,IDC_EDIT_FS_NAME,TRUE); PrintToFile((LPCTSTR)FormatBigInteger(DriveInfo->MaximumComponentLength,FALSE),IDC_EDIT_FS_MAX_COMPONENT,TRUE); PrintToFile((LPCTSTR)TEXT("\n"),IDC_SPACE,TRUE); return TRUE; }