Hola a todos!
Quien sabe sobre alguna Api que monitoree la integridad de la información en los discos fijos.
O sea detectar en el sistema y en todo momento si cree, modifique, copie, movi o borre una información X (no importa cual) en el disco duro.
Cómo saber si hubo cambios en la estructura de la información en general mediante la Api o evento del sistema?
Gracias!
Saludos.
Yo queria saber si exista algun programa que registre todo movimiento en el disco duro, lectura, escritura, etc, y tb del registro de windows, pero no veo ninguno, y me preguntaba si habria alguna forma de crearlo, pero no e encontrado nada
Deberia haber alguna Api..
Preguntemosle a nuestro moderador que es toda una autoridad en la materia.
Saludos.
Como existen las funciones de monitoreo del registro también están las de archivos, pero lo ideal sería hacerlo con un driver como lo hace el RegMon o el FileMon (dos programas excelentes).
Las funciones son FindFirstChangeNotification (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/findfirstchangenotification.asp) y FindNextChangeNotification (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/findnextchangenotification.asp). Primero se llama a la primera función y luego en un bucle a la segunda.
Cuando no se necesite más el handle se debe liberar llamando a FindCloseChangeNotification (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/findclosechangenotification.asp).
Saludos.
osita! y yo pensaba que no habia na pa esto! esk hay que preguntar en el sitio adecuado a la persona adecuada, por cierto, esos programas que tu as nombrado que hacen? monitorean archivos y el regisro?
Gracias Anhur!
Siempre nos salvas! ;D
Saludos.
este no es el foro adecuado para mi post, pero sí el hilo... ??? He codeado un código para probarlo pero no funciona, cambio el nombre de algún archivo y no me dice nada. Aquí os dejo el código a ver qué le veis:
#include <stdio.h>
#include <windows.h>
/*FUNCIÓN PRINCIPAL*/
void main()
{
//devuelde la descripción del error, a partir de su código
char *MensajeError(DWORD error_num);
HANDLE mon1=FindFirstChangeNotification("D:\\mon",TRUE,FILE_NOTIFY_CHANGE_FILE_NAME);
//creamos el handle
if(mon1==INVALID_HANDLE_VALUE)
{
printf("[!] Error al crear el handle -> %s",MensajeError(GetLastError()));
return;
}
for(;;)
{
if (FindNextChangeNotification(mon1)==0)
{
printf("\nCambio en el nombre de un archivo");
}
Sleep(100);
}
//cerramos y salimos
FindCloseChangeNotification(mon1);
return;
}
//devuelde la descripción del error, a partir de su código
char *MensajeError(DWORD error_num)
{
char *lpMsgBuf;
//cojemos el mensaje del error
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error_num,
0,
(LPTSTR) &lpMsgBuf,
0,
NULL
);
return lpMsgBuf;
}
Creo que no hace falta decir que dicho archivo se encuentra en "D:\mon" :)
No sé si será lo más apropiado pero ahí voy con mi ejemplo.
Use un Timer y un ListBox para esto.
Private Const FILE_NOTIFY_CHANGE_ATTRIBUTES = &H4
Private Const FILE_NOTIFY_CHANGE_DIR_NAME = &H2
Private Const FILE_NOTIFY_CHANGE_FILE_NAME = &H1
Private Const FILE_NOTIFY_CHANGE_SIZE = &H8
Private Const FILE_NOTIFY_CHANGE_LAST_WRITE = &H10
Private Const FILE_NOTIFY_CHANGE_SECURITY = &H100
Private Const FILE_NOTIFY_CHANGE_ALL = &H4 Or &H2 Or &H1 Or &H8 Or &H10 Or &H100
Private Const INFINITE = &HFFFFFFFF
Private Declare Function FindFirstChangeNotification Lib "kernel32" Alias "FindFirstChangeNotificationA" _
(ByVal lpPathName As String, ByVal bWatchSubtree As Long, ByVal dwNotifyFilter As Long) As Long
Private Declare Function FindNextChangeNotification Lib "kernel32" (ByVal hChangeHandle As Long) As Long
Private Declare Function FindCloseChangeNotification Lib "kernel32" (ByVal hChangeHandle As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Dim Handle As Long
Private Sub Form_Load()
Timer1.Interval = 1000
Handle = FindFirstChangeNotification("C:\", INFINITE, FILE_NOTIFY_CHANGE_ALL)
WaitForSingleObject Handle, 1
End Sub
Private Sub Timer1_Timer()
FindNextChangeNotification Handle
If WaitForSingleObject(Handle, 1) = 0 Then
List1.AddItem "La informacion del disco C:\ ha cambiado!!! ~ [ " & Now & " ]"
List1.Selected(List1.ListCount - 1) = True
End If
DoEvents
End Sub
Private Sub Form_Unload(Cancel As Integer)
FindCloseChangeNotification Handle
End Sub
En este otro intento controlar al mismo tiempo todas las unidades logicas añadiendo dos Apis más a lo anterior.
Pero por más que le di vueltas no me funcionó muy bien. Por poco me convierto en mi propio avatar :(
Aquí les dejo un trozo del
Private Declare Function GetLogicalDrives Lib "kernel32" () As Long
Private Declare Function GetDriveType Lib "kernel32" Alias "GetDriveTypeA" (ByVal nDrive As String) As Long
Dim Cont As Byte
Dim Drives As String
Dim Handle() As Long
Private Sub Form_Load()
Dim U As String * 1
Dim LDs As Long, Cnt As Long
LDs = GetLogicalDrives
For Cnt = 0 To 25
If (LDs And 2 ^ Cnt) <> 0 Then
If GetDriveType(Chr$(65 + Cnt) & ":\") = 3 Then _
Drives = Drives + Chr$(65 + Cnt)
End If
Next Cnt
ReDim Handle(1 To Len(Drives))
For Cont = 1 To Len(Drives)
U = Mid(Drives, Cont, 1)
Handle(Cont) = FindFirstChangeNotification(U & ":\", INFINITE, FILE_NOTIFY_CHANGE_ALL)
WaitForSingleObject Handle(Cont), 1
List1.AddItem "La informacion del disco " & U & _
":\ ha cambiado!!! ~ [ " & Now & " ]": List1.Selected(List1.ListCount - 1) = True
Next
End Sub
Ahora pregunto:
Existe otra via menos alevosa :P - con perdón de Anhur
Alguna variable global del sistema o manera de pasarle todas las unidades juntas ???
Saludos.
CitarHe codeado un código para probarlo pero no funciona, cambio el nombre de algún archivo y no me dice nada. Aquí os dejo el código a ver qué le veis:
Ah
Lympex! Eres admirable hombre, lástima que no tenga suficiente conocimiento en lenguaje C para codearme contigo.
De todas formas espero que lo que postee te sirva.
Saludos.
he retocado l codigo para k haga lo miso que haces tú con VB, pero tampoco funciona. El código en VB que posteastes tampoco me funciona. Aquí dejo el código en C
#include <stdio.h>
#include <windows.h>
#define COMPLETO FILE_NOTIFY_CHANGE_ATTRIBUTES || FILE_NOTIFY_CHANGE_DIR_NAME || FILE_NOTIFY_CHANGE_FILE_NAME || FILE_NOTIFY_CHANGE_SIZE || FILE_NOTIFY_CHANGE_LAST_WRITE || FILE_NOTIFY_CHANGE_SECURITY
/*FUNCIÓN PRINCIPAL*/
void main()
{
//devuelde la descripción del error, a partir de su código
char *MensajeError(DWORD error_num);
HANDLE mon1;
mon1=FindFirstChangeNotification("C:\\",TRUE,COMPLETO);
WaitForSingleObject(mon1,1);
//creamos el handle
if(mon1==INVALID_HANDLE_VALUE)
{
printf("[!] Error al crear el handle -> %s",MensajeError(GetLastError()));
return;
}
for(;;)
{
FindNextChangeNotification(mon1);
if(WaitForSingleObject(mon1,1)==0)
{
printf("\nLa informacion en la unidad C:\\ ha cambiado");
}
Sleep(1000);
}
//cerramos y salimos
FindCloseChangeNotification(mon1);
return;
}
//devuelde la descripción del error, a partir de su código
char *MensajeError(DWORD error_num)
{
char *lpMsgBuf;
//cojemos el mensaje del error
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error_num,
0,
(LPTSTR) &lpMsgBuf,
0,
NULL
);
return lpMsgBuf;
}
Será la Api
WaitForSingleObjectHonestamente a mi me funciona someramente.
Debería ser así
WaitForSingleObject Handle, &HFFFFFFFFpero con este valor infinito se congela. :(
Me dí cuenta que cuando ocurre el evento
WaitForSingleObject devuelve
0. Entonces lo que estoy tratando de hacer es mantenerla sin que se congele pero al mismo tiempo que este pediente del proceso.
CitarEl código en VB que posteastes tampoco me funciona.
No puedo decir que sea perfecto :-\ pero el evento se verificará en algún momento.
Quizás no sea la manera adecuada, preguntémosle nuevamente a los que más saben.
Por último me gustaría volver a citar a
Anhur y fíjense en lo que dice: '
luego en un bucle a la segunda'CitarLas funciones son FindFirstChangeNotification y FindNextChangeNotification. Primero se llama a la primera función y luego en un bucle a la segunda.
Saludos.
El siguiente ejemplo funciona perfectamente.
Option Explicit
Private Const FILE_NOTIFY_CHANGE_ATTRIBUTES = &H4
Private Const FILE_NOTIFY_CHANGE_DIR_NAME = &H2
Private Const FILE_NOTIFY_CHANGE_FILE_NAME = &H1
Private Const FILE_NOTIFY_CHANGE_SIZE = &H8
Private Const FILE_NOTIFY_CHANGE_LAST_WRITE = &H10
Private Const FILE_NOTIFY_CHANGE_SECURITY = &H100
Private Const FILE_NOTIFY_CHANGE_ALL = &H4 Or &H2 Or &H1 Or &H8 Or &H10 Or &H100
Private Const INFINITE = &HFFFFFFFF
Private Const OBJECT_WAIT_0 = 0
Private Const INVALID_HANDLE_VALUE = -1
Declare Function FindFirstChangeNotification Lib "kernel32" Alias "FindFirstChangeNotificationA" (ByVal lpPathName As String, ByVal bWatchSubtree As Long, ByVal dwNotifyFilter As Long) As Long
Declare Function FindNextChangeNotification Lib "kernel32" (ByVal hChangeHandle As Long) As Long
Declare Function FindCloseChangeNotification Lib "kernel32" (ByVal hChangeHandle As Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Declare Function SetTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Declare Function KillTimer Lib "user32" (ByVal hWnd As Long, ByVal nIDEvent As Long) As Long
Private bFileMonEnabled As Boolean
Sub Main()
Call StartFileMon
Call frmMain.Show
End Sub
Sub FileMonProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal idEvent As Long, ByVal dwTime As Long)
Dim r&, hMon&
r = KillTimer(0&, idEvent)
bFileMonEnabled = True
hMon = FindFirstChangeNotification("C:\WINDOWS", True, FILE_NOTIFY_CHANGE_ALL)
Do While bFileMonEnabled
r = WaitForSingleObject(hMon, 100&)
If r = OBJECT_WAIT_0 Then
r = FindNextChangeNotification(hMon)
'Se modificó el directorio.
'
End If
DoEvents
Loop
r = FindCloseChangeNotification(hMon)
End Sub
Sub StartFileMon()
If Not bFileMonEnabled Then
Call SetTimer(0&, 0&, 0&, AddressOf FileMonProc)
End If
End Sub
Sub StopFileMon()
bFileMonEnabled = False
End Sub
Lympex, tu error es que se debe llamar a FindNextChangeNotification luego de que la función WaitForSingleObject devuelva OBJECT_WAIT_0. Lo que hace es reestablecer el objeto a non-signaled.
Saludos.