1 /* 2 vfdshext.cpp 3 4 Virtual Floppy Drive for Windows 5 Driver control library 6 shell extension COM shell extension class 7 8 Copyright (c) 2003-2005 Ken Kato 9 */ 10 11 #define WIN32_LEAN_AND_MEAN 12 #include <windows.h> 13 #include <shellapi.h> 14 #include <shlobj.h> 15 16 #include "vfdtypes.h" 17 #include "vfdapi.h" 18 #include "vfdlib.h" 19 20 // class header 21 #include "vfdshext.h" 22 23 // 24 // Constructor 25 // 26 CVfdShExt::CVfdShExt() 27 { 28 VFDTRACE(0, ("CVfdShExt::CVfdShExt()\n")); 29 30 m_cRefCnt = 0L; 31 m_pDataObj = NULL; 32 m_nDevice = (ULONG)-1; 33 m_sTarget[0] = '\0'; 34 m_bDragDrop = FALSE; 35 36 g_cDllRefCnt++; 37 } 38 39 // 40 // Destructor 41 // 42 CVfdShExt::~CVfdShExt() 43 { 44 VFDTRACE(0, ("CVfdShExt::~CVfdShExt()\n")); 45 46 if (m_pDataObj) { 47 m_pDataObj->Release(); 48 } 49 50 g_cDllRefCnt--; 51 } 52 53 // IUnknown members 54 55 STDMETHODIMP CVfdShExt::QueryInterface( 56 REFIID riid, 57 LPVOID *ppv) 58 { 59 *ppv = NULL; 60 61 if (IsEqualIID(riid, IID_IShellExtInit) || 62 IsEqualIID(riid, IID_IUnknown)) { 63 VFDTRACE(0, 64 ("CVfdShExt::QueryInterface()==>IID_IShellExtInit\n")); 65 66 *ppv = (LPSHELLEXTINIT)this; 67 } 68 else if (IsEqualIID(riid, IID_IContextMenu)) { 69 VFDTRACE(0, 70 ("CVfdShExt::QueryInterface()==>IID_IContextMenu\n")); 71 72 *ppv = (LPCONTEXTMENU)this; 73 } 74 else if (IsEqualIID(riid, IID_IShellPropSheetExt)) { 75 VFDTRACE(0, 76 ("CVfdShExt::QueryInterface()==>IID_IShellPropSheetExt\n")); 77 78 *ppv = (LPSHELLPROPSHEETEXT)this; 79 } 80 81 if (*ppv) { 82 AddRef(); 83 84 return NOERROR; 85 } 86 87 VFDTRACE(0, 88 ("CVfdShExt::QueryInterface()==>Unknown Interface!\n")); 89 90 return E_NOINTERFACE; 91 } 92 93 STDMETHODIMP_(ULONG) CVfdShExt::AddRef() 94 { 95 VFDTRACE(0, ("CVfdShExt::AddRef()\n")); 96 97 return ++m_cRefCnt; 98 } 99 100 STDMETHODIMP_(ULONG) CVfdShExt::Release() 101 { 102 VFDTRACE(0, ("CVfdShExt::Release()\n")); 103 104 if (--m_cRefCnt) { 105 return m_cRefCnt; 106 } 107 108 #ifndef __REACTOS__ 109 delete this; 110 #endif 111 112 return 0L; 113 } 114 115 // IShellExtInit members 116 117 // 118 // Initialize 119 // Called by the shell to initialize the shell extension object 120 // 121 STDMETHODIMP CVfdShExt::Initialize( 122 LPCITEMIDLIST pIDFolder, 123 LPDATAOBJECT pDataObj, 124 HKEY hRegKey) 125 { 126 CHAR drive = '\0'; 127 128 VFDTRACE(0, ("CVfdShExt::Initialize()\n")); 129 130 UNREFERENCED_PARAMETER(hRegKey); 131 132 // Initialize can be called more than once 133 134 if (m_pDataObj) { 135 m_pDataObj->Release(); 136 m_pDataObj = NULL; 137 } 138 139 m_nDevice = (ULONG)-1; 140 m_sTarget[0] = '\0'; 141 142 // Get the folder name 143 if (SHGetPathFromIDList(pIDFolder, m_sTarget)) { 144 145 // act as a Drag-and-Drop Handler 146 147 VFDTRACE(0, ("Drag-Drop: %s\n", m_sTarget)); 148 149 if (GetDriveType(m_sTarget) != DRIVE_REMOVABLE) { 150 VFDTRACE(0, ("Not a VFD drive\n")); 151 return NOERROR; 152 } 153 154 drive = m_sTarget[0]; 155 m_bDragDrop = TRUE; 156 } 157 else { 158 159 // act as a context menu handler 160 161 VFDTRACE(0, ("Context menu:\n")); 162 m_bDragDrop = FALSE; 163 } 164 165 // Extract the target object name 166 167 if (pDataObj) { 168 169 STGMEDIUM medium; 170 FORMATETC fmt = { 171 CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL 172 }; 173 174 if (SUCCEEDED(pDataObj->GetData(&fmt, &medium))) { 175 if (DragQueryFile((HDROP)medium.hGlobal, (UINT)-1, NULL, 0)) { 176 177 DragQueryFile((HDROP)medium.hGlobal, 178 0, m_sTarget, sizeof(m_sTarget)); 179 } 180 181 ReleaseStgMedium(&medium); 182 } 183 } 184 185 VFDTRACE(0, ("Target %s\n", m_sTarget)); 186 187 if (!drive) { 188 // Contect menu handler 189 // -- Data object is the target drive 190 drive = m_sTarget[0]; 191 } 192 193 HANDLE hDevice = VfdOpenDevice(drive); 194 195 if (hDevice == INVALID_HANDLE_VALUE) { 196 VFDTRACE(0, ("Not a VFD drive\n")); 197 return NOERROR; 198 } 199 200 ULONG ret = VfdGetDeviceNumber(hDevice, &m_nDevice); 201 202 CloseHandle(hDevice); 203 204 if (ret != ERROR_SUCCESS) { 205 m_nDevice = (ULONG)-1; 206 return NOERROR; 207 } 208 209 VFDTRACE(0, ("VFD device %d\n", m_nDevice)); 210 // Store the data object 211 212 m_pDataObj = pDataObj; 213 m_pDataObj->AddRef(); 214 215 return NOERROR; 216 } 217 218 /* 219 STDMETHODIMP CVfdShExt::GetInfoFlags( 220 DWORD *pdwFlags) 221 { 222 VFDTRACE(0, ("CVfdShExt::GetInfoFlags\n")); 223 *pdwFlags = 0; 224 return NOERROR; 225 } 226 227 STDMETHODIMP CVfdShExt::GetInfoTip( 228 DWORD dwFlags, 229 LPWSTR *ppwszTip) 230 { 231 VFDTRACE(0, ("CVfdShExt::GetInfoTip\n")); 232 *ppwszTip = NULL; 233 return NOERROR; 234 } 235 */ 236