Reactos
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//
26CVfdShExt::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//
42CVfdShExt::~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
55STDMETHODIMP 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
93STDMETHODIMP_(ULONG) CVfdShExt::AddRef()
94{
95 VFDTRACE(0, ("CVfdShExt::AddRef()\n"));
96
97 return ++m_cRefCnt;
98}
99
100STDMETHODIMP_(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//
121STDMETHODIMP 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/*
219STDMETHODIMP CVfdShExt::GetInfoFlags(
220 DWORD *pdwFlags)
221{
222 VFDTRACE(0, ("CVfdShExt::GetInfoFlags\n"));
223 *pdwFlags = 0;
224 return NOERROR;
225}
226
227STDMETHODIMP CVfdShExt::GetInfoTip(
228 DWORD dwFlags,
229 LPWSTR *ppwszTip)
230{
231 VFDTRACE(0, ("CVfdShExt::GetInfoTip\n"));
232 *ppwszTip = NULL;
233 return NOERROR;
234}
235*/