⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qdrive.cpp

📁 Drive.dll is a dll that creates a drive to system directoryor drive similar to existing drives such
💻 CPP
字号:
//
// QDrive.cpp : Defines the DLL's Entry point and Self-registration code

#define INC_OLE2

#include <windows.h>
#include <initguid.h>
// #define _WIN32_IE as 0x0400 if you want ShellVersion 4.71 specific interfaces
// to be declared in shlobj.h
#include <shlobj.h>
#include <tchar.h>
#include <stdlib.h>
#include "QDrive.h"
#include "ShellFolder.h"
#include "resource.h"
#include "ContextMenu.h"
//
// Global variables
//
UINT		g_uiRefThisDll = 0;		// Reference count for this DLL
HINSTANCE	g_hInstance;			// Instance handle for this DLL
HIMAGELIST	g_hImageListSmall = NULL;
HIMAGELIST	g_hImageListLarge = NULL;
void createImageLists(); 

class CQDriveClassFactory : public IClassFactory
{
protected:
	ULONG   m_ulRef;         // Object reference count
public:
	CQDriveClassFactory();
	~CQDriveClassFactory();
        
    // IUnknown methods
	STDMETHODIMP            QueryInterface (REFIID, LPVOID FAR *);
	STDMETHODIMP_(ULONG)    AddRef ();
	STDMETHODIMP_(ULONG)    Release ();
    
	// IClassFactory methods
	STDMETHODIMP    CreateInstance (LPUNKNOWN, REFIID, LPVOID FAR *);
	STDMETHODIMP    LockServer (BOOL);
};

extern "C" int APIENTRY DllMain (HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		g_hInstance = hInstance;
		createImageLists();
	}
	return TRUE;
}

// Helper functions
// TODO : Modify to suit your needs
void createImageLists()
{
	int nSmallCx = GetSystemMetrics(SM_CXSMICON);
	int nSmallCy = GetSystemMetrics(SM_CYSMICON);

	if(g_hImageListSmall)
	{
		ImageList_Destroy(g_hImageListSmall);
	}

	//set the small image list
	g_hImageListSmall = ImageList_Create(nSmallCx, nSmallCy, ILC_COLORDDB | ILC_MASK, 4, 0);

	if(g_hImageListSmall)
	{
		HICON hIcon;

		hIcon = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_ICON_ROOT), 
								IMAGE_ICON, nSmallCx, nSmallCy, LR_DEFAULTCOLOR);
		ImageList_AddIcon(g_hImageListSmall, hIcon);

		hIcon = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_ICON_FOLDER_CLOSE), 
								IMAGE_ICON, nSmallCx, nSmallCy, LR_DEFAULTCOLOR);
		ImageList_AddIcon(g_hImageListSmall, hIcon);
	}

	if(g_hImageListLarge)
	{
		ImageList_Destroy(g_hImageListLarge);
	}

	int nCx = GetSystemMetrics(SM_CXICON);
	int nCy = GetSystemMetrics(SM_CYICON);

	//set the large image list
	g_hImageListLarge = ImageList_Create(nCx, nCy, ILC_COLORDDB | ILC_MASK, 4, 0);

	if(g_hImageListSmall)
	{
		HICON hIcon;

		hIcon = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_ICON_ROOT), 
								IMAGE_ICON, nCx, nCy, LR_DEFAULTCOLOR);
		ImageList_AddIcon(g_hImageListLarge, hIcon);

		hIcon = (HICON)LoadImage(g_hInstance, MAKEINTRESOURCE(IDI_ICON_FOLDER_CLOSE), 
								IMAGE_ICON, nCx, nCy, LR_DEFAULTCOLOR);
		ImageList_AddIcon(g_hImageListLarge, hIcon);
	}
}

STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID *ppv)
{
	*ppv = NULL;

	if (!IsEqualCLSID (rclsid, CLSID_Shell_Extension_QDrive))
	{
		return ResultFromScode (CLASS_E_CLASSNOTAVAILABLE);
	}
    
	CQDriveClassFactory *pClassFactory = new CQDriveClassFactory;

	if (pClassFactory == NULL)
	{
		return ResultFromScode (E_OUTOFMEMORY);
	}

	HRESULT hr = pClassFactory->QueryInterface (riid, ppv);
	pClassFactory->Release ();
	return hr;
}

