Pregunta: | 1928 - LEER/ESCRIBIR LOS SECTORES DE UN DISCO |
Autor: | Cristhian Guzman Echeverria |
Como puedo Leer/Escribir los sectores del disco duro mediante las API´s, lo que deseo es tener acceso a la parte fisica del disco duro, lo necesito para un programa que corra sobre windows, ya sea usando las API´s o un lenguaje ensamblador para windows |
Respuesta: | Paul Wolfe |
' Para acceso R/W directamente a los sectores de un disco hay ciertas reglas. 'La longitud del buffer de lectura / escritura debe ser un múltiplo del tamaño de los sectores del disco, que generalmente es de 512 bytes. 'También el puntero de lectura / escritura debe estár posicionado al principio de un sector. 'Tanto el conteo de los sectores, como la posicion dentro de ellos empieza con 0. Por ejemplo si un disco tiene 1024 sectores, el primero será el sector 0, y el último el 1023. De igual manera un sector de 512 bytes comienza con la posición 0, y termina con 511. '*******ESPERO TE SIRVA ESTO:************** Option Explicit Public Declare Function GetDiskFreeSpace Lib "Kernel32.dll" Alias "GetDiskFreeSpaceA" (ByVal lpRootPathName As String, lpSectorsPerCluster As Long, lpBytesPerSector As Long, lpNumberOfFreeClusters As Long, lpTotalNumberOfClusters As Long) As Long Public Declare Function GetVolumeInformation Lib "Kernel32.dll" Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Long, lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long Public Declare Function GetDriveType Lib "Kernel32.dll" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long Public Declare Function CreateFile Lib "Kernel32.dll" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long Public Declare Function CloseHandle Lib "Kernel32.dll" (ByVal hObject As Long) As Long Public Declare Function SetFilePointer Lib "Kernel32.dll" (ByVal hFile As Long, ByVal lDistanceToMove As Long, lpDistanceToMoveHigh As Long, ByVal dwMoveMethod As Long) As Long Public Declare Function ReadFile Lib "Kernel32.dll" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, ByVal lpOverlapped As Long) As Long Public Declare Function WriteFile Lib "Kernel32.dll" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, ByVal lpOverlapped As Long) As Long Public Declare Function FlushFileBuffers Lib "Kernel32.dll" (ByVal hFile As Long) As Long Public Declare Function DeviceIoControl Lib "Kernel32.dll" (ByVal hDevice As Long, ByVal dwIoControlCode As Long, ByRef lpInBuffer As Any, ByVal nInBufferSize As Long, ByRef lpOutBuffer As Any, ByVal nOutBufferSize As Long, ByRef lpBytesReturned As Long, ByVal lpOverlapped As Long) As Long Public Declare Sub CopyMemory Lib "Kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) Public Const FILE_READ_ACCESS = &H1 Public Const FILE_WRITE_ACCESS = &H2 Public Const GENERIC_READ = &H80000000 Public Const GENERIC_WRITE = &H40000000 Public Const FILE_SHARE_READ = &H1 Public Const FILE_SHARE_WRITE = &H2 Public Const OPEN_EXISTING = 3 Public Const INVALID_HANDLE_VALUE = -1& Public Const FILE_BEGIN = 0 Public Const FILE_CURRENT = 1 'Public Const lngMaxSectors As Long = 4194303 'Public Const FILE_END = 2 Public Const FSCTL_LOCK_VOLUME As Long = &H90018 Public Const FSCTL_UNLOCK_VOLUME As Long = &H9001C Public Type typeVolumeInformation byteTipoUnidad As Byte ' Removible=2, Fijo=3, etc.. byteEtiqueta() As Byte byteSistemaArchivos() As Byte lngSerialVolumen As Long lngBytesPorSector As Long lngSectoresPorCluster As Long lngBytesPorCluster As Long lngTotalDeSectores As Long lngSectoresLibres As Long lngTotalDeClusters As Long lngClustersLibres As Long End Type Public Function ObtenerInfoVolumen(ByVal byteDrv As Byte, typeRetVolInfo As typeVolumeInformation) As Long On Error Resume Next If byteDrv <= 0 Or byteDrv > 26 Then Exit Function ' Unidad incorrecta, sale... Const lStrLen = 256 Dim sUnidad As String: sUnidad = "" Dim lRet As Long: lRet = 0 Dim l As Long: l = 0 Dim sVolLabel As String: sVolLabel = String(lStrLen, 0) Dim sVolFileSys As String: sVolFileSys = String(lStrLen, 0) Dim lTmpTotalClusters As Long: lTmpTotalClusters = 0 Dim lTmpBytesSec As Long: lTmpBytesSec = 0 sUnidad = Chr$(byteDrv + 64) & ":\" typeRetVolInfo.byteTipoUnidad = CByte(GetDriveType(sUnidad)) If typeRetVolInfo.byteTipoUnidad <> 2 And typeRetVolInfo.byteTipoUnidad <> 3 And typeRetVolInfo.byteTipoUnidad <> 5 And typeRetVolInfo.byteTipoUnidad <> 6 Then Exit Function lRet = GetDiskFreeSpace(sUnidad, typeRetVolInfo.lngSectoresPorCluster, lTmpBytesSec, l, lTmpTotalClusters) If lTmpBytesSec > 0 Then typeRetVolInfo.lngBytesPorSector = lTmpBytesSec Else typeRetVolInfo.lngBytesPorSector = 512 End If typeRetVolInfo.lngTotalDeSectores = typeRetVolInfo.lngSectoresPorCluster * lTmpTotalClusters typeRetVolInfo.lngBytesPorCluster = typeRetVolInfo.lngSectoresPorCluster * typeRetVolInfo.lngBytesPorSector Call GetVolumeInformation(sUnidad, sVolLabel, lStrLen, typeRetVolInfo.lngSerialVolumen, &H0, &H0, sVolFileSys, lStrLen) sVolLabel = Replace(sVolLabel, Chr(0), "") sVolFileSys = Replace(sVolFileSys, Chr(0), "") If sVolLabel <> vbNullString Then ' Convertir a array de bytes:... For l = 1 To Len(sVolLabel) ReDim Preserve typeRetVolInfo.byteEtiqueta(l - 1) typeRetVolInfo.byteEtiqueta(l - 1) = CByte(Asc(Mid$(sVolLabel, l, 1))) Next l Else ReDim typeRetVolInfo.byteEtiqueta(0) typeRetVolInfo.byteEtiqueta(0) = 0 End If If sVolFileSys <> vbNullString Then ' Convertir a array de bytes:... For l = 1 To Len(sVolFileSys) ReDim Preserve typeRetVolInfo.byteSistemaArchivos(l - 1) typeRetVolInfo.byteSistemaArchivos(l - 1) = CByte(Asc(Mid$(sVolFileSys, l, 1))) Next l Else ReDim typeRetVolInfo.byteSistemaArchivos(0) typeRetVolInfo.byteSistemaArchivos(0) = 0 End If FsOk: If Err = 0 Then ObtenerInfoVolumen = 1 On Error GoTo 0 End Function Public Function LeerDisco(ByVal byteDrv As Byte, ByVal lngSectorInicial As Long, ByVal lngPosicion As Long, ByRef byteRetArray() As Byte, ByVal lngCntBytes As Long) As Long On Error Resume Next 'Dim sDrive As String: sDrive = Chr$(byteDrv + 64) & ":" Dim tDatosVol As typeVolumeInformation Dim lRet As Long: lRet = ObtenerInfoVolumen(byteDrv, tDatosVol) If lRet = 0 Then Exit Function lRet = 0 Dim lCVolumen As Long: lCVolumen = 0 Dim iSectores As Integer: iSectores = 0 Dim lngLow As Long: lngLow = 0 Dim lCntMAXes As Long: lCntMAXes = 0 Dim lngTmpSSec As Long: lngTmpSSec = lngSectorInicial Dim boolFlagF As Boolean: boolFlagF = False Dim lTmpBL As Long: lTmpBL = 0 iSectores = Int((lngPosicion + lngCntBytes - 1) / tDatosVol.lngBytesPorSector) + 1 If (lngSectorInicial + iSectores - 1) > (tDatosVol.lngTotalDeSectores - 1) Then Exit Function lCVolumen = CreateFile("\\.\" & Chr$(byteDrv + 64) & ":", GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, 0&, 0&) If lCVolumen = INVALID_HANDLE_VALUE Then Exit Function ' Or GENERIC_WRITE '********************************************************************************* ReDim abBuff(iSectores * tDatosVol.lngBytesPorSector - 1) As Byte Call SetPos(lCVolumen, lngSectorInicial, tDatosVol.lngBytesPorSector) lRet = ReadFile(lCVolumen, abBuff(0), UBound(abBuff) + 1, lTmpBL, 0&) CloseHandle lCVolumen ReDim byteRetArray(lngCntBytes - 1) CopyMemory byteRetArray(0), abBuff(lngPosicion), lngCntBytes Erase abBuff() LeerDisco = lngCntBytes 'lTmpBL On Error GoTo 0 End Function Public Function SetPos(ByVal lVolHand As Long, ByVal lSecIni As Long, ByVal lBxSec As Long) As Boolean On Error Resume Next Const lngMaxValLong As Long = 2147483647 Dim lngMaxSectors As Long: lngMaxSectors = CLng(Fix(lngMaxValLong / lBxSec)) Dim lngTmpSSec As Long: lngTmpSSec = lSecIni Dim lFileMovePos As Long: lFileMovePos = 0 While lngTmpSSec > lngMaxSectors Call SetFilePointer(lVolHand, CLng(lngMaxSectors * lBxSec), 0, lFileMovePos) lngTmpSSec = lngTmpSSec - lngMaxSectors If lFileMovePos = 0 Then lFileMovePos = 1 Wend Call SetFilePointer(lVolHand, CLng(lngTmpSSec * lBxSec), 0, lFileMovePos) If Err = 0 Then SetPos = True On Error GoTo 0 End Function |
Respuesta: | René Berra |
puede que esto te sirva: Function CopyFile(Src As String, Dst As String) As Single Static buf$ Dim BTest!, FSize! ´declare the needed variables Dim Chunk%, F1%, F2% Const BUFSIZE = 1024 ´set the buffer size If Len(Dir(Dst)) Then ´check to see if the destination file already exists Kill Dst ´delete the already found file, and carryon with the code End If On Error GoTo FileCopyError ´incase of error goto this label F1 = FreeFile ´returns file number available Open Src For Binary As F1 ´open the source file F2 = FreeFile ´returns file number available Open Dst For Binary As F2 ´open the destination file FSize = LOF(F1) BTest = FSize - LOF(F2) Do If BTest < BUFSIZE Then Chunk = BTest Else Chunk = BUFSIZE buf = String(Chunk, " ") Get F1, , buf Put F2, , buf BTest = FSize - LOF(F2) Loop Until BTest = 0 Close F1 ´closes the source file Close F2 ´closes the destination file CopyFile = FSize Exit Function ´exit the procedure FileCopyError: ´file copy error label CopyFile = 0 Close F1 ´closes the source file Close F2 ´closes the destination file Exit Function ´exit the procedure End Function |