Monitoring to folders with copy hooks

zhaozj2021-02-16  43

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 final 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_root / directory / shellex / copyHookHandlers, create a type of REG_SZ in this sub key and will you The CLSID of the COM object can be used as its default value.

Below is a copy of a copy hook

// ccopyhook.h

// ccopyhook class implements the icopyhook interface, CclassFactory implements the iClassFactory interface

#include

Class CgopyHook: Public icopyHOK: PUBLIC ICOPYHOOK

{

PUBLIC:

CcopyHook (): 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 CclassFactory: Public IClassFactory: Public ICLASSFAACTORY

{

PUBLIC:

CCLASSFAACTORY (): 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;

}

// ccopyhook.cpp

// implement file for ccopyhook objects and CCLASSFActory objects

#include #include "ccopyhook.h"

Extern long nlocks; // Object count for DllcanunloadNow

Ulong __stdcall ccopyhook :: addRef () {

IF (m_refcnt == 0)

NLOCKS ;

m_refcnt ;

Return M_REFCNT;

}

Ulong __stdcall ccopyhook :: release () {

INT nnewcnt = - m_refcnt;

IF (nnewcnt <= 0) {

NLOCKS -

DELETE THIS;

}

Return nnewcnt;

}

HRESULT __STDCALL CCOPYHOK :: Queryinterface (Refiid IID, Void ** PPVObject) {

IF (IID == iid_iunknown)

* pPVObject = static_cast (this);

Else

IF (iid == iid_ishellcopyhook)

* 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 CCOPYHOOK :: CopyCallback (HWND HWND, UINT WFUNC, UINT WFLAGS,

LPCTSTSTSRCFILE, DWORD DWSRCATTRIBS,

LPCTSTSTST 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 cclassfactory :: addRef () {

IF (m_refcnt == 0)

NLOCKS ;

m_refcnt ;

Return M_REFCNT;

}

Ulong __stdcall cclassfactory :: release () {

INT nnewcnt = - m_refcnt;

IF (nnewcnt <= 0) {

NLOCKS -

DELETE THIS;

}

Return nnewcnt;

}

HRESULT __STDCALL CCLASSFAACTORY :: Queryinterface (Refiid IID, Void ** PPVObject) {

IF (IID == iid_iunknown)

* pPVObject = static_cast (this);

Else

IF (IID == iID_ICLASSFACTORY)

* pPVObject = static_cast (this);

Else

Return E_NOINTERFACE;

Reinterpret_cast (* ppvobject) -> addref (); returnide;

}

HRESULT __STDCALL CCLASSFAACTORY :: CreateInstance (IUNKNOWN * PUNKOWNOUTER, REFIID RIID, VOID ** PPVOBJ) {

IF (Punkownouter! = NULL)

RETURN CLASS_E_NOAGGREGATION;

CgopyHook * Pobj = new ccopy;

POBJ-> addRef ();

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

POBJ-> Release ();

Return HR;

}

HRESULT __STDCALL CCLASSFAACTORY :: LOCKSERVER (BOOL FLOCK) {

IF (FLOCK)

NLOCKS ;

Else

NLOCKS -

Return S_OK;

}

// main.cpp

// Mainly realize the export functions of several COM object standards.

#include

#include

#include "ccopyhook.h"

/ / 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", (const char *) - 1},

{"CLSID // {7e10A039-Fe03-4F9C-B7E1-C5eeeaf53735} // 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;

Bool apientry dllmain (Handle Hmodule,

DWORD UL_REASON_FOR_CALL,

LPVOID LPRESERVED

) {

IF (ul_reason_for_call == DLL_PROCESS_ATTACH)

Hinstance = (hmodule) hmodule;

Return True;

}

Stdapi DllunregisterServer () {

HRESULT HR = S_OK; Long Ret = 0;

Int items = sizeof (szregtable) / sizeof (szregtable [0]);

For (INT i = items-1; I> = 0; i -) {

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

IF ((i == items-1) || stricmp (SzregTable [i 1] [0], SZKEYNAME)! = 0) Ret = regdeletekey (HKEY_CLASSES_ROOT, SZKEYNAME);

IF (Ret! = Error_Success)

HR = Selfreg_e_class;

}

Return HR;

}

// Reusable DLLREGISTERSERVER function, as long as the registry key is placed in an array as long as the above format, you can // to complete the registration of any component with this code.

Stdapi DllRegisterServer (void) {

HRESULT HR = S_OK;

Int items = 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 Ret = regREATEKEY (HKEY_CLASS_ROOT, SZKEYNAME, & HKEY);

IF (RET == Error_Success) {

RegSetValueex (HKEY, SZVALUENAME, 0, REG_SZ, (const Byte *) Szvalue,

Strlen (SzValue) 1);

RegcloseKey (HKEY);

}

IF (RET! = Error_Success) {

HR = Selfreg_e_class;

DllunregisterServer ();

}

}

Return HR;

}

Stdapi DllgetClassObject (Refclsid Rclsid, Refiid Riid, Void ** PPVObj) {

HRESULT HR = E_OUTOFMEMORY;

* pPVOBJ = NULL;

CCLASSFAACTORY * PCLASSFAACTORY = New CCLASSFAACTORY;

IF (PCLASSFAACTORY! = NULL)

HR = PCLASSFAACTORY-> QueryInterface (riid, ppvobj);

Return HR;

}

Stdapi DllcanunloadNow () {

RETURN NLOCKS == 0? S_OK: S_FALSE;

}

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

New Post(0)