STDAPI DllCanUnloadNow (void)
{
	return ResultFromScode ((g_uiRefThisDll == 0) ? S_OK : S_FALSE);
}

#define SZ_CLSID				_T("CLSID\\{A79EBF22-97C6-11d2-A6CA-204C4F4F5020}")
#define SZ_INPROCSERVER32		_T("CLSID\\{A79EBF22-97C6-11d2-A6CA-204C4F4F5020}\\InprocServer32")
#define SZ_DEFAULT				_T("")
#define SZ_DEFAULTICON			_T("CLSID\\{A79EBF22-97C6-11d2-A6CA-204C4F4F5020}\\DefaultIcon")
#define SZ_THREADINGMODEL		_T("ThreadingModel")
#define SZ_APARTMENT			_T("Apartment")
#define SZ_SHELLFOLDER			_T("CLSID\\{A79EBF22-97C6-11d2-A6CA-204C4F4F5020}\\ShellFolder")
#define SZ_ATTRIBUTES			_T("Attributes")
#define SZ_APPROVED				_T("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved")
#define SZ_ERRMSG				_T("Unable to add ClassId {A79EBF22-97C6-11d2-A6CA-204C4F4F5020} to Registry\nAdministrative Privileges Needed")
#define SZ_ERROR				_T("Error")
#define SZ_SHELLEX				_T("CLSID\\{A79EBF22-97C6-11d2-A6CA-204C4F4F5020}\\shellex")
#define SZ_SHELLEX_CTX			_T("CLSID\\{A79EBF22-97C6-11d2-A6CA-204C4F4F5020}\\shellex\\ContextMenuHandlers")
#define SZ_CTXMENUHDLR			_T("CLSID\\{A79EBF22-97C6-11d2-A6CA-204C4F4F5020}\\shellex\\ContextMenuHandlers\\{A79EBF22-97C6-11d2-A6CA-204C4F4F5020}")
#define SZ_NAMESPACE_DT			_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Desktop\\Namespace\\{A79EBF22-97C6-11d2-A6CA-204C4F4F5020}")
STDAPI DllRegisterServer(void)
{
	HRESULT hr = E_UNEXPECTED;

	static TCHAR szDescr[] = _T("Q:\\");

	TCHAR szFilePath[_MAX_PATH];
	GetModuleFileName(g_hInstance, szFilePath, _MAX_PATH);
	
	// Create SZ_CLSID
	HKEY hKeyCLSID = NULL;
	if (::RegCreateKey(HKEY_CLASSES_ROOT, SZ_CLSID, &hKeyCLSID) != ERROR_SUCCESS)
	{
		return E_UNEXPECTED;	// No point in continuing further
	}
	if (::RegSetValueEx(hKeyCLSID, SZ_DEFAULT, 0, REG_SZ,  (const BYTE*)szDescr, 
				(lstrlen(szDescr)+1) * sizeof(TCHAR)) != ERROR_SUCCESS)
	{
		return E_UNEXPECTED;	// No point in continuing further
	}
	::RegCloseKey(hKeyCLSID);

	HKEY hkeyInprocServer32 = NULL;
	if (::RegCreateKey(HKEY_CLASSES_ROOT, SZ_INPROCSERVER32, &hkeyInprocServer32) == ERROR_SUCCESS)
	{
		static TCHAR szApartment[] = SZ_APARTMENT;
		if (::RegSetValueEx(hkeyInprocServer32, SZ_DEFAULT, 0, REG_SZ, 
				(const BYTE*)szFilePath, (lstrlen(szFilePath)+1) * sizeof(TCHAR)) == ERROR_SUCCESS)
		{
			if (::RegSetValueEx(hkeyInprocServer32, SZ_THREADINGMODEL, 0, REG_SZ, 
				(const BYTE*)szApartment, (lstrlen(szApartment)+1) * sizeof(TCHAR)) == ERROR_SUCCESS)
			{
				hr = S_OK;
			}
		}
		::RegCloseKey(hkeyInprocServer32);
	}

	// Set the default icon for the NameSpace extension folder
	HKEY hkeyDefaultIcon = NULL;
	if (::RegCreateKey(HKEY_CLASSES_ROOT, SZ_DEFAULTICON, &hkeyDefaultIcon) == ERROR_SUCCESS)
	{
		static TCHAR szDefaultIcon[MAX_PATH];
		strcpy(szDefaultIcon, szFilePath);
		strcat(szDefaultIcon, ",0");
		if (::RegSetValueEx(hkeyDefaultIcon, SZ_DEFAULT, 0, REG_SZ, 
				(const BYTE*)szDefaultIcon, (lstrlen(szDefaultIcon)+1) * sizeof(TCHAR)) == ERROR_SUCCESS)
		{
			hr = S_OK;
		}
		::RegCloseKey(hkeyDefaultIcon);
	}
	else
	{
		hr = E_UNEXPECTED;
	}

	HKEY hKeyApproved = NULL;
	LONG lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, SZ_APPROVED, 0, KEY_SET_VALUE, &hKeyApproved);
	if (lRet == ERROR_ACCESS_DENIED)
	{
		MessageBox(NULL, SZ_ERRMSG, SZ_ERROR, MB_OK);
		hr = E_UNEXPECTED;
	}
	else if (lRet == ERROR_FILE_NOT_FOUND)
	{
		// Its okay.. The key doesn't exist. May be its Win95/98 or older verion of NT
	}
	if (hKeyApproved)
	{
		if (RegSetValueEx(hKeyApproved, SZ_GUID, 0, REG_SZ, 
			(const BYTE*) szDescr, (lstrlen(szDescr) + 1) * sizeof(TCHAR)) == ERROR_SUCCESS)
		{
			hr = S_OK;
		}
		else
		{
			hr = E_UNEXPECTED;
		}
	}
	
	// create SZ_NAMESPACE_DT
	HKEY hKeyNameSpaceDT = NULL;
	if (::RegCreateKey(HKEY_LOCAL_MACHINE, SZ_NAMESPACE_DT,
					&hKeyNameSpaceDT) == ERROR_SUCCESS)
	{
		if (::RegSetValueEx(hKeyNameSpaceDT, SZ_DEFAULT, 0, REG_SZ, 
				(const BYTE*)szDescr, (lstrlen(szDescr)+1) * sizeof(TCHAR)) == ERROR_SUCCESS)
		{
			hr &= S_OK;
		}
		else
		{
			hr &= E_UNEXPECTED;
		}
		::RegCloseKey(hKeyNameSpaceDT);
	}
	// Register ShellFolder Attributes
	HKEY hKeyShellFolder = NULL;
	DWORD dwDisposition = 0;
	if (::RegCreateKeyEx(HKEY_CLASSES_ROOT, SZ_SHELLFOLDER, NULL, NULL,
						REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKeyShellFolder,
						&dwDisposition) == ERROR_SUCCESS)
	{
		DWORD dwAttr = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DROPTARGET;
		if (::RegSetValueEx(hKeyShellFolder, SZ_ATTRIBUTES, 0, REG_BINARY, 
				(LPBYTE)&dwAttr, sizeof(dwAttr)) == ERROR_SUCCESS)
		{
			hr = S_OK;
		}
		else
		{
			hr = E_UNEXPECTED;
		}
		::RegCloseKey(hKeyShellFolder);
	}
	// Register context menu handler
	// create SZ_CTXMENUHDLR
	HKEY hKeyCtxMenuHdlr = NULL;
	if (::RegCreateKey(HKEY_CLASSES_ROOT, SZ_CTXMENUHDLR, &hKeyCtxMenuHdlr) != ERROR_SUCCESS)
	{
		hr = E_UNEXPECTED;
	}
	::RegCloseKey(hKeyCtxMenuHdlr);
	//TODO: Add extra registrations here.. like HKCR\\.MyExt etc
	return hr;
}

