用VB对磁盘的物理扇区数据读/写操作

原创 2004年08月13日 01:37:00

Option Explicit

'/////////////////////////////////////////
'// 对磁盘的物理扇区数据读/写操作
'// last update: 2004-8-7
'// Kwanhong Young
'/////////////////////////////////////////


'//file system
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Declare Function ReadFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long '//declare has changed
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long '//declare has changed
Private Declare Function SetFilePointer Lib "kernel32" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long

Private Const GENERIC_READ = &H80000000
Private Const GENERIC_WRITE = &H40000000

Private Const FILE_SHARE_READ = &H1
Private Const FILE_SHARE_WRITE = &H2
Private Const OPEN_EXISTING = 3

Private Const INVALID_HANDLE_VALUE = -1

'//file seek
Private Const FILE_BEGIN = 0
Private Const FILE_CURRENT = 1
Private Const FILE_END = 2

Private Const ERROR_SUCCESS = 0&

'//device io control
Private Declare Function DeviceIoControl Lib "kernel32" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, lpInBuffer As Any, ByVal nInBufferSize As Long, lpOutBuffer As Any, ByVal nOutBufferSize As Long, lpBytesReturned As Long, ByVal lpOverlapped As Long) As Long

Private Const IOCTL_DISK_GET_DRIVE_GEOMETRY As Long = &H70000   '458752
Private Const IOCTL_STORAGE_GET_MEDIA_TYPES_EX  As Long = &H2D0C04
Private Const IOCTL_DISK_FORMAT_TRACKS As Long = &H7C018
Private Const FSCTL_LOCK_VOLUME As Long = &H90018
Private Const FSCTL_UNLOCK_VOLUME As Long = &H9001C
Private Const FSCTL_DISMOUNT_VOLUME As Long = &H90020
Private Const FSCTL_GET_VOLUME_BITMAP = &H9006F

'//type
Private Type LARGE_INTEGER
    lowpart As Long
    highpart As Long
End Type

Private Enum MEDIA_TYPE
    Unknown
    F5_1Pt2_512
    F3_1Pt44_512
    F3_2Pt88_512
    F3_20Pt8_512
    F3_720_512
    F5_360_512
    F5_320_512
    F5_320_1024
    F5_180_512
    F5_160_512
    RemovableMedia
    FixedMedia
End Enum

Private Type DISK_GEOMETRY
    Cylinders           As LARGE_INTEGER
    MediaType           As MEDIA_TYPE
    TracksPerCylinder   As Long
    SectorsPerTrack     As Long
    BytesPerSector      As Long
End Type

'//private vars
Private hDisk           As Long             'disk handle
Private lpGeometry      As DISK_GEOMETRY    'disk info
Private lBufferSize     As Long             'the buffer size of read/write

Public Function OpenDisk(ByVal FileName As String) As Boolean
'// 打开磁盘
    hDisk = CreateFile(FileName, _
                        GENERIC_READ Or GENERIC_WRITE, _
                        FILE_SHARE_READ Or FILE_SHARE_WRITE, _
                        ByVal 0&, _
                        OPEN_EXISTING, _
                        0, _
                        0)
    OpenDisk = Not (hDisk = INVALID_HANDLE_VALUE)
End Function

Public Function CloseDisk() As Boolean
'//关闭磁盘
    CloseDisk = CloseHandle(hDisk)
End Function

Public Function GetDiskGeometry() As Boolean
'//获取磁盘参数
    Dim dwOutBytes      As Long
    Dim bResult         As Boolean
   
    bResult = DeviceIoControl(hDisk, _
                                IOCTL_DISK_GET_DRIVE_GEOMETRY, _
                                ByVal 0&, 0, _
                                lpGeometry, Len(lpGeometry), _
                                dwOutBytes, _
                                ByVal 0&)
   
    If bResult Then lBufferSize = lpGeometry.BytesPerSector * lpGeometry.SectorsPerTrack
    GetDiskGeometry = bResult
End Function

