reactos/modules/rosapps/lib/vfdlib/vfdshext.cpp
Pierre Schweitzer 25c7e1a8d0
[VFD] Import the VFD project (Virtual Floppy Drive) which allows creating virtual
floppy drives in ReactOS and mount images on them.
Only the cmd got imported. The GUI interface may come later on.
Note that, as for vcdrom, the driver is left disabled and you need to explicitely
start it through vfd command line interface.

CORE-14090
2017-12-16 21:48:34 +01:00

236 lines
3.9 KiB
C++

/*
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;
}
*/