STDAPI DllUnregisterServer(void)
{
	HRESULT hr = E_UNEXPECTED;

	::RegDeleteKey(HKEY_CLASSES_ROOT, SZ_INPROCSERVER32);
	::RegDeleteKey(HKEY_CLASSES_ROOT, SZ_DEFAULTICON);
	::RegDeleteKey(HKEY_CLASSES_ROOT, SZ_CTXMENUHDLR);
	::RegDeleteKey(HKEY_CLASSES_ROOT, SZ_SHELLEX_CTX);
	::RegDeleteKey(HKEY_CLASSES_ROOT, SZ_SHELLEX);
	::RegDeleteKey(HKEY_CLASSES_ROOT, SZ_SHELLFOLDER);
	if (::RegDeleteKey(HKEY_CLASSES_ROOT, SZ_CLSID) == ERROR_SUCCESS)
	{
		hr = S_OK;
	}
	HKEY hKeyApproved = NULL;
	LONG lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, SZ_APPROVED, 0, KEY_SET_VALUE, &hKeyApproved);
	if (lRet == ERROR_ACCESS_DENIED)
	{
		MessageBox(NULL, SZ_ERRMSG, SZ_ERROR, MB_OK);
		hr = E_UNEXPECTED;
	}
	else if (lRet == ERROR_FILE_NOT_FOUND)
	{
		// Its okay.. The key doesn't exist. May be its Win95 or older verion of NT
	}
	if (hKeyApproved)
	{
		if (::RegDeleteValue(hKeyApproved, SZ_GUID) != ERROR_SUCCESS)
		{
			hr &= E_UNEXPECTED;
		}
		::RegCloseKey(hKeyApproved);
	}
	// create SZ_NAMESPACE_DT
	::RegDeleteKey(HKEY_LOCAL_MACHINE, SZ_NAMESPACE_DT);

	return hr;
}

