[VFD] Import the VFD project (Virtual Floppy Drive) which allows creating virtual
[reactos.git] / modules / rosapps / lib / vfdlib / vfdshext.cpp
diff --git a/modules/rosapps/lib/vfdlib/vfdshext.cpp b/modules/rosapps/lib/vfdlib/vfdshext.cpp
new file mode 100644 (file)
index 0000000..73f249d
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+       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;
+}
+*/