Monitoring to folders with copy hooks

zhaozj2021-02-16  82

This article is not known. Original: Webber84, modified by ccrun (old demon) and passed in BCB.

ICopyHook is a COM interface for creating a copy hook handler, which determines whether a folder or printer object can be moved, copied, renamed or delete. SHELL CopyCallback method that calls the ICOPYHOOK interface is verified before performing these operations. CopyCallback returns an int value indicates whether the shell should continue to do this. Return value idyes indicates that the return value IDNO and IDCANCEL are terminated.

A folder object can be installed with multiple copy hook handles. If this happens, the shell will call each handler again. Only when each handler returns iDyes, the shell actually performs the operation of the user request.

The role of the copy hook handler is to verify them before the above four operations are performed, but the shell does not notify the result of the operation to the copy hook handler. The API function provided by Windows FindFirstChangeNotification and FindNextChangeNotification can implement this feature. Therefore, only the two methods are combined to make full monitoring of a folder.

Copy the hook handler is not difficult, first create a COM object as a component within the process, it only needs to expose an icopyhook interface (of course IUNKNOWN). The COM component is then registered with Regsrv32.exe. The last step is to register your copy hook handler to the shell. The method is to create a name of any Sub Key under the registry hkey_classes_rootdirectoryShellexCopyHookHandlers. Create a type of REG_SZ in this sub key and use the CLSID of your COM object. Its default value is OK.

Below is a copy of a copy hook (Note: The following code is modified by the old demon and adding the detailed operation process, successfully compiling and passed the test) in BCB6.

1. Create TcopyHook from the iCopyHook interface, create TclassFactory from the iClassFactory interface:

// tcopyhook.h

// TcopyHook class implements the icopyhook interface, TclassFactory implements the iClassFactory interface

/ / -------------------------------------------------------------------------------------------- ---------------------------

#DEFINE NO_WIN32_LEAN_AND_MEAN

#include

/ / -------------------------------------------------------------------------------------------- ---------------------------

Class TcopyHook: Public icopyHOK: PUBLIC icopy

