I want to say a little about my idea, I want to hook the DeleteFile win32 API function in explorer.exe to intercept the deleting action, if someone deletes a file, a dialog box will pop up to ask for password, if the password is correct that one should be able to delete the file, if not the file will be protected from unauthorized user.
Firstly, I've done the hooking in Win7 and it failed then I tried the hooking in WinXP and it worked well except that when the user chooses Cancel, the file, in fact, is not deleted (that's what I want because user cancels his deleting operation), but the file is hidden right after user choosing Cancel from the dialog box. I have to press F5 (Refresh the window containing the file) to make it visible again. If don't do that, the user may think the file is deleted no matter what he chooses from the dialog. It is a little nasty to me. I tested the hooking on a Virtual machine installed with Win XP. I hope it should work well on a real machine. But this is not a serious problem to me. I think I've done the hooking successfully in Win XP. My serious problem is for Win 7.
For Win 7, my code even can't create a hook into explorer.exe, because right after the LocalHook.Create() is called, explorer.exe will be restarted, there is no exception raised. Because it is restarted so the hook is failed. I tried hooking CreateFile instead (this is from a sample code on EasyHook) and the hooking works well (explorer.exe doesn't restart). I don't know why explorer.exe restarts, there is no exception so it is really difficult for me to know, even debugging can't help (with my debugging skill), now here is a little of my inject dll code (the code for the main interface works well, it injects the dll successfully, because I can see some message sent from dll code, but the dll code which creates LocalHook fails):
public void Run(RemoteHooking.IContext icontext, string channel)
{
try
{
mainInterface.ShowStatus("Creating...");
hook = LocalHook.Create(LocalHook.GetProcAddress("kernel32.dll", "DeleteFileW"), new DeleteFileHandler(DeleteFileHookInstance), this);
mainInterface.ShowStatus("Completing...");
hook.ThreadACL.SetExclusiveACL(new int[] { 0 });
RemoteHooking.WakeUpProcess();
mainInterface.ShowStatus("OK");
}
catch (Exception ex)
{
mainInterface.ShowStatus("CreateHook failed: " + ex.Message);
System.Diagnostics.Process.GetCurrentProcess().Kill();
}
while (true) { System.Threading.Thread.Sleep(500); }
}
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
private static extern int DeleteFile(string filename);
[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode)]
private delegate int DeleteFileHandler(string filename);
private static bool deleted = false;
private int DeleteFileHookInstance(string filename)
{
if (deleted)
{
deleted = false;
return 1;
}
if (MessageBox.Show("Do you really want to delete file " + filename + "?", "Confirm delete file", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
deleted = true;
return DeleteFile(filename);
}
else return 1;
}
Please help me out, your help would be highly appreciated!
Thanks!