///////////////////////////////////////////////////////////
// CQDriveClassFactory member functions
CQDriveClassFactory::CQDriveClassFactory()
{
	m_ulRef = 1;
	g_uiRefThisDll++;
}

CQDriveClassFactory::~CQDriveClassFactory()
{
	g_uiRefThisDll--;
}

///////////////////////////////////////////////////////////
// IUnknown implementation
//
STDMETHODIMP CQDriveClassFactory::QueryInterface (REFIID riid, LPVOID FAR *ppv)
{
	if (IsEqualIID (riid, IID_IUnknown)) 
	{
		*ppv = (LPUNKNOWN) (LPCLASSFACTORY) this;
		m_ulRef++;
		return NOERROR;
	}

	else if (IsEqualIID (riid, IID_IClassFactory)) 
	{
		*ppv = (LPCLASSFACTORY) this;
		m_ulRef++;
		return NOERROR;
	}
	else 
	{  
		*ppv = NULL;
		return ResultFromScode (E_NOINTERFACE);
	}
}

STDMETHODIMP_(ULONG) CQDriveClassFactory::AddRef ()
{
	return ++m_ulRef;
}

STDMETHODIMP_(ULONG) CQDriveClassFactory::Release ()
{
	if (--m_ulRef == 0)
	{
		delete this;
	}
	return m_ulRef;
}

STDMETHODIMP CQDriveClassFactory::CreateInstance (LPUNKNOWN pUnkOuter, REFIID riid,
    LPVOID FAR *ppvObj)
{
    *ppvObj = NULL;

    //
    // Return an error code if pUnkOuter is not NULL, because we don't
    // support aggregation.
    //
    if (pUnkOuter != NULL)
        return ResultFromScode (CLASS_E_NOAGGREGATION);

	//
	// Instantiate a ContextMenu extension this ShellFolder supports.
	//
	if (IsEqualIID (riid, IID_IShellExtInit)) 
	{
		CContextMenu *pCtxMenu = new CContextMenu(NULL, 0, NULL);
		if (NULL == pCtxMenu)
		{
			return E_OUTOFMEMORY;
		}
		HRESULT hr = pCtxMenu->QueryInterface(riid, ppvObj);
		
		pCtxMenu->Release();
		return hr;
	}
	else if (IsEqualIID (riid, IID_IContextMenu)) 
	{
		*ppvObj = (LPCONTEXTMENU) this;
		m_ulRef++;
		return NOERROR;
	}
	CShellFolder *pShellFolder = new CShellFolder(NULL, NULL);
	if(NULL == pShellFolder)
	{
		return E_OUTOFMEMORY;
	}
	HRESULT hr = pShellFolder->QueryInterface(riid, ppvObj);
	pShellFolder->Release();
	return hr;
}

STDMETHODIMP CQDriveClassFactory::LockServer (BOOL fLock)
{
	return ResultFromScode (E_NOTIMPL);
}

//EOF

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -