File: Factory.cpp

package info (click to toggle)
firefox 142.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,591,884 kB
  • sloc: cpp: 7,451,570; javascript: 6,392,463; ansic: 3,712,584; python: 1,388,569; xml: 629,223; asm: 426,919; java: 184,857; sh: 63,439; makefile: 19,150; objc: 13,059; perl: 12,983; yacc: 4,583; cs: 3,846; pascal: 3,352; lex: 1,720; ruby: 1,003; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 53; csh: 10
file content (74 lines) | stat: -rw-r--r-- 1,819 bytes parent folder | download | duplicates (19)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "mozilla/Atomics.h"
#include "mozilla/RefPtr.h"

#include <windows.h>
#include <shlobj.h>

already_AddRefed<IExtractIconW> CreateIconExtension();

class ClassFactory final : public IClassFactory {
  mozilla::Atomic<uint32_t> mRefCnt;

  ~ClassFactory() = default;

 public:
  ClassFactory() : mRefCnt(0) {}

  // IUnknown

  STDMETHODIMP QueryInterface(REFIID aRefIID, void** aResult) {
    if (!aResult) {
      return E_INVALIDARG;
    }

    if (aRefIID == IID_IClassFactory) {
      RefPtr ref(static_cast<IClassFactory*>(this));
      ref.forget(aResult);
      return S_OK;
    }

    return E_NOINTERFACE;
  }

  STDMETHODIMP_(ULONG) AddRef() { return ++mRefCnt; }

  STDMETHODIMP_(ULONG) Release() {
    ULONG result = --mRefCnt;
    if (!result) {
      delete this;
    }
    return result;
  }

  // IClassFactory

  STDMETHODIMP CreateInstance(IUnknown* aOuter, REFIID aRefIID,
                              void** aResult) {
    if (aOuter) {
      return CLASS_E_NOAGGREGATION;
    }

    RefPtr<IUnknown> instance;
    if (IsEqualCLSID(aRefIID, IID_IExtractIconA) ||
        IsEqualCLSID(aRefIID, IID_IExtractIconW)) {
      instance = CreateIconExtension();
    } else {
      return E_NOINTERFACE;
    }

    return instance ? instance->QueryInterface(aRefIID, aResult)
                    : E_OUTOFMEMORY;
  }

  STDMETHODIMP LockServer(BOOL) { return S_OK; }
};

already_AddRefed<IClassFactory> CreateFactory() {
  return mozilla::MakeAndAddRef<ClassFactory>();
}