Public Sub GetDiskInfo(MediaType As Long, _
                        Cylinders As Long, _
                        TracksPerCylinder As Long, _
                        SectorsPerTrack As Long, _
                        BytesPerSector As Long)
'//返回磁盘的参数
    MediaType = lpGeometry.MediaType
    Cylinders = lpGeometry.Cylinders.lowpart
    TracksPerCylinder = lpGeometry.TracksPerCylinder
    SectorsPerTrack = lpGeometry.SectorsPerTrack
    BytesPerSector = lpGeometry.BytesPerSector

End Sub

Public Property Get BufferSize() As Long
'//返回每次读/写的缓冲大小
    BufferSize = lBufferSize
End Property


Public Function LockVolume() As Boolean
'// 将卷锁定
    Dim dwOutBytes  As Long
    Dim bResult     As Boolean
   
    bResult = DeviceIoControl(hDisk, _
                                FSCTL_LOCK_VOLUME, _
                                ByVal 0&, 0, _
                                ByVal 0&, 0, _
                                dwOutBytes, _
                                ByVal 0&)
    LockVolume = bResult
End Function


Public Function UnlockVolume() As Boolean
'// 将卷解锁
    Dim dwOutBytes As Long
    Dim bResult As Boolean
   
    bResult = DeviceIoControl(hDisk, _
                                FSCTL_UNLOCK_VOLUME, _
                                ByVal 0&, 0, _
                                ByVal 0&, 0, _
                                dwOutBytes, _
                                ByVal 0&)
    UnlockVolume = bResult
End Function


Public Function DismountVolume() As Boolean
'// 将卷卸下,使系统重新辨识磁盘,等效于重新插盘
    Dim dwOutBytes As Long
    Dim bResult As Boolean
   
    bResult = DeviceIoControl(hDisk, _
                                FSCTL_DISMOUNT_VOLUME, _
                                ByVal 0&, 0, _
                                ByVal 0&, 0, _
                                dwOutBytes, _
                                ByVal 0&)
    DismountVolume = bResult
End Function


Public Function ReadDisk(ByVal Cylinders As Long, _
                    ByVal Tracks As Long, _
                    db() As Byte) As Boolean
'//按柱面和磁道来读取磁盘数据
    Dim iPos    As Long
    Dim lRead   As Long
   
    iPos = Cylinders * Tracks * lBufferSize
   
    If SeekAbsolute(0, iPos) Then
        ReadDisk = ReadBytes(lBufferSize, db(), lRead)
    End If
End Function

Public Function WriteDisk(ByVal Cylinders As Long, _
                     ByVal Tracks As Long, _
                     db() As Byte) As Boolean
'//按柱面和磁道来写磁盘数据
    Dim iPos    As Long
    Dim lRead   As Long
   
    iPos = Cylinders * Tracks * lBufferSize
   
    If SeekAbsolute(0, iPos) Then
        WriteDisk = WriteBytes(lBufferSize, db())
    End If
End Function


'/////////////////////////////////////////////////////////////////////////////////////
'//file system

Private Function SeekAbsolute(ByVal HighPos As Long, ByVal LowPos As Long) As Boolean
'//seek file
    '//Notice: when you set LowPos=5, the read/write will begin with the 6th(LowPos+1) byte
    LowPos = SetFilePointer(hDisk, LowPos, HighPos, FILE_BEGIN)
    If LowPos = -1 Then
        SeekAbsolute = (Err.LastDllError = ERROR_SUCCESS)
    Else
        SeekAbsolute = True
    End If
   
End Function


Private Function ReadBytes(ByVal ByteCount As Long, ByRef DataBytes() As Byte, ByRef ActuallyReadByte As Long) As Boolean
'//read data to array
    Dim RetVal    As Long
    RetVal = ReadFile(hDisk, DataBytes(0), ByteCount, ActuallyReadByte, 0)
    'ActuallyReadByte =>> if the bytesRead=0 mean EOF
    ReadBytes = Not (RetVal = 0)
   
End Function

Private Function WriteBytes(ByVal ByteCount As Long, ByRef DataBytes() As Byte) As Boolean
'//write data from array
    Dim RetVal As Long
    Dim BytesToWrite As Long
    Dim BytesWritten As Long
   
    RetVal = WriteFile(hDisk, DataBytes(0), ByteCount, BytesWritten, 0)
   
    WriteBytes = Not (RetVal = 0)
End Function

DeviceIoControl 直接从磁盘扇区读文件

好久没写博客了,最近看了下DeviceIoControl  关于磁盘的应用,特记一文,以备久后查阅。 首先介绍下,文件在磁盘的存储结构(具体可以到网上查询NTFS文件系统相关的教程后者数据恢复方面...
  • ilovemayverymuch
  • ilovemayverymuch
  • 2014年07月20日 02:35
  • 2483

Linux中如何读写硬盘上指定物理扇区

读指定物理扇区: dd  if=  of=   skip=  bs=512 count=1 写指定物理扇区: dd   if=   of=   seek=  bs=512 c...
  • xshalk
  • xshalk
  • 2013年12月30日 22:15
  • 6515

[Win32] 直接读写磁盘扇区(磁盘绝对读写)

本博文由CSDN博主zuishikonghuan所作,版权归zuishikonghuan所有,转载请注明出处: 正讲着驱动开发呢,这里突然插一篇Win32的博文,其实,还是做引子,上一篇博文“IRP与...
  • zuishikonghuan
  • zuishikonghuan
  • 2016年01月03日 16:31
  • 6526

linux2.6硬盘扇区直接读写程序

下面的程序可以在linux2.6内核直接读写硬盘的指定扇区,也是根据网上一个朋友的做法做了修改的;有两个不是很明白的地方就是:1、bd_claim函数的使用,这个是个递归函数,像是匹配内存指针和设备,...
  • mao0514
  • mao0514
  • 2015年04月29日 10:37
  • 2177

Linux中如何读写硬盘(或Virtual Disk)上指定物理扇区

文件系统调试 Linux中如何读写硬盘(或Virtual Disk)上指定物理扇区 读指定物理扇区 dd if= of= skip= bs=512 count=1 写指定物理扇区 dd if= o...
  • noviblue
  • noviblue
  • 2017年02月19日 11:07
  • 929

关于硬盘扇区的基本知识

转自:http://www.intohard.com/article-436-1.html 盘片上涉及的基本概念 整个硬盘上一般有很多的盘片组成,每个盘片如同切西瓜一样被“切”成一块一块的扇面,同时沿...
  • yongheng_1999
  • yongheng_1999
  • 2016年12月15日 23:15
  • 2670

Linux中如何读写硬盘上指定物理扇区

读指定物理扇区: dd  if=  of=   skip=  bs=512 count=1 写指定物理扇区: dd   if=   of=   seek=  bs=512 c...
  • bfboys
  • bfboys
  • 2016年09月04日 15:21
  • 824

文件系统中的逻辑块、物理块和扇区之间的关系

原文链接:文件系统中的逻辑块、物理块和扇区之间的关系 扇区(sector):硬件(磁盘)上的最小的操作单位,是操作系统和块设备(硬件、磁盘)之间传送数据的单位。          ...
  • sinat_25457697
  • sinat_25457697
  • 2015年02月10日 10:50
  • 3153

linux 读写磁盘扇区

linux2.6硬盘扇区直接读写程序  (2010-03-23 08:35:16) 转载▼ 标签:  linux   硬盘   读写 分类...
  • hcstar
  • hcstar
  • 2014年12月26日 15:18
  • 352

Linux中硬盘物理扇区 与文件系统文件对应关系

1               概述 系统读写文件过程中,如下面内核打印信息,报告读写某个扇区错误。那么我们如何能够通过sector找到读写哪个文件错误? kernel: end_request:...
  • xiaofei0859
  • xiaofei0859
  • 2016年10月11日 18:28
  • 1348
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:用VB对磁盘的物理扇区数据读/写操作
举报原因:
原因补充:

(最多只允许输入30个字)