Zu 2.:
Ich hab's noch nie mit Disketten probiert, muss aber ansich funktionieren.
Leider nur für NT und aufwärts.
In ein Modul:
Option Explicit
'*****************************************************************
' Module for performing Direct Read/Write access to disk sectors
'
' Written by Arkadiy Olovyannikov (ark@fesma.ru)
'
' formated, cutted, fixed and commented by rm_code
'*****************************************************************
Private Const FILE_BEGIN = 0 ' file begin at byte 0
'function for reading from a drive (only NT)
Public Function DirectReadDriveNT(ByVal sDrive As String, ByVal iStartSec As _
Long, ByVal iOffset As Long, ByRef ret() As Byte, Optional ByVal cBytes As _
Long = -1) As Boolean
Dim hDevice As Long, nSectors As Long, nRead As Long, BytesPerSector As Long
Dim abBuff() As Byte, abResult() As Byte
Dim sd As SECURITY_ATTRIBUTES
'get the size of a disk sector in bytes
If Not GetSectorSize(sDrive, BytesPerSector) Then Exit Function
If cBytes = -1 Or cBytes < 1 Then cBytes = BytesPerSector
'get the number of sectors to read
nSectors = Int((iOffset + cBytes - 1) / BytesPerSector) + 1
'open the drive
hDevice = CreateFile("\\.\" & UCase(Left(sDrive, 1)) & ":", _
GENERIC_READ Or GENERIC_WRITE, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
sd, OPEN_EXISTING, 0&, 0&)
'check for a valid drive handle
If hDevice = INVALID_HANDLE_VALUE Then Exit Function
'set the filepointer to the first sector we want to read
SetFilePointer hDevice, iStartSec * BytesPerSector, 0, FILE_BEGIN
'prepare the buffers
ReDim abResult(cBytes - 1)
ReDim abBuff(nSectors * BytesPerSector - 1)
'read the sectors and close the handle to the drive
ReadFile hDevice, abBuff(0), UBound(abBuff) + 1, nRead, 0&
CloseHandle hDevice
'copy the bytes from the read buffer to the result buffer...
CopyMemory abResult(0), abBuff(iOffset), cBytes
'... and return it
ret = abResult
DirectReadDriveNT = True
End Function
'function for writing to a drive (only NT)
Public Function DirectWriteDriveNT(ByVal sDrive As String, ByVal iStartSec As _
Long, ByVal iOffset As Long, ByVal sWrite As String) As Boolean
Dim hDevice As Long, nRead As Long, nSectors As Long, BytesPerSector As Long
Dim sd As SECURITY_ATTRIBUTES
Dim abBuff() As Byte, ab() As Byte
'get the size of a disk sector in bytes
If Not GetSectorSize(sDrive, BytesPerSector) Then Exit Function
'get the number of sectors to read
nSectors = Int((iOffset + Len(sWrite) - 1) / BytesPerSector) + 1
'open the drive
hDevice = CreateFile("\\.\" & UCase(Left(sDrive, 1)) & ":", _
GENERIC_READ Or GENERIC_WRITE, _
FILE_SHARE_READ Or FILE_SHARE_WRITE, _
sd, OPEN_EXISTING, 0&, 0&)
'check for a valid drive handle
If hDevice = INVALID_HANDLE_VALUE Then Exit Function
'fill the write buffer with the data from the sectors we want to overwrite,
'because we have the option to start writing from an offset
DirectReadDriveNT sDrive, iStartSec, 0, abBuff, nSectors * BytesPerSector
ab = StrConv(sWrite, vbFromUnicode)
'add the data to write to the writebuffer
CopyMemory abBuff(iOffset), ab(0), Len(sWrite)
'set the filepointer to the first sector we want to write to
SetFilePointer hDevice, iStartSec * BytesPerSector, 0, FILE_BEGIN
'lock the drive for writing
LockFile hDevice, LoWord(iStartSec * BytesPerSector), _
HiWord(iStartSec * BytesPerSector), _
LoWord(nSectors * BytesPerSector), _
HiWord(nSectors * BytesPerSector)
'write it!
DirectWriteDriveNT = WriteFile(hDevice, abBuff(0), UBound(abBuff) + 1, _
nRead, 0&)
'make sure everything was written
FlushFileBuffers hDevice
'unlock the drive
UnlockFile hDevice, LoWord(iStartSec * BytesPerSector), _
HiWord(iStartSec * BytesPerSector), _
LoWord(nSectors * BytesPerSector), _
HiWord(nSectors * BytesPerSector)
'and clean up a little bit
CloseHandle hDevice
End Function |