xref: /reactos/dll/win32/mshtml/loadopts.c (revision 1734f297)
1 /*
2  * Copyright 2006 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include "mshtml_private.h"
20 
21 typedef struct load_opt {
22     DWORD option;
23     PVOID buffer;
24     DWORD size;
25 
26     struct load_opt *next;
27 } load_opt;
28 
29 typedef struct {
30     IHtmlLoadOptions IHtmlLoadOptions_iface;
31 
32     LONG ref;
33 
34     load_opt *opts;
35 } HTMLLoadOptions;
36 
37 static inline HTMLLoadOptions *impl_from_IHtmlLoadOptions(IHtmlLoadOptions *iface)
38 {
39     return CONTAINING_RECORD(iface, HTMLLoadOptions, IHtmlLoadOptions_iface);
40 }
41 
42 static HRESULT WINAPI HtmlLoadOptions_QueryInterface(IHtmlLoadOptions *iface,
43         REFIID riid, void **ppv)
44 {
45     HTMLLoadOptions *This = impl_from_IHtmlLoadOptions(iface);
46 
47     TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
48 
49     if(IsEqualGUID(&IID_IUnknown, riid)) {
50         *ppv = &This->IHtmlLoadOptions_iface;
51     }else if(IsEqualGUID(&IID_IOptionArray, riid)) {
52         *ppv = &This->IHtmlLoadOptions_iface;
53     }else if(IsEqualGUID(&IID_IHtmlLoadOptions, riid)) {
54         *ppv = &This->IHtmlLoadOptions_iface;
55     }else {
56         *ppv = NULL;
57         WARN("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
58         return E_NOINTERFACE;
59     }
60 
61     IUnknown_AddRef((IUnknown*)*ppv);
62     return S_OK;
63 }
64 
65 static ULONG WINAPI HtmlLoadOptions_AddRef(IHtmlLoadOptions *iface)
66 {
67     HTMLLoadOptions *This = impl_from_IHtmlLoadOptions(iface);
68     LONG ref = InterlockedIncrement(&This->ref);
69 
70     TRACE("(%p) ref=%d\n", This, ref);
71 
72     return ref;
73 }
74 
75 static ULONG WINAPI HtmlLoadOptions_Release(IHtmlLoadOptions *iface)
76 {
77     HTMLLoadOptions *This = impl_from_IHtmlLoadOptions(iface);
78     LONG ref = InterlockedDecrement(&This->ref);
79 
80     TRACE("(%p) ref=%d\n", This, ref);
81 
82     if(!ref) {
83         load_opt *iter = This->opts, *last;
84 
85         while(iter) {
86             last = iter;
87             iter = iter->next;
88 
89             heap_free(last->buffer);
90             heap_free(last);
91         }
92 
93         heap_free(This);
94     }
95 
96     return ref;
97 }
98 
99 static HRESULT WINAPI HtmlLoadOptions_QueryOption(IHtmlLoadOptions *iface, DWORD dwOption,
100         LPVOID pBuffer, ULONG *pcbBuf)
101 {
102     HTMLLoadOptions *This = impl_from_IHtmlLoadOptions(iface);
103     load_opt *iter;
104 
105     TRACE("(%p)->(%d %p %p)\n", This, dwOption, pBuffer, pcbBuf);
106 
107     for(iter = This->opts; iter; iter = iter->next) {
108         if(iter->option == dwOption)
109             break;
110     }
111 
112     if(!iter) {
113         *pcbBuf = 0;
114         return S_OK;
115     }
116 
117     if(*pcbBuf < iter->size) {
118         *pcbBuf = iter->size;
119         return E_FAIL;
120     }
121 
122     memcpy(pBuffer, iter->buffer, iter->size);
123     *pcbBuf = iter->size;
124 
125     return S_OK;
126 }
127 
128 static HRESULT WINAPI HtmlLoadOptions_SetOption(IHtmlLoadOptions *iface, DWORD dwOption,
129         LPVOID pBuffer, ULONG cbBuf)
130 {
131     HTMLLoadOptions *This = impl_from_IHtmlLoadOptions(iface);
132     load_opt *iter = NULL;
133 
134     TRACE("(%p)->(%d %p %d)\n", This, dwOption, pBuffer, cbBuf);
135 
136     for(iter = This->opts; iter; iter = iter->next) {
137         if(iter->option == dwOption)
138             break;
139     }
140 
141     if(!iter) {
142         iter = heap_alloc(sizeof(load_opt));
143         iter->next = This->opts;
144         This->opts = iter;
145 
146         iter->option = dwOption;
147     }else {
148         heap_free(iter->buffer);
149     }
150 
151     if(!cbBuf) {
152         iter->buffer = NULL;
153         iter->size = 0;
154 
155         return S_OK;
156     }
157 
158     iter->size = cbBuf;
159     iter->buffer = heap_alloc(cbBuf);
160     memcpy(iter->buffer, pBuffer, iter->size);
161 
162     return S_OK;
163 }
164 
165 static const IHtmlLoadOptionsVtbl HtmlLoadOptionsVtbl = {
166     HtmlLoadOptions_QueryInterface,
167     HtmlLoadOptions_AddRef,
168     HtmlLoadOptions_Release,
169     HtmlLoadOptions_QueryOption,
170     HtmlLoadOptions_SetOption
171 };
172 
173 HRESULT HTMLLoadOptions_Create(IUnknown *pUnkOuter, REFIID riid, void** ppv)
174 {
175     HTMLLoadOptions *ret;
176     HRESULT hres;
177 
178     TRACE("(%p %s %p)\n", pUnkOuter, debugstr_mshtml_guid(riid), ppv);
179 
180     ret = heap_alloc(sizeof(HTMLLoadOptions));
181     if(!ret)
182         return E_OUTOFMEMORY;
183 
184     ret->IHtmlLoadOptions_iface.lpVtbl = &HtmlLoadOptionsVtbl;
185     ret->ref = 1;
186     ret->opts = NULL;
187 
188     hres = IHtmlLoadOptions_QueryInterface(&ret->IHtmlLoadOptions_iface, riid, ppv);
189     IHtmlLoadOptions_Release(&ret->IHtmlLoadOptions_iface);
190     return hres;
191 }
192