mirror of
https://github.com/reactos/reactos.git
synced 2025-01-07 06:45:24 +00:00
236 lines
3.9 KiB
C++
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;
|
||
|
}
|
||
|
*/
|