reactos/modules/rosapps/lib/vfdlib/vfdshext.cpp

236 lines
3.9 KiB
C++
Raw Normal View History

/*
vfdshext.cpp
Virtual Floppy Drive for Windows
Driver control library
shell extension COM shell extension class
Copyright (c) 2003-2005 Ken Kato
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#include "vfdtypes.h"
#include "vfdapi.h"
#include "vfdlib.h"
// class header
#include "vfdshext.h"
//
// Constructor
//
CVfdShExt::CVfdShExt()
{
VFDTRACE(0, ("CVfdShExt::CVfdShExt()\n"));
m_cRefCnt = 0L;
m_pDataObj = NULL;
m_nDevice = (ULONG)-1;
m_sTarget[0] = '\0';
m_bDragDrop = FALSE;
g_cDllRefCnt++;
}
//
// Destructor
//
CVfdShExt::~CVfdShExt()
{
VFDTRACE(0, ("CVfdShExt::~CVfdShExt()\n"));
if (m_pDataObj) {
m_pDataObj->Release();
}
g_cDllRefCnt--;
}
// IUnknown members
STDMETHODIMP CVfdShExt::QueryInterface(
REFIID riid,
LPVOID *ppv)
{
*ppv = NULL;
if (IsEqualIID(riid, IID_IShellExtInit) ||
IsEqualIID(riid, IID_IUnknown)) {
VFDTRACE(0,
("CVfdShExt::QueryInterface()==>IID_IShellExtInit\n"));
*ppv = (LPSHELLEXTINIT)this;
}
else if (IsEqualIID(riid, IID_IContextMenu)) {
VFDTRACE(0,
("CVfdShExt::QueryInterface()==>IID_IContextMenu\n"));
*ppv = (LPCONTEXTMENU)this;
}
else if (IsEqualIID(riid, IID_IShellPropSheetExt)) {
VFDTRACE(0,
("CVfdShExt::QueryInterface()==>IID_IShellPropSheetExt\n"));
*ppv = (LPSHELLPROPSHEETEXT)this;
}
if (*ppv) {
AddRef();
return NOERROR;
}
VFDTRACE(0,
("CVfdShExt::QueryInterface()==>Unknown Interface!\n"));
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG) CVfdShExt::AddRef()
{
VFDTRACE(0, ("CVfdShExt::AddRef()\n"));
return ++m_cRefCnt;
}
STDMETHODIMP_(ULONG) CVfdShExt::Release()
{
VFDTRACE(0, ("CVfdShExt::Release()\n"));
if (--m_cRefCnt) {
return m_cRefCnt;
}
#ifndef __REACTOS__
delete this;
#endif
return 0L;
}
// IShellExtInit members
//
// Initialize
// Called by the shell to initialize the shell extension object
//
STDMETHODIMP CVfdShExt::Initialize(
LPCITEMIDLIST pIDFolder,
LPDATAOBJECT pDataObj,
HKEY hRegKey)
{
CHAR drive = '\0';
VFDTRACE(0, ("CVfdShExt::Initialize()\n"));
UNREFERENCED_PARAMETER(hRegKey);
// Initialize can be called more than once
if (m_pDataObj) {
m_pDataObj->Release();
m_pDataObj = NULL;
}
m_nDevice = (ULONG)-1;
m_sTarget[0] = '\0';
// Get the folder name
if (SHGetPathFromIDList(pIDFolder, m_sTarget)) {
// act as a Drag-and-Drop Handler
VFDTRACE(0, ("Drag-Drop: %s\n", m_sTarget));
if (GetDriveType(m_sTarget) != DRIVE_REMOVABLE) {
VFDTRACE(0, ("Not a VFD drive\n"));
return NOERROR;
}
drive = m_sTarget[0];
m_bDragDrop = TRUE;
}
else {
// act as a context menu handler
VFDTRACE(0, ("Context menu:\n"));
m_bDragDrop = FALSE;
}
// Extract the target object name
if (pDataObj) {
STGMEDIUM medium;
FORMATETC fmt = {
CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL
};
if (SUCCEEDED(pDataObj->GetData(&fmt, &medium))) {
if (DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0)) {
DragQueryFile((HDROP)medium.hGlobal,
0, m_sTarget, sizeof(m_sTarget));
}
ReleaseStgMedium(&medium);
}
}
VFDTRACE(0, ("Target %s\n", m_sTarget));
if (!drive) {
// Contect menu handler
// -- Data object is the target drive
drive = m_sTarget[0];
}
HANDLE hDevice = VfdOpenDevice(drive);
if (hDevice == INVALID_HANDLE_VALUE) {
VFDTRACE(0, ("Not a VFD drive\n"));
return NOERROR;
}
ULONG ret = VfdGetDeviceNumber(hDevice, &m_nDevice);
CloseHandle(hDevice);
if (ret != ERROR_SUCCESS) {
m_nDevice = (ULONG)-1;
return NOERROR;
}
VFDTRACE(0, ("VFD device %d\n", m_nDevice));
// Store the data object
m_pDataObj = pDataObj;
m_pDataObj->AddRef();
return NOERROR;
}
/*
STDMETHODIMP CVfdShExt::GetInfoFlags(
DWORD *pdwFlags)
{
VFDTRACE(0, ("CVfdShExt::GetInfoFlags\n"));
*pdwFlags = 0;
return NOERROR;
}
STDMETHODIMP CVfdShExt::GetInfoTip(
DWORD dwFlags,
LPWSTR *ppwszTip)
{
VFDTRACE(0, ("CVfdShExt::GetInfoTip\n"));
*ppwszTip = NULL;
return NOERROR;
}
*/