{

PUBLIC:

TcopyHook (): m_refcnt (0) {}

STDMETHODIMP Queryinterface (Refiid IID, Void ** PPVObject);

STDMETHODIMP_ (ULONG) AddRef ();

STDMETHODIMP_ (ULONG) Release ();

STDMETHODIMP_ (UINT) COPYCALLBACK (HWND HWND, UINT WFUNC, UINT WFLAGS,

LPCTSTSTSRCFILE, DWORD DWSRCATTRIBS,

LPCTSTSTR PSZDESTFILE, DWORD DWDESTATTRIBS;

Private:

INT M_REFCNT;

}

/ / -------------------------------------------------------------------------------------------- --------------------------- Class TclassFactory: Public iClassFactory

{

PUBLIC:

TclassFactory (): m_refcnt (0) {}

STDMETHODIMP Queryinterface (Refiid IID, Void ** PPVObject);

STDMETHODIMP_ (ULONG) AddRef ();

STDMETHODIMP_ (ULONG) Release ();

Stdmethodimp CreateInstance (IUNKNOWN * PUNKOUTER, REFIID RIID, Void ** PPVObject);

STDMETHODIMP LOCKSERVER (BOOL FLOCK);

Private:

INT M_REFCNT;

}

// TcopyHOK.cpp

// TCOPYHOK object and TclassFactory object implementation file

#include

#include "tcopyhook.h"

/ / -------------------------------------------------------------------------------------------- ---------------------------

Extern long nlocks; // Object count for DllcanunloadNow

Ulong __stdcall tcopyhook :: addRef ()

{

IF (m_refcnt == 0)

NLOCKS ;

m_refcnt ;

Return M_REFCNT;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

Ulong __stdcall tcopyhotyHook :: release ()

{

INT nnewcnt = --m_refcnt;

IF (nnewcnt <= 0)

{

NLOCKS -

DELETE THIS;

}

Return nnewcnt;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

HRESULT __STDCALL TCOPYHOK :: queryinterface (Refiid dwiid, void ** ppvobject)

{

IF (dwiid == iid_iunknown)

* pPVObject = static_cast (this);

Else

IF (dwiid == iid_ishellcopy)

* pPVObject = static_cast (this);

Else

Return E_NOINTERFACE;

Reinterpret_cast (* ppvobject) -> addref ();

Return S_OK;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// This is the CopyCallback method, all functions of copy hooks are implemented by it. Specific value for parameters See MSDN

UINT __STDCALL TCOPYHOK :: CopyCallback (HWND HWND, UINT WFUNC, UINT WFLAGS,

LPCTSTSTR PSZSRCFILE, DWORD DWSRCATTRIBS, LPCTSTR PSZDESTFILE, DWORD DWDESTATTRIBS

{

Char Szmessage [MAX_PATH 14];

Sprintf (Szmessage, "Do you continue?", pszsrcfile;

Return MessageBox (NULL, SZMESSAGE, "Confirm", MB_YESNO | MB_ICONEXCLAMATION

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

Ulong __stdcall tclassfactory :: addRef ()

{

IF (m_refcnt == 0)

NLOCKS ;

m_refcnt ;

Return M_REFCNT;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

Ulong __stdcall tclassfactory :: release ()

{

INT nnewcnt = --m_refcnt;

IF (nnewcnt <= 0)

{

NLOCKS -

DELETE THIS;

}

Return nnewcnt;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

HRESULT __STDCALL TCLASSFAACTORY :: Queryinterface (Refiid Dwiid, Void ** PPVObject)

{

IF (dwiid == iid_iunknown)

* pPVObject = static_cast (this);

Else

IF (dwiid == iid_iclassfactory)

* pPVObject = static_cast (this);

Else

Return E_NOINTERFACE;

Reinterpret_cast (* ppvobject) -> addref ();

Return S_OK;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

HRESULT __STDCALL TCLASSFAACTORY :: CreateInstance (IUNKNOWN * Punkownouter,

Refiid riid, void ** ppvobj)

{

IF (Punkownouter! = NULL)

RETURN CLASS_E_NOAGGREGATION;

TcopyHook * pobj = new tcopy;

POBJ-> addRef ();

HRESULT HR = POBJ-> QueryInterface (RIID, PPVOBJ);

POBJ-> Release ();

Return HR;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

HRESULT __STDCALL TCLASSFAACTORY :: LOCKSERVER (BOOL FLOCK)

{

IF (FLOCK)

NLOCKS ;

Else

NLOCKS -

Return S_OK;

}

2. New -> ActiveX -> ActiveX Library in BCB, then add the corresponding code.

/ / -------------------------------------------------------------------------------------------- ----------------

// Original: Webber84

// Modify: ccrun (www.ccrun.com)

// Welcome to C Builder Research: http://www.ccrun.com

/ / In order to prevent irresponsible reprivers, add the original author and modified information, please forgive me.

/ / -------------------------------------------------------------------------------------------- ----------------

The following is the modified Project1.cpp, you can directly copy. :

// $$ ---- AXLIB Proj Source ---- (staxlibprojectsource)

#DEFINE NO_WIN32_LEAN_AND_MEAN

#include

#pragma HDRSTOP

#include

#include

#include

#include "tcopyhook.h"

#pragma package (smart_init)

Tcommodule Project1Module;

Tcommodule & _Module = Project1Module;

/ / This is the item to add to the registry. Note If you want to use this code, you should use uuidgen.exe to generate one

// new CLSID.

Const char * szregtable [] [3] =

{

{"CLSID / {7e10A039-Fe03-4F9C-B7E1-C5eeeaf53735}", 0, "CopyHook"},

{"CLSID / {7E10A039-Fe03-4F9C-B7E1-C5eeeaf53735} / inprocserver32", 0, (const char *) - 1},

{"CLSID / {7E10A039-Fe03-4F9C-B7E1-C5eeeeaf53735} / inprocserver32", "threadingmodel", "Apartment"},

{"CLSID / {7e10A039-Fe03-4F9C-B7E1-C5eeeaf53735} / progid", 0, "Webber84.copyHook.1"}

{"Webber84.copyHook.1", 0, "copyhook"},

{"Webber84.copyHook.1 / CLSID", 0, "{7e10A039-Fe03-4F9C-B7E1-C5EEEAF53735}"}

}

HModule Hinstance = NULL;

Long nlocks = 0;

/ / -------------------------------------------------------------------------------------------- ---------------------------

// The ATL Object Map Holds An Array of _tl_Objmap_ENTRY STRUCTURES THAT

// Described The Objects of Your Ole Server. The map is handed to your

// Project's ccommodule-derived _Module Object via the init method.begin_Object_map (Objectmap)

END_OBJECT_MAP ()

/ / -------------------------------------------------------------------------------------------- ---------------------------

// entry point of your server invoked by Windows for Processes or Threads Are

// Initialized or Terminated.

Int WinAPI DLLENTRYPOINT (Hinstance Hinst, Unsigned Long Reason, Void *)

{

IF (REASON == DLL_PROCESS_ATTACH)

Hinstance = (hmodule) hinst;

Return True;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// _Module.Term is type_process_detach of your roll

// DLLENTRYPOINT. HOWEVER, THIS May Result in An IncorRect Shutdown Sequence.

// instead an exit routine is setup to invoke the cleanup routine

// ccommodule :: Term.

Void Moduleterm (Void)

{

_Module.Term ();

}

#pragma EXIT MODULETERM 63

/ / -------------------------------------------------------------------------------------------- ---------------------------

// entry point of your server invoked to inquire WHETHER THE DLL IS NO

// Longer in Use and shop be unloaded.

StDAPI __Export DllcanunloadNow (Void)

{

RETURN NLOCKS == 0? S_OK: S_FALSE;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// Entry Point of Your Server ALLOWING OLE TO RETRIEVE A CLASS OBJECT

// Your Server

StDAPI __EXPORT DLLGETCLASSOBJECT (Refclsid Rclsid, Refiid Riid, LPVOID * PPV)

{

HRESULT HR = E_OUTOFMEMORY;

* ppv = NULL;

TclassFactory * pclassfactory = new tclassfactory;

IF (PCLASSFAACTORY! = NULL)

HR = PCLASSFAACTORY-> QueryInterface (RIID, PPV);

Return HR;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// entry point of your server invoked to instruct the server to create // registry entries for all classes supported by the module

Stdapi __export dllregisterServer (void)

{

HRESULT HR = S_OK;

INT NITEMS = SizeOf (szregtable) / sizeof (szregtable [0]);

CHAR SZDLLPATH [MAX_PATH];

GetModuleFileName (Hinstance, SzdllPath, Max_Path);

For (int i = 0; i

{

Const char * szkeyname = szregtable [i] [0];

Const char * szvaluename = szregtable [i] [1];

Const char * szvalue = szregtable [i] [2];

IF (SzValue == (const char *) - 1)

Szvalue = szdllpath;

HKEY HKEY;

Long Lreturn = RegcreateKey (hkey_classes_root, szkeyname, & hkey);

IF (LRETURN == Error_Success)

{

RegSetValueex (HKEY, SZVALUENAME, 0, REG_SZ,

(const Byte *) Szvalue, Strlen (SzValue) 1);

RegcloseKey (HKEY);

}

IF (Lreturn! = Error_Success)

{

HR = Selfreg_e_class;

DllunregisterServer ();

}

}

Return HR;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

// entry point of your server invoked to instruct the server to remove, INSTRUCT

// All Registry Entries Created THROUGH DLLREGISTERSERVER.

Stdapi __export dllunregisterServer (void)

{

HRESULT HR = S_OK;

Long Lreturn = 0;

INT NITEMS = SizeOf (szregtable) / sizeof (szregtable [0]);

For (int i = nitems-1; i> = 0; I -)

{

Const char * szkeyname = szregtable [i] [0];

IF ((i == Nitems-1) || stricmp (SzregTable [i 1] [0], SZKEYNAME)! = 0)

Lreturn = regdeleteKey (HKEY_CLASES_ROOT, SZKEYNAME);

IF (Lreturn! = Error_Success)

HR = Selfreg_e_class;

}

Return HR;

}

/ / -------------------------------------------------------------------------------------------- ---------------------------

3. In the BCB IDE environment, select the project -> Add to Project -> of the menu, find the TcopyHook.cpp -> OK compilation project created. If there is no error, Project1.dll will be generated.

4. Modify the registry:

Create a new item under HKEY_CLASSES_ROOTDIRECTORYSHELLEXCOPYHOKHANDLERS, name TEST, change its default value to {7e10A039-FE03-4F9C-B7E1-C5eeeAf53735}, old demon: The default value should be the same as the same registration item in Project1.cpp.

5. Register COM components:

Run the regsvr32.exe path Project.dll, click OK, do not pay back the wrong window. Restart your computer, try a copy of a folder, when Paste is, it is okay, hehe. Try it yourself.

Source code download:

http://www.ccrun.com/cctools/mycopyhook.rar

转载请注明原文地址:https://www.9cbs.com/read-12346.html

New Post(0)