|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Visual Basic Win32 Shell
Routines Undocumented Windows: Format Disk Dialog The Format Drive Dialog |
||
Posted: | Wednesday August 6, 1997 | |
Updated: | Monday December 26, 2011 | |
Applies to: | VB4-32, VB5, VB6 | |
Developed with: | VB4-32, Windows 95 | |
OS restrictions: | None | |
Author: | Brad Martinez | |
Related: |
SHChangeNotifyRegister: Receive Shell Change Notifications Undocumented Windows: Overview Undocumented Windows: Shell Dialogs Undocumented Windows: Change Icon Dialog Undocumented Windows: Path Functions |
|
Prerequisites |
None. |
|
Our
second project exploring the undocumented API takes us to SHFormatDrive. Though not listed in Brad's original listings nor an ordinal API
like those in Part 1 of this series (and future parts as well), it is nonetheless totally undocumented .. not a trace of it could be located
in the July 1997 MSDN. The caveat still applies: as an undocumented API it is not supported in any way, shape or form by Microsoft. In addition, this API *will* format a drive after prompting, so be careful. The actual call is only one line of code; the bulk of the code is for determination the Windows version since the constant values passed to SHFormatDrive are different for 9x vs. NT, to load the combo box with available drives, and to present a last-ditch message box if the selected drive isn't drive A: Once again, I've detailed the project form as both it appears with captions in place (the left or top illustration), and as a 'skeleton' form with the control names substituted for captions. There are no hidden controls, so instead of the usual control list, use the right-most form (or bottom, as resolution dictates) to design your project form. The arrangement makes no difference; the names indicated match the code below.
Can
you format a drive without showing the dialog? Theoretically yes, but
only through interrupt calls or DeviceIOControl on NT boxes. VBnet
does not demonstrate this method anywhere on the site.
|
BAS Module Code |
Once the form has been designed and saved, paste the following into the general declarations area of a file you name UndocSHFormat.bas: |
|
Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved. ' Some pages may also contain other copyrights by the author. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Distribution: You can freely use this code in your own ' applications, but you may not reproduce ' or publish this code on any web site, ' online service, or distribute as source ' on any media without express permission. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ------------------------------------------------------ 'Determines if the current OS is WinNT. 'Tested in the form load event only Public Declare Function GetVersionEx Lib "kernel32" _ Alias "GetVersionExA" _ (lpVersionInformation As OSVERSIONINFO) As Long Public Type OSVERSIONINFO dwOSVersionInfoSize As Long dwMajorVersion As Long dwMinorVersion As Long dwBuildNumber As Long dwPlatformId As Long szCSDVersion As String * 128 End Type Public Const VER_PLATFORM_WIN32s = 0 Public Const VER_PLATFORM_WIN32_WINDOWS = 1 Public Const VER_PLATFORM_WIN32_NT = 2 'APIs declarations for the format function Public Declare Function SHFormatDrive Lib "shell32" _ (ByVal hwndOwner As Long, _ ByVal iDrive As Long, _ ByVal iCapacity As Long, _ ByVal iFormatType As Long) As Long Public Const SHFD_CAPACITY_DEFAULT = 0 'default drive capacity Public Const SHFD_CAPACITY_360 = 3 '360KB, 5.25" only Public Const SHFD_CAPACITY_720 = 5 '720KB, 3.5" only 'Normally, these below would be declared as constants, 'if the values between Win95/98 and NT were the same (see 'the commented-out const values below). Public SHFD_FORMAT_QUICK As Long Public SHFD_FORMAT_FULL As Long Public SHFD_FORMAT_SYSONLY As Long 'However, because VB lacks a conditional #If variable 'to distinguish between Win95/98 and NT, they are DIMmed 'here and set in the Form_Load routine after GetVersionEx 'has been called. 'Win95/98 'Public Const SHFD_FORMAT_QUICK As Long= 0 'quick format 'Public Const SHFD_FORMAT_FULL As Long= 1 'full format 'Public Const SHFD_FORMAT_SYSONLY As Long= 2 'copy sys files only 'WinNT 'Public Const SHFD_FORMAT_FULL As Long= 0 'full format 'Public Const SHFD_FORMAT_QUICK As Long= 1 'quick format '------------------------------------------------------ 'support APIs to populate the combo box 'with the available drives Public Declare Function GetLogicalDriveStrings Lib "kernel32" _ Alias "GetLogicalDriveStringsA" _ (ByVal nBufferLength As Long, _ ByVal lpBuffer As String) As Long Public Declare Function GetDriveType Lib "kernel32" _ Alias "GetDriveTypeA" _ (ByVal nDrive As String) As Long Public Const DRIVE_REMOVABLE As Long = 2 Public Const DRIVE_FIXED As Long = 3 Public Const DRIVE_REMOTE As Long = 4 Public Const DRIVE_CDROM As Long = 5 Public Const DRIVE_RAMDISK As Long = 6 Public Function IsWinNT() As Boolean 'Returns True if the current operating 'system is WinNT or later Dim osvi As OSVERSIONINFO osvi.dwOSVersionInfoSize = Len(osvi) GetVersionEx osvi IsWinNT = (osvi.dwPlatformId = VER_PLATFORM_WIN32_NT) End Function |
Form Code |
To the project form illustrated above add the following code: |
|
Option Explicit Private Sub Form_Load() Me.Move (Screen.Width - Me.Width) / 2, (Screen.Height - Me.Height) / 2 'Load the combo box with the user's 'drives & drive types LoadAvailableDrives Combo1 'Pre-select index 1 (typically a user's C drive if 'only 1 floppy is installed) Combo1.ListIndex = 1 'Determine if the OS is NT or Win95/98 and assign 'the correct format variables If IsWinNT Then lbOSType = "(NT settings)" SHFD_FORMAT_FULL = 0 'full format SHFD_FORMAT_QUICK = 1 'quick format Else 'it's Win95/98 lbOSType = "(Win95/98 settings)" SHFD_FORMAT_QUICK = 0 'quick format SHFD_FORMAT_FULL = 1 'full format SHFD_FORMAT_SYSONLY = 2 'copies system files only End If End Sub Private Sub cmdSHFormat_Click() 'displays the Format Drive property sheet Dim resp As Integer Dim drvToFormat As Integer Dim prompt As String prompt = "Are you sure you want to run the _ Format dialog against " & Combo1.Text resp = MsgBox(prompt, vbCritical Or vbYesNo, "Are you sure") If resp = vbYes Then lbMessage.Caption = "Checking drive for disk..." lbMessage.Refresh Call SHFormatDrive(Me.hWnd, _ drvToFormat, _ SHFD_CAPACITY_DEFAULT, _ SHFD_FORMAT_QUICK) lbMessage.Caption = "" End If End Sub Private Sub cmdEnd_Click() Unload Me End Sub Private Function GetDrvStr(currDrive As String) As String 'from a passed drive string, determines 'the type of drive Select Case GetDriveType(currDrive) Case 0, 1: GetDrvStr= " - Undetermined Drive Type -" Case DRIVE_REMOVABLE: Select Case Left(currDrive, 1) Case "A", "B": GetDrvStr= "Floppy drive" Case Else: GetDrvStr= "Removable drive" End Select Case DRIVE_FIXED: GetDrvStr= "Fixed (Hard) drive" Case DRIVE_REMOTE: GetDrvStr= "Remote drive" Case DRIVE_CDROM: GetDrvStr= "CD ROM" Case DRIVE_RAMDISK: GetDrvStr= "Ram disk" End Select End Function Private Sub LoadAvailableDrives(cmbo As ComboBox) Dim lpBuffer As String 'get list of available drives lpBuffer = GetDriveString() 'Separate the drive strings 'and add to the combo. StripNulls 'will continually shorten the 'string. Loop until a single 'remaining terminating null is 'encountered. Do Until lpBuffer = Chr(0) 'strip off one drive item 'and add to the combo cmbo.AddItem StripNulls(lpBuffer) Loop '----------------- ' 'alternate method to above for VB6 ' Dim b() As String ' Dim cnt As Long ' b() = Split(lpBuffer, vbNullChar) ' 'lpBuffer has 2 trailing nulls, ' 'that will appear as array entries ' 'so skip those ' For cnt = LBound(b) To (UBound(b) - 2) ' Combo1.AddItem b(cnt) ' Next '----------------- End Sub Private Function GetDriveString() As String 'returns string of available 'drives each separated by a null Dim sBuffer As String 'possible 26 drives, three characters each + null sBuffer = Space$(26 * 4) If GetLogicalDriveStrings(Len(sBuffer), sBuffer) Then 'do not trim off trailing null! GetDriveString = Trim$(sBuffer) End If End Function Private Function StripNulls(startstr As String) As String 'Take a string separated by chr$(0) 'and split off 1 item, shortening the 'string so next item is ready for removal. Dim pos As Long pos = InStr(startstr$, Chr$(0)) If pos Then StripNulls = Mid$(startstr, 1, pos - 1) startstr = Mid$(startstr, pos + 1, Len(startstr)) Exit Function End If End Function |
Comments |
Save the project before running. If there is no disk in
the selected drive, the normal grinding will occur, but the dialog will still appear. Therefore, you'll want to check for the presence of a
disk in the drive before calling this on a user's system.
If you select the drive on which Windows is installed, it's self-preserving nature **should** inform you that that drive can not be formatted. However, should the Format dialog appear, selecting Start will format the selected disk. Use caution. |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |