Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/dlls/activeds/pathname.c
4389 views
1
/*
2
* Copyright 2020 Dmitry Timoshkov
3
*
4
* This file contains only stubs to get the printui.dll up and running
5
* activeds.dll is much much more than this
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* This library is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20
*/
21
22
#include <stdarg.h>
23
24
#define COBJMACROS
25
26
#include "windef.h"
27
#include "winbase.h"
28
#include "iads.h"
29
#include "adserr.h"
30
31
#include "wine/debug.h"
32
33
WINE_DEFAULT_DEBUG_CHANNEL(activeds);
34
35
#include "initguid.h"
36
DEFINE_GUID(CLSID_Pathname,0x080d0d78,0xf421,0x11d0,0xa3,0x6e,0x00,0xc0,0x4f,0xb9,0x50,0xdc);
37
38
typedef struct
39
{
40
IADsPathname IADsPathname_iface;
41
LONG ref;
42
BSTR provider, server, dn;
43
} Pathname;
44
45
static inline Pathname *impl_from_IADsPathname(IADsPathname *iface)
46
{
47
return CONTAINING_RECORD(iface, Pathname, IADsPathname_iface);
48
}
49
50
static HRESULT WINAPI path_QueryInterface(IADsPathname *iface, REFIID riid, void **obj)
51
{
52
TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
53
54
if (!riid || !obj) return E_INVALIDARG;
55
56
if (IsEqualGUID(riid, &IID_IUnknown) ||
57
IsEqualGUID(riid, &IID_IDispatch) ||
58
IsEqualGUID(riid, &IID_IADsPathname))
59
{
60
IADsPathname_AddRef(iface);
61
*obj = iface;
62
return S_OK;
63
}
64
65
FIXME("interface %s is not implemented\n", debugstr_guid(riid));
66
return E_NOINTERFACE;
67
}
68
69
static ULONG WINAPI path_AddRef(IADsPathname *iface)
70
{
71
Pathname *path = impl_from_IADsPathname(iface);
72
return InterlockedIncrement(&path->ref);
73
}
74
75
static ULONG WINAPI path_Release(IADsPathname *iface)
76
{
77
Pathname *path = impl_from_IADsPathname(iface);
78
LONG ref = InterlockedDecrement(&path->ref);
79
80
if (!ref)
81
{
82
TRACE("destroying %p\n", iface);
83
SysFreeString(path->provider);
84
SysFreeString(path->server);
85
SysFreeString(path->dn);
86
free(path);
87
}
88
89
return ref;
90
}
91
92
static HRESULT WINAPI path_GetTypeInfoCount(IADsPathname *iface, UINT *count)
93
{
94
FIXME("%p,%p: stub\n", iface, count);
95
return E_NOTIMPL;
96
}
97
98
static HRESULT WINAPI path_GetTypeInfo(IADsPathname *iface, UINT index, LCID lcid, ITypeInfo **info)
99
{
100
FIXME("%p,%u,%#lx,%p: stub\n", iface, index, lcid, info);
101
return E_NOTIMPL;
102
}
103
104
static HRESULT WINAPI path_GetIDsOfNames(IADsPathname *iface, REFIID riid, LPOLESTR *names,
105
UINT count, LCID lcid, DISPID *dispid)
106
{
107
FIXME("%p,%s,%p,%u,%lu,%p: stub\n", iface, debugstr_guid(riid), names, count, lcid, dispid);
108
return E_NOTIMPL;
109
}
110
111
static HRESULT WINAPI path_Invoke(IADsPathname *iface, DISPID dispid, REFIID riid, LCID lcid, WORD flags,
112
DISPPARAMS *params, VARIANT *result, EXCEPINFO *excepinfo, UINT *argerr)
113
{
114
FIXME("%p,%ld,%s,%04lx,%04x,%p,%p,%p,%p: stub\n", iface, dispid, debugstr_guid(riid), lcid, flags,
115
params, result, excepinfo, argerr);
116
return E_NOTIMPL;
117
}
118
119
static HRESULT parse_path(BSTR path, BSTR *provider, BSTR *server, BSTR *dn)
120
{
121
WCHAR *p, *p_server;
122
int server_len;
123
124
*provider = NULL;
125
*server = NULL;
126
*dn = NULL;
127
128
if (wcsnicmp(path, L"LDAP:", 5) != 0)
129
return E_ADS_BAD_PATHNAME;
130
131
*provider = SysAllocStringLen(path, 4);
132
if (!*provider) return E_OUTOFMEMORY;
133
134
p = path + 5;
135
if (!*p) return S_OK;
136
137
if (*p++ != '/' || *p++ != '/' || !*p)
138
{
139
SysFreeString(*provider);
140
return E_ADS_BAD_PATHNAME;
141
}
142
143
p_server = p;
144
server_len = 0;
145
while (*p && *p != '/')
146
{
147
p++;
148
server_len++;
149
}
150
if (server_len == 0)
151
{
152
SysFreeString(*provider);
153
return E_ADS_BAD_PATHNAME;
154
}
155
156
*server = SysAllocStringLen(p_server, server_len);
157
if (!*server)
158
{
159
SysFreeString(*provider);
160
return E_OUTOFMEMORY;
161
}
162
163
if (!*p) return S_OK;
164
165
if (*p++ != '/' || !*p)
166
{
167
SysFreeString(*provider);
168
SysFreeString(*server);
169
return E_ADS_BAD_PATHNAME;
170
}
171
172
*dn = SysAllocString(p);
173
if (!*dn)
174
{
175
SysFreeString(*provider);
176
SysFreeString(*server);
177
return E_OUTOFMEMORY;
178
}
179
180
return S_OK;
181
}
182
183
static HRESULT WINAPI path_Set(IADsPathname *iface, BSTR adspath, LONG type)
184
{
185
Pathname *path = impl_from_IADsPathname(iface);
186
HRESULT hr;
187
BSTR provider, server, dn;
188
189
TRACE("%p,%s,%ld\n", iface, debugstr_w(adspath), type);
190
191
if (!adspath) return E_INVALIDARG;
192
193
if (type == ADS_SETTYPE_PROVIDER)
194
{
195
SysFreeString(path->provider);
196
path->provider = SysAllocString(adspath);
197
return path->provider ? S_OK : E_OUTOFMEMORY;
198
}
199
200
if (type == ADS_SETTYPE_SERVER)
201
{
202
SysFreeString(path->server);
203
path->server = SysAllocString(adspath);
204
return path->server ? S_OK : E_OUTOFMEMORY;
205
}
206
207
if (type == ADS_SETTYPE_DN)
208
{
209
SysFreeString(path->dn);
210
path->dn = SysAllocString(adspath);
211
return path->dn ? S_OK : E_OUTOFMEMORY;
212
}
213
214
if (type != ADS_SETTYPE_FULL)
215
{
216
FIXME("type %ld not implemented\n", type);
217
return E_INVALIDARG;
218
}
219
220
hr = parse_path(adspath, &provider, &server, &dn);
221
if (hr == S_OK)
222
{
223
SysFreeString(path->provider);
224
SysFreeString(path->server);
225
SysFreeString(path->dn);
226
227
path->provider = provider;
228
path->server = server;
229
path->dn = dn;
230
}
231
return hr;
232
}
233
234
static HRESULT WINAPI path_SetDisplayType(IADsPathname *iface, LONG type)
235
{
236
FIXME("%p,%ld: stub\n", iface, type);
237
return E_NOTIMPL;
238
}
239
240
static HRESULT WINAPI path_Retrieve(IADsPathname *iface, LONG type, BSTR *adspath)
241
{
242
Pathname *path = impl_from_IADsPathname(iface);
243
int len;
244
245
TRACE("%p,%ld,%p\n", iface, type, adspath);
246
247
if (!adspath) return E_INVALIDARG;
248
249
switch (type)
250
{
251
default:
252
FIXME("type %ld not implemented\n", type);
253
/* fall through */
254
255
case ADS_FORMAT_X500:
256
len = wcslen(path->provider) + 3;
257
if (path->server) len += wcslen(path->server) + 1;
258
if (path->dn) len += wcslen(path->dn);
259
260
*adspath = SysAllocStringLen(NULL, len);
261
if (!*adspath) break;
262
263
wcscpy(*adspath, path->provider);
264
wcscat(*adspath, L"://");
265
if (path->server)
266
{
267
wcscat(*adspath, path->server);
268
wcscat(*adspath, L"/");
269
}
270
if (path->dn) wcscat(*adspath, path->dn);
271
break;
272
273
case ADS_FORMAT_PROVIDER:
274
*adspath = SysAllocString(path->provider);
275
break;
276
277
case ADS_FORMAT_SERVER:
278
*adspath = path->provider ? SysAllocString(path->server) : SysAllocStringLen(NULL, 0);
279
break;
280
281
case ADS_FORMAT_X500_DN:
282
*adspath = path->dn ? SysAllocString(path->dn) : SysAllocStringLen(NULL, 0);
283
break;
284
285
case ADS_FORMAT_LEAF:
286
if (!path->dn)
287
*adspath = SysAllocStringLen(NULL, 0);
288
else
289
{
290
WCHAR *p = wcschr(path->dn, ',');
291
*adspath = p ? SysAllocStringLen(path->dn, p - path->dn) : SysAllocString(path->dn);
292
}
293
break;
294
}
295
296
TRACE("=> %s\n", debugstr_w(*adspath));
297
return *adspath ? S_OK : E_OUTOFMEMORY;
298
}
299
300
static HRESULT WINAPI path_GetNumElements(IADsPathname *iface, LONG *count)
301
{
302
Pathname *path = impl_from_IADsPathname(iface);
303
WCHAR *p;
304
305
TRACE("%p,%p\n", iface, count);
306
307
if (!count) return E_INVALIDARG;
308
309
*count = 0;
310
311
p = path->dn;
312
while (p)
313
{
314
*count += 1;
315
p = wcschr(p, ',');
316
if (p) p++;
317
}
318
319
return S_OK;
320
}
321
322
static HRESULT WINAPI path_GetElement(IADsPathname *iface, LONG index, BSTR *element)
323
{
324
Pathname *path = impl_from_IADsPathname(iface);
325
HRESULT hr;
326
WCHAR *p, *end;
327
LONG count;
328
329
TRACE("%p,%ld,%p\n", iface, index, element);
330
331
if (!element) return E_INVALIDARG;
332
333
count = 0;
334
hr = HRESULT_FROM_WIN32(ERROR_INVALID_INDEX);
335
336
p = path->dn;
337
while (p)
338
{
339
end = wcschr(p, ',');
340
341
if (index == count)
342
{
343
*element = end ? SysAllocStringLen(p, end - p) : SysAllocString(p);
344
hr = *element ? S_OK : E_OUTOFMEMORY;
345
break;
346
}
347
348
p = end ? end + 1 : NULL;
349
count++;
350
}
351
352
return hr;
353
}
354
355
static HRESULT WINAPI path_AddLeafElement(IADsPathname *iface, BSTR element)
356
{
357
FIXME("%p,%s: stub\n", iface, debugstr_w(element));
358
return E_NOTIMPL;
359
}
360
361
static HRESULT WINAPI path_RemoveLeafElement(IADsPathname *iface)
362
{
363
FIXME("%p: stub\n", iface);
364
return E_NOTIMPL;
365
}
366
367
static HRESULT WINAPI path_CopyPath(IADsPathname *iface, IDispatch **path)
368
{
369
FIXME("%p,%p: stub\n", iface, path);
370
return E_NOTIMPL;
371
}
372
373
static HRESULT WINAPI path_GetEscapedElement(IADsPathname *iface, LONG reserved, BSTR element, BSTR *str)
374
{
375
FIXME("%p,%ld,%s,%p: stub\n", iface, reserved, debugstr_w(element), str);
376
return E_NOTIMPL;
377
}
378
379
static HRESULT WINAPI path_get_EscapedMode(IADsPathname *iface, LONG *mode)
380
{
381
FIXME("%p,%p: stub\n", iface, mode);
382
return E_NOTIMPL;
383
}
384
385
static HRESULT WINAPI path_put_EscapedMode(IADsPathname *iface, LONG mode)
386
{
387
FIXME("%p,%ld: stub\n", iface, mode);
388
return E_NOTIMPL;
389
}
390
391
static const IADsPathnameVtbl IADsPathname_vtbl =
392
{
393
path_QueryInterface,
394
path_AddRef,
395
path_Release,
396
path_GetTypeInfoCount,
397
path_GetTypeInfo,
398
path_GetIDsOfNames,
399
path_Invoke,
400
path_Set,
401
path_SetDisplayType,
402
path_Retrieve,
403
path_GetNumElements,
404
path_GetElement,
405
path_AddLeafElement,
406
path_RemoveLeafElement,
407
path_CopyPath,
408
path_GetEscapedElement,
409
path_get_EscapedMode,
410
path_put_EscapedMode
411
};
412
413
static HRESULT Pathname_create(REFIID riid, void **obj)
414
{
415
Pathname *path;
416
HRESULT hr;
417
418
path = malloc(sizeof(*path));
419
if (!path) return E_OUTOFMEMORY;
420
421
path->IADsPathname_iface.lpVtbl = &IADsPathname_vtbl;
422
path->ref = 1;
423
path->provider = SysAllocString(L"LDAP");
424
path->server = NULL;
425
path->dn = NULL;
426
427
hr = IADsPathname_QueryInterface(&path->IADsPathname_iface, riid, obj);
428
IADsPathname_Release(&path->IADsPathname_iface);
429
430
return hr;
431
}
432
433
static const struct class_info
434
{
435
const CLSID *clsid;
436
HRESULT (*constructor)(REFIID, void **);
437
} class_info[] =
438
{
439
{ &CLSID_Pathname, Pathname_create }
440
};
441
442
typedef struct
443
{
444
IClassFactory IClassFactory_iface;
445
LONG ref;
446
const struct class_info *info;
447
} class_factory;
448
449
static inline class_factory *impl_from_IClassFactory(IClassFactory *iface)
450
{
451
return CONTAINING_RECORD(iface, class_factory, IClassFactory_iface);
452
}
453
454
static HRESULT WINAPI factory_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *obj)
455
{
456
TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj);
457
458
if (!riid || !obj) return E_INVALIDARG;
459
460
if (IsEqualIID(riid, &IID_IUnknown) ||
461
IsEqualIID(riid, &IID_IClassFactory))
462
{
463
IClassFactory_AddRef(iface);
464
*obj = iface;
465
return S_OK;
466
}
467
468
*obj = NULL;
469
FIXME("interface %s is not implemented\n", debugstr_guid(riid));
470
return E_NOINTERFACE;
471
}
472
473
static ULONG WINAPI factory_AddRef(IClassFactory *iface)
474
{
475
class_factory *factory = impl_from_IClassFactory(iface);
476
ULONG ref = InterlockedIncrement(&factory->ref);
477
478
TRACE("(%p) ref %lu\n", iface, ref);
479
480
return ref;
481
}
482
483
static ULONG WINAPI factory_Release(IClassFactory *iface)
484
{
485
class_factory *factory = impl_from_IClassFactory(iface);
486
ULONG ref = InterlockedDecrement(&factory->ref);
487
488
TRACE("(%p) ref %lu\n", iface, ref);
489
490
if (!ref)
491
free(factory);
492
493
return ref;
494
}
495
496
static HRESULT WINAPI factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj)
497
{
498
class_factory *factory = impl_from_IClassFactory(iface);
499
500
TRACE("%p,%s,%p\n", outer, debugstr_guid(riid), obj);
501
502
if (!riid || !obj) return E_INVALIDARG;
503
504
*obj = NULL;
505
if (outer) return CLASS_E_NOAGGREGATION;
506
507
return factory->info->constructor(riid, obj);
508
}
509
510
static HRESULT WINAPI factory_LockServer(IClassFactory *iface, BOOL lock)
511
{
512
FIXME("%p,%d: stub\n", iface, lock);
513
return S_OK;
514
}
515
516
static const struct IClassFactoryVtbl factory_vtbl =
517
{
518
factory_QueryInterface,
519
factory_AddRef,
520
factory_Release,
521
factory_CreateInstance,
522
factory_LockServer
523
};
524
525
static HRESULT factory_constructor(const struct class_info *info, REFIID riid, void **obj)
526
{
527
class_factory *factory;
528
HRESULT hr;
529
530
factory = malloc(sizeof(*factory));
531
if (!factory) return E_OUTOFMEMORY;
532
533
factory->IClassFactory_iface.lpVtbl = &factory_vtbl;
534
factory->ref = 1;
535
factory->info = info;
536
537
hr = IClassFactory_QueryInterface(&factory->IClassFactory_iface, riid, obj);
538
IClassFactory_Release(&factory->IClassFactory_iface);
539
540
return hr;
541
}
542
543
HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID *obj)
544
{
545
int i;
546
547
TRACE("%s,%s,%p\n", debugstr_guid(clsid), debugstr_guid(iid), obj);
548
549
if (!clsid || !iid || !obj) return E_INVALIDARG;
550
551
*obj = NULL;
552
553
for (i = 0; i < ARRAY_SIZE(class_info); i++)
554
{
555
if (IsEqualCLSID(class_info[i].clsid, clsid))
556
return factory_constructor(&class_info[i], iid, obj);
557
}
558
559
FIXME("class %s/%s is not implemented\n", debugstr_guid(clsid), debugstr_guid(iid));
560
return CLASS_E_CLASSNOTAVAILABLE;
561
}
562
563