1 /*
2 * Copyright (c) 2020 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "iunknown.h"
16 #include "common.h"
17
18 #define OLD_VERSION 0
19
IUNKNOWN_AddRef(IUnknown * iUnknown)20 int IUNKNOWN_AddRef(IUnknown *iUnknown)
21 {
22 if (iUnknown == NULL) {
23 return EC_INVALID;
24 }
25
26 IUnknownEntry *entry = GET_OBJECT(iUnknown, IUnknownEntry, iUnknown);
27 entry->ref++;
28 return entry->ref;
29 }
30
IUNKNOWN_QueryInterface(IUnknown * iUnknown,int ver,void ** target)31 int IUNKNOWN_QueryInterface(IUnknown *iUnknown, int ver, void **target)
32 {
33 if (iUnknown == NULL || target == NULL) {
34 return EC_INVALID;
35 }
36
37 IUnknownEntry *entry = GET_OBJECT(iUnknown, IUnknownEntry, iUnknown);
38 if ((entry->ver & (uint16)ver) != ver) {
39 return EC_INVALID;
40 }
41
42 if (ver == OLD_VERSION &&
43 entry->ver != OLD_VERSION &&
44 (entry->ver & (uint16)DEFAULT_VERSION) != DEFAULT_VERSION) {
45 return EC_INVALID;
46 }
47
48 *target = iUnknown;
49 iUnknown->AddRef(iUnknown);
50 return EC_SUCCESS;
51 }
52
IUNKNOWN_Release(IUnknown * iUnknown)53 int IUNKNOWN_Release(IUnknown *iUnknown)
54 {
55 if (iUnknown == NULL) {
56 return EC_INVALID;
57 }
58
59 IUnknownEntry *entry = GET_OBJECT(iUnknown, IUnknownEntry, iUnknown);
60 int ref = entry->ref - 1;
61 if (ref < 0) {
62 // The iUnknown is already freed, there is some exception;
63 } else {
64 if (ref == 0) {
65 // Nobody reference to the iUnknown, should delete it.
66 // But iUnknown may be global variable, so the default version don`t delete it.
67 } else {
68 entry->ref = ref;
69 }
70 }
71 return ref;
72 }