sbWindowsFormatter.cpp
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 :miv */
3 /*
4  *=BEGIN SONGBIRD GPL
5  *
6  * This file is part of the Songbird web player.
7  *
8  * Copyright(c) 2005-2009 POTI, Inc.
9  * http://www.songbirdnest.com
10  *
11  * This file may be licensed under the terms of of the
12  * GNU General Public License Version 2 (the ``GPL'').
13  *
14  * Software distributed under the License is distributed
15  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
16  * express or implied. See the GPL for the specific language
17  * governing rights and limitations.
18  *
19  * You should have received a copy of the GPL along with this
20  * program. If not, go to http://www.gnu.org/licenses/gpl.html
21  * or write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23  *
24  *=END SONGBIRD GPL
25  */
26 
32 //------------------------------------------------------------------------------
33 //
34 // Songbird Windows formatter imported services.
35 //
36 //------------------------------------------------------------------------------
37 
38 // Self imports.
39 #include "sbWindowsFormatter.h"
40 
41 // Local imports.
42 #include "sbIWindowsFormatter_i.c"
43 
44 // Songbird imports.
45 #include <sbWindowsStorage.h>
46 #include <sbWindowsUtils.h>
47 
48 
49 //------------------------------------------------------------------------------
50 //
51 // Songbird Windows formatter IUnknown implementation.
52 //
53 //------------------------------------------------------------------------------
54 
61 STDMETHODIMP_(ULONG)
62 sbWindowsFormatter::AddRef()
63 {
64  // Increment the reference count and return the result.
65  return ++mRefCount;
66 }
67 
68 
76 STDMETHODIMP_(ULONG)
77 sbWindowsFormatter::Release()
78 {
79  // Decrement the reference count.
80  ULONG refCount = --mRefCount;
81 
82  // Delete self if reference count reaches zero.
83  if (mRefCount == 0)
84  delete this;
85 
86  return refCount;
87 }
88 
89 
101 STDMETHODIMP
103  void** aInterface)
104 {
105  // Validate arguments.
106  if (IsBadWritePtr(aInterface, sizeof(void*)))
107  return E_POINTER;
108 
109  // Initialize interface to null.
110  *aInterface = NULL;
111 
112  // Return requested interface.
113  if (InlineIsEqualGUID(aIID, IID_IUnknown))
114  *aInterface = static_cast<IUnknown*>(this);
115  else if (InlineIsEqualGUID(aIID, IID_sbIWindowsFormatter))
116  *aInterface = static_cast<sbIWindowsFormatter*>(this);
117  else
118  return E_NOINTERFACE;
119 
120  // Add a reference to the interface.
121  (static_cast<IUnknown*>(*aInterface))->AddRef();
122 
123  return S_OK;
124 }
125 
126 
127 //------------------------------------------------------------------------------
128 //
129 // Songbird Windows formatter sbIWindowsFormat implementation.
130 //
131 //------------------------------------------------------------------------------
132 
154 STDMETHODIMP
155 sbWindowsFormatter::Format(BSTR aVolumeName,
156  unsigned long aType,
157  BSTR aLabel,
158  DWORD aUnitAllocationSize,
159  long aForce,
160  long aQuickFormat,
161  long aEnableCompression)
162 {
163  // Validate arguments.
164  SB_WIN_ENSURE_ARG_POINTER(aVolumeName);
165 
166  // Log format request.
167  sbWindowsEventLog("Formatting volume: %S\n", aVolumeName);
168 
169  // Function variables.
170  HRESULT result;
171 
172  // Get the VDS volume from the volume name and set it up for auto-disposal.
173  IVdsVolumeMF* volume;
174  result = GetVolume(aVolumeName, &volume);
175  SB_WIN_ENSURE_SUCCESS(result, result);
176  SB_WIN_ENSURE_TRUE(result == S_OK, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
177  sbAutoIUnknown autoVolume(volume);
178 
179  // Format the volume.
180  IVdsAsync* async;
181  result = volume->Format(static_cast<VDS_FILE_SYSTEM_TYPE>(aType),
182  aLabel,
183  aUnitAllocationSize,
184  aForce,
185  aQuickFormat,
186  aEnableCompression,
187  &async);
188  SB_WIN_ENSURE_SUCCESS(result, result);
189  sbAutoIUnknown autoAsync(async);
190 
191  // Wait for the format to complete.
192  VDS_ASYNC_OUTPUT asyncOutput;
193  HRESULT formatResult;
194  result = async->Wait(&formatResult, &asyncOutput);
195  SB_WIN_ENSURE_SUCCESS(result, result);
196  SB_WIN_ENSURE_SUCCESS(formatResult, formatResult);
197 
198  return S_OK;
199 }
200 
201 
202 //------------------------------------------------------------------------------
203 //
204 // Public Songbird Windows formatter services.
205 //
206 //------------------------------------------------------------------------------
207 
208 //-------------------------------------
209 //
210 // New
211 //
212 
213 /* static */ HRESULT
215 {
216  // Validate arguments.
217  SB_WIN_ENSURE_ARG_POINTER(aWindowsFormatter);
218 
219  // Function variables.
220  HRESULT result;
221 
222  // Create the Windows formatter object and set it up for auto-disposal.
223  sbWindowsFormatter* windowsFormatter = new sbWindowsFormatter();
224  SB_WIN_ENSURE_TRUE(windowsFormatter, E_OUTOFMEMORY);
225  windowsFormatter->AddRef();
226  sbAutoIUnknown autoWindowsFormatter(windowsFormatter);
227 
228  // Initialize the Windows formatter.
229  result = windowsFormatter->Initialize();
230  SB_WIN_ENSURE_SUCCESS(result, result);
231 
232  // Return results.
233  *aWindowsFormatter = windowsFormatter;
234  autoWindowsFormatter.forget();
235 
236  return S_OK;
237 }
238 
239 
240 //-------------------------------------
241 //
242 // ~sbWindowsFormatter
243 //
244 
246 {
247  // Release the VDS service object.
248  if (mVdsService)
249  mVdsService->Release();
250 }
251 
252 
253 //------------------------------------------------------------------------------
254 //
255 // Private Songbird Windows formatter services.
256 //
257 //------------------------------------------------------------------------------
258 
259 //-------------------------------------
260 //
261 // sbWindowsFormatter
262 //
263 
264 sbWindowsFormatter::sbWindowsFormatter() :
265  mRefCount(0),
266  mVdsService(NULL)
267 {
268 }
269 
270 
271 //-------------------------------------
272 //
273 // GetVolume
274 //
275 
276 HRESULT
277 sbWindowsFormatter::Initialize()
278 {
279  HRESULT result;
280 
281  // Initialize COM.
282  mAutoCOMInitializer.Initialize();
283  result = mAutoCOMInitializer.GetHRESULT();
284  SB_WIN_ENSURE_SUCCESS(result, result);
285 
286  // Get the VDS service loader object and set it up for auto-disposal.
287  IVdsServiceLoader* vdsServiceLoader;
288  result = CoCreateInstance(CLSID_VdsLoader,
289  NULL,
290  CLSCTX_LOCAL_SERVER,
291  IID_IVdsServiceLoader,
292  reinterpret_cast<void**>(&vdsServiceLoader));
293  SB_WIN_ENSURE_SUCCESS(result, result);
294  sbAutoIUnknown autoVdsServiceLoader(vdsServiceLoader);
295 
296  // Load the VDS service.
297  result = vdsServiceLoader->LoadService(NULL, &mVdsService);
298  SB_WIN_ENSURE_SUCCESS(result, result);
299  result = mVdsService->WaitForServiceReady();
300  SB_WIN_ENSURE_SUCCESS(result, result);
301 
302  return S_OK;
303 }
304 
305 
306 //-------------------------------------
307 //
308 // GetVolume
309 //
310 
311 HRESULT
312 sbWindowsFormatter::GetVolume(BSTR aVolumeName,
313  IVdsVolumeMF** aVolume)
314 {
315  // Validate arguments.
316  SB_WIN_ENSURE_ARG_POINTER(aVolumeName);
317  SB_WIN_ENSURE_ARG_POINTER(aVolume);
318 
319  // Function variables.
320  HRESULT result;
321 
322  // Return a null volume by default.
323  *aVolume = NULL;
324 
325  // Get the list of software providers and set it up for auto-disposal.
326  IEnumVdsObject* swProviderEnum;
327  result = mVdsService->QueryProviders(VDS_QUERY_SOFTWARE_PROVIDERS,
328  &swProviderEnum);
329  SB_WIN_ENSURE_SUCCESS(result, result);
330  sbAutoIUnknown autoSwProviderEnum(swProviderEnum);
331 
332  // Search each software provider for the volume. Enumerate all software
333  // providers until no more remain or until the volume is found.
334  while (1) {
335  // Get the next software provider and set it up for auto-disposal. The
336  // returned count will be zero when the enumeration is complete.
337  IUnknown* swProviderIUnknown;
338  ULONG count;
339  result = swProviderEnum->Next(1, &swProviderIUnknown, &count);
340  SB_WIN_ENSURE_SUCCESS(result, result);
341  if (!count)
342  break;
343  sbAutoIUnknown autoSwProviderIUnknown(swProviderIUnknown);
344 
345  // QI the software provider and set it up for auto-disposal.
346  IVdsSwProvider* swProvider;
347  result = swProviderIUnknown->QueryInterface
348  (IID_IVdsSwProvider,
349  reinterpret_cast<void**>(&swProvider));
350  SB_WIN_ENSURE_SUCCESS(result, result);
351  sbAutoIUnknown autoSwProvider(swProvider);
352 
353  // Try getting the volume from the software provider. Return volume if
354  // found.
355  result = GetVolume(swProvider, aVolumeName, aVolume);
356  SB_WIN_ENSURE_SUCCESS(result, result);
357  if (result == S_OK)
358  return S_OK;
359  }
360 
361  return S_FALSE;
362 }
363 
364 
365 //-------------------------------------
366 //
367 // GetVolume
368 //
369 
370 HRESULT
371 sbWindowsFormatter::GetVolume(IVdsSwProvider* aSwProvider,
372  BSTR aVolumeName,
373  IVdsVolumeMF** aVolume)
374 {
375  // Validate arguments.
376  SB_WIN_ENSURE_ARG_POINTER(aSwProvider);
377  SB_WIN_ENSURE_ARG_POINTER(aVolumeName);
378  SB_WIN_ENSURE_ARG_POINTER(aVolume);
379 
380  // Function variables.
381  HRESULT result;
382 
383  // Return a null volume by default.
384  *aVolume = NULL;
385 
386  // Get the list of VDS packs and set it up for auto-disposal.
387  IEnumVdsObject* packEnum;
388  result = aSwProvider->QueryPacks(&packEnum);
389  SB_WIN_ENSURE_SUCCESS(result, result);
390  sbAutoIUnknown autoPackEnum(packEnum);
391 
392  // Search each pack for the volume. Enumerate all packs until no more remain
393  // or until the volume is found.
394  while (1) {
395  // Get the next pack and set it up for auto-disposal. The returned count
396  // will be zero when the enumeration is complete.
397  IUnknown* packIUnknown;
398  ULONG count;
399  result = packEnum->Next(1, &packIUnknown, &count);
400  SB_WIN_ENSURE_SUCCESS(result, result);
401  if (!count)
402  break;
403  sbAutoIUnknown autoPackIUnknown(packIUnknown);
404 
405  // QI the pack and set it up for auto-disposal.
406  IVdsPack* pack;
407  result = packIUnknown->QueryInterface(IID_IVdsPack,
408  reinterpret_cast<void**>(&pack));
409  SB_WIN_ENSURE_SUCCESS(result, result);
410  sbAutoIUnknown autoPack(pack);
411 
412  // Try getting the volume from the pack. Return volume if found.
413  result = GetVolume(pack, aVolumeName, aVolume);
414  SB_WIN_ENSURE_SUCCESS(result, result);
415  if (result == S_OK)
416  return S_OK;
417  }
418 
419  return S_FALSE;
420 }
421 
422 
423 //-------------------------------------
424 //
425 // GetVolume
426 //
427 
428 HRESULT
429 sbWindowsFormatter::GetVolume(IVdsPack* aPack,
430  BSTR aVolumeName,
431  IVdsVolumeMF** aVolume)
432 {
433  // Validate arguments.
434  SB_WIN_ENSURE_ARG_POINTER(aPack);
435  SB_WIN_ENSURE_ARG_POINTER(aVolumeName);
436  SB_WIN_ENSURE_ARG_POINTER(aVolume);
437 
438  // Function variables.
439  HRESULT result;
440 
441  // Return a null volume by default.
442  *aVolume = NULL;
443 
444  // Get the target volume storage device number.
445  STORAGE_DEVICE_NUMBER targetDevNum;
446  result = sbWinGetStorageDevNum(aVolumeName, &targetDevNum);
447  SB_WIN_ENSURE_SUCCESS(result, result);
448 
449  // Get the list of VDS pack volumes and set it up for auto-disposal.
450  IEnumVdsObject* volumeEnum;
451  result = aPack->QueryVolumes(&volumeEnum);
452  SB_WIN_ENSURE_SUCCESS(result, result);
453  sbAutoIUnknown autoVolumeEnum(volumeEnum);
454 
455  // Search for the volume. Enumerate all volumes until no more remain or until
456  // the target volume is found.
457  while (1) {
458  // Get the next volume and set it up for auto-disposal. The returned count
459  // will be zero when the enumeration is complete.
460  IUnknown* volumeIUnknown;
461  ULONG count;
462  result = volumeEnum->Next(1, &volumeIUnknown, &count);
463  SB_WIN_ENSURE_SUCCESS(result, result);
464  if (!count)
465  break;
466  sbAutoIUnknown autoVolumeIUnknown(volumeIUnknown);
467 
468  // QI the volume and set it up for auto-disposal.
469  IVdsVolume* volume;
470  result = volumeIUnknown->QueryInterface(IID_IVdsVolume,
471  reinterpret_cast<void**>(&volume));
472  SB_WIN_ENSURE_SUCCESS(result, result);
473  sbAutoIUnknown autoVolume(volume);
474 
475  // Get the volume properties.
476  VDS_VOLUME_PROP volumeProp;
477  result = volume->GetProperties(&volumeProp);
478  SB_WIN_ENSURE_SUCCESS(result, result);
479 
480  // Get the volume storage device number.
481  STORAGE_DEVICE_NUMBER volumeDevNum;
482  result = sbWinGetStorageDevNum(volumeProp.pwszName, &volumeDevNum);
483  SB_WIN_ENSURE_SUCCESS(result, result);
484 
485  // Return volume if it matches the target.
486  if ((volumeDevNum.DeviceType == targetDevNum.DeviceType) &&
487  (volumeDevNum.DeviceNumber == targetDevNum.DeviceNumber) &&
488  (volumeDevNum.PartitionNumber == targetDevNum.PartitionNumber)) {
489  result = volumeIUnknown->QueryInterface
490  (IID_IVdsVolumeMF,
491  reinterpret_cast<void**>(aVolume));
492  SB_WIN_ENSURE_SUCCESS(result, result);
493  return S_OK;
494  }
495  }
496 
497  return S_FALSE;
498 }
499 
HRESULT Initialize(DWORD aInitFlags=COINIT_MULTITHREADED)
Songbird Windows Formatter Definitions.
nsresult sbWinGetStorageDevNum(DEVINST aDevInst, const GUID *aGUID, STORAGE_DEVICE_NUMBER *aStorageDevNum)
var count
Definition: test_bug7406.js:32
STDMETHOD() Format(BSTR aVolumeName, unsigned long aType, BSTR aLabel, DWORD aUnitAllocationSize, long aForce, long aQuickFormat, long aEnableCompression)
STDMETHOD() QueryInterface(REFIID aIID, void **aInterface)
#define SB_WIN_ENSURE_SUCCESS(aHR, aRV)
static HRESULT New(sbWindowsFormatter **aWindowsFormatter)
HRESULT GetHRESULT() const