ReactOS 0.4.16-dev-522-gb68104a
actctx.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Runtime Library
4 * PURPOSE: Activation Context Support
5 * FILE: lib/rtl/actctx.c
6 * PROGRAMERS:
7 * Jon Griffiths
8 * Eric Pouech
9 * Jacek Caban for CodeWeavers
10 * Alexandre Julliard
11 * Stefan Ginsberg (stefan.ginsberg@reactos.org)
12 * Samuel SerapiĆ³n
13 */
14
15/* Based on Wine 3.2-37c98396 */
16#ifdef __REACTOS__
17
18#include <rtl.h>
19#include <ntstrsafe.h>
20#include <compat_undoc.h>
21
22#include <wine/unicode.h>
23#include "wine/exception.h"
24#include "wine/debug.h"
25
27
28#define GetProcessHeap() RtlGetProcessHeap()
29#define GetCurrentProcess() NtCurrentProcess()
30#define DPRINT1 FIXME
31#define DPRINT TRACE
32#define FILE_END_OF_FILE_INFORMATION FILE_STANDARD_INFORMATION
33#define FileEndOfFileInformation FileStandardInformation
34#define RELATIVE_PATH RtlPathTypeRelative
35#define windows_dir SharedUserData->NtSystemRoot
36#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
37#define wcsnicmp _wcsnicmp
38#define swprintf _snwprintf
39#define wcsicmp _wcsicmp
41
42#undef RT_MANIFEST
43#undef CREATEPROCESS_MANIFEST_RESOURCE_ID
44
45BOOLEAN RtlpNotAllowingMultipleActivation;
46
47#endif // __REACTOS__
48
49#define ACTCTX_FLAGS_ALL (\
50 ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID |\
51 ACTCTX_FLAG_LANGID_VALID |\
52 ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID |\
53 ACTCTX_FLAG_RESOURCE_NAME_VALID |\
54 ACTCTX_FLAG_SET_PROCESS_DEFAULT |\
55 ACTCTX_FLAG_APPLICATION_NAME_VALID |\
56 ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF |\
57 ACTCTX_FLAG_HMODULE_VALID )
58
59#define ACTCTX_MAGIC 0xC07E3E11
60#define STRSECTION_MAGIC 0x64487353 /* dHsS */
61#define GUIDSECTION_MAGIC 0x64487347 /* dHsG */
62
63#define ACTCTX_FAKE_HANDLE ((HANDLE) 0xf00baa)
64
65/* we don't want to include winuser.h */
66#define RT_MANIFEST ((ULONG_PTR)24)
67#define CREATEPROCESS_MANIFEST_RESOURCE_ID ((ULONG_PTR)1)
68
69#ifndef __REACTOS__ // defined in oaidl.h
70/* from oaidl.h */
71typedef enum tagLIBFLAGS {
77
78/* from oleidl.idl */
79typedef enum tagOLEMISC
80{
99 OLEMISC_IMEMODE = 0x40000,
104#endif // !__REACTOS__
105
106#define MAX_NAMESPACES 64
107
108typedef struct
109{
110 const WCHAR *ptr;
111 unsigned int len;
112} xmlstr_t;
113
115{
119};
120
122{
125};
126
127typedef struct
128{
129 const WCHAR *ptr;
130 const WCHAR *end;
131 struct xml_attr namespaces[MAX_NAMESPACES];
134} xmlbuf_t;
135
137{
140};
141
143{
148};
149
151{
160};
161
163{
164 DWORD magic;
165 ULONG size;
166 DWORD unk1[3];
167 ULONG count;
169 DWORD unk2[2];
172};
173
174struct string_index
175{
176 ULONG hash; /* key string hash */
179 ULONG data_offset; /* redirect data offset */
182};
183
185{
186 DWORD magic;
187 ULONG size;
188 DWORD unk[3];
189 ULONG count;
191 DWORD unk2;
194};
195
196struct guid_index
197{
198 GUID guid;
202};
203
205{
206 ULONG size;
207 DWORD res;
209 ULONG name_offset; /* versioned name offset */
211 ULONG module_offset;/* container name offset */
212};
213
214struct dllredirect_data
215{
216 ULONG size;
217 ULONG unk;
218 DWORD res[3];
219};
220
222{
223 ULONG size;
224 DWORD res;
228 WORD flags;
233};
234
236{
243
245{
252
254{
255 ULONG size;
257 DWORD model;
258 GUID clsid;
259 GUID alias;
260 GUID clsid2;
261 GUID tlbid;
273};
274
276{
278 BaseIface = 2
280
282{
283 ULONG size;
284 DWORD mask;
285 GUID iid;
287 GUID tlbid;
288 GUID base;
291};
292
294{
295 ULONG size;
296 DWORD res;
297 GUID clsid;
302};
303
304struct clrclass_data
305{
306 ULONG size;
307 DWORD res[2];
314 DWORD res2[2];
315};
316
318{
319 ULONG size;
322};
323
324/*
325
326 Sections structure.
327
328 Sections are accessible by string or guid key, that defines two types of sections.
329 All sections of each type have same magic value and header structure, index
330 data could be of two possible types too. So every string based section uses
331 the same index format, same applies to guid sections - they share same guid index
332 format.
333
334 - window class redirection section is a plain buffer with following format:
335
336 <section header>
337 <index[]>
338 <data[]> --- <original name>
339 <redirect data>
340 <versioned name>
341 <module name>
342
343 Header is fixed length structure - struct strsection_header,
344 contains redirected classes count;
345
346 Index is an array of fixed length index records, each record is
347 struct string_index.
348
349 All strings in data itself are WCHAR, null terminated, 4-bytes aligned.
350
351 Versioned name offset is relative to redirect data structure (struct wndclass_redirect_data),
352 others are relative to section itself.
353
354 - dll redirect section format:
355
356 <section header>
357 <index[]>
358 <data[]> --- <dll name>
359 <data>
360
361 This section doesn't seem to carry any payload data except dll names.
362
363 - typelib section format:
364
365 <section header>
366 <module names[]>
367 <index[]>
368 <data[]> --- <data>
369 <helpstring>
370
371 Header is fixed length, index is an array of fixed length 'struct guid_index'.
372 All strings are WCHAR, null terminated, 4-bytes aligned. Module names part is
373 4-bytes aligned as a whole.
374
375 Module name offsets are relative to section, helpstring offset is relative to data
376 structure itself.
377
378 - comclass section format:
379
380 <section header>
381 <module names[]>
382 <index[]>
383 <data[]> --- <data> --- <data>
384 <progid> <clrdata>
385 <name>
386 <version>
387 <progid>
388
389 This section uses two index records per comclass, one entry contains original guid
390 as specified by context, another one has a generated guid. Index and strings handling
391 is similar to typelib sections.
392
393 For CLR classes additional data is stored after main COM class data, it contains
394 class name and runtime version string, see 'struct clrclass_data'.
395
396 Module name offsets are relative to section, progid offset is relative to data
397 structure itself.
398
399 - COM interface section format:
400
401 <section header>
402 <index[]>
403 <data[]> --- <data>
404 <name>
405
406 Interface section contains data for proxy/stubs and external proxy/stubs. External
407 ones are defined at assembly level, so this section has no module information.
408 All records are indexed with 'iid' value from manifest. There an exception for
409 external variants - if 'proxyStubClsid32' is specified, it's stored as iid in
410 redirect data, but index is still 'iid' from manifest.
411
412 Interface name offset is relative to data structure itself.
413
414 - CLR surrogates section format:
415
416 <section header>
417 <index[]>
418 <data[]> --- <data>
419 <name>
420 <version>
421
422 There's nothing special about this section, same way to store strings is used,
423 no modules part as it belongs to assembly level, not a file.
424
425 - ProgID section format:
426
427 <section header>
428 <guids[]>
429 <index[]>
430 <data[]> --- <progid>
431 <data>
432
433 This sections uses generated alias guids from COM server section. This way
434 ProgID -> CLSID mapping returns generated guid, not the real one. ProgID string
435 is stored too, aligned.
436*/
437
439{
441 unsigned int num;
442 unsigned int allocated;
443};
444
445struct entity
446{
448 union
449 {
450 struct
451 {
458 struct
459 {
461 WCHAR *tlbid;
463 WCHAR *name; /* clrClass: class name */
464 WCHAR *version; /* clrClass: CLR runtime version */
473 struct {
477 WCHAR *name;
478 WCHAR *ps32; /* only stored for 'comInterfaceExternalProxyStub' */
482 struct
483 {
484 WCHAR *name;
486 } class;
487 struct
488 {
489 WCHAR *name;
490 WCHAR *clsid;
491 WCHAR *version;
493 struct
494 {
495 WCHAR *name;
499 } u;
500};
501
503{
504 struct entity *base;
505 unsigned int num;
506 unsigned int allocated;
507};
508
510{
514};
515
517{
521};
522
523struct assembly
524{
531 unsigned int num_dlls;
532 unsigned int allocated_dlls;
534 COMPATIBILITY_CONTEXT_ELEMENT *compat_contexts;
536 ACTCTX_REQUESTED_RUN_LEVEL run_level;
538};
539
541{
550
551#ifdef __REACTOS__
552typedef struct _ASSEMBLY_STORAGE_MAP_ENTRY
553{
554 ULONG Flags;
555 UNICODE_STRING DosPath;
557} ASSEMBLY_STORAGE_MAP_ENTRY, *PASSEMBLY_STORAGE_MAP_ENTRY;
558
559typedef struct _ASSEMBLY_STORAGE_MAP
560{
561 ULONG Flags;
562 ULONG AssemblyCount;
563 PASSEMBLY_STORAGE_MAP_ENTRY *AssemblyArray;
564} ASSEMBLY_STORAGE_MAP, *PASSEMBLY_STORAGE_MAP;
565#endif // __REACTOS__
566
568{
571#ifdef __REACTOS__
572 ULONG Flags;
573 LIST_ENTRY Links;
574 PACTIVATION_CONTEXT_DATA ActivationContextData;
575 PVOID NotificationRoutine;
577 ULONG SentNotifications[8];
578 ULONG DisabledNotifications[8];
579 ASSEMBLY_STORAGE_MAP StorageMap;
580 PASSEMBLY_STORAGE_MAP_ENTRY InlineStorageMapEntries;
581 ULONG StackTraceIndex;
582 PVOID StackTraces[4][4];
583#endif // __REACTOS__
587 unsigned int num_assemblies;
589 /* section data */
599
601{
604 unsigned int num_dependencies;
606};
607
609
610#ifdef __i386__
611static const WCHAR current_archW[] = {'x','8','6',0};
612#elif defined __x86_64__
613static const WCHAR current_archW[] = {'a','m','d','6','4',0};
614#elif defined __arm__
615static const WCHAR current_archW[] = {'a','r','m',0};
616#elif defined __aarch64__
617static const WCHAR current_archW[] = {'a','r','m','6','4',0};
618#else
619static const WCHAR current_archW[] = {'n','o','n','e',0};
620#endif
621
622static const WCHAR asmv1W[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','a','s','m','.','v','1',0};
623static const WCHAR asmv2W[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','a','s','m','.','v','2',0};
624static const WCHAR asmv3W[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','a','s','m','.','v','3',0};
625static const WCHAR assemblyW[] = {'a','s','s','e','m','b','l','y',0};
626static const WCHAR assemblyIdentityW[] = {'a','s','s','e','m','b','l','y','I','d','e','n','t','i','t','y',0};
627static const WCHAR bindingRedirectW[] = {'b','i','n','d','i','n','g','R','e','d','i','r','e','c','t',0};
628static const WCHAR clrClassW[] = {'c','l','r','C','l','a','s','s',0};
629static const WCHAR clrSurrogateW[] = {'c','l','r','S','u','r','r','o','g','a','t','e',0};
630static const WCHAR comClassW[] = {'c','o','m','C','l','a','s','s',0};
631static const WCHAR comInterfaceExternalProxyStubW[] = {'c','o','m','I','n','t','e','r','f','a','c','e','E','x','t','e','r','n','a','l','P','r','o','x','y','S','t','u','b',0};
632static const WCHAR comInterfaceProxyStubW[] = {'c','o','m','I','n','t','e','r','f','a','c','e','P','r','o','x','y','S','t','u','b',0};
633static const WCHAR dependencyW[] = {'d','e','p','e','n','d','e','n','c','y',0};
634static const WCHAR dependentAssemblyW[] = {'d','e','p','e','n','d','e','n','t','A','s','s','e','m','b','l','y',0};
635static const WCHAR descriptionW[] = {'d','e','s','c','r','i','p','t','i','o','n',0};
636static const WCHAR fileW[] = {'f','i','l','e',0};
637static const WCHAR hashW[] = {'h','a','s','h',0};
638static const WCHAR noInheritW[] = {'n','o','I','n','h','e','r','i','t',0};
639static const WCHAR noInheritableW[] = {'n','o','I','n','h','e','r','i','t','a','b','l','e',0};
640static const WCHAR typelibW[] = {'t','y','p','e','l','i','b',0};
641static const WCHAR windowClassW[] = {'w','i','n','d','o','w','C','l','a','s','s',0};
642
643static const WCHAR clsidW[] = {'c','l','s','i','d',0};
644static const WCHAR hashalgW[] = {'h','a','s','h','a','l','g',0};
645static const WCHAR helpdirW[] = {'h','e','l','p','d','i','r',0};
646static const WCHAR iidW[] = {'i','i','d',0};
647static const WCHAR languageW[] = {'l','a','n','g','u','a','g','e',0};
648static const WCHAR manifestVersionW[] = {'m','a','n','i','f','e','s','t','V','e','r','s','i','o','n',0};
649static const WCHAR g_nameW[] = {'n','a','m','e',0};
650static const WCHAR neutralW[] = {'n','e','u','t','r','a','l',0};
651static const WCHAR newVersionW[] = {'n','e','w','V','e','r','s','i','o','n',0};
652static const WCHAR oldVersionW[] = {'o','l','d','V','e','r','s','i','o','n',0};
653static const WCHAR optionalW[] = {'o','p','t','i','o','n','a','l',0};
654static const WCHAR processorArchitectureW[] = {'p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e',0};
655static const WCHAR progidW[] = {'p','r','o','g','i','d',0};
656static const WCHAR publicKeyTokenW[] = {'p','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
657static const WCHAR threadingmodelW[] = {'t','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
658static const WCHAR tlbidW[] = {'t','l','b','i','d',0};
659static const WCHAR typeW[] = {'t','y','p','e',0};
660static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0};
661static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};
662static const WCHAR versionedW[] = {'v','e','r','s','i','o','n','e','d',0};
663static const WCHAR yesW[] = {'y','e','s',0};
664static const WCHAR noW[] = {'n','o',0};
665static const WCHAR restrictedW[] = {'R','E','S','T','R','I','C','T','E','D',0};
666static const WCHAR controlW[] = {'C','O','N','T','R','O','L',0};
667static const WCHAR hiddenW[] = {'H','I','D','D','E','N',0};
668static const WCHAR hasdiskimageW[] = {'H','A','S','D','I','S','K','I','M','A','G','E',0};
669static const WCHAR flagsW[] = {'f','l','a','g','s',0};
670static const WCHAR miscstatusW[] = {'m','i','s','c','S','t','a','t','u','s',0};
671static const WCHAR miscstatusiconW[] = {'m','i','s','c','S','t','a','t','u','s','I','c','o','n',0};
672static const WCHAR miscstatuscontentW[] = {'m','i','s','c','S','t','a','t','u','s','C','o','n','t','e','n','t',0};
673static const WCHAR miscstatusthumbnailW[] = {'m','i','s','c','S','t','a','t','u','s','T','h','u','m','b','n','a','i','l',0};
674static const WCHAR miscstatusdocprintW[] = {'m','i','s','c','S','t','a','t','u','s','D','o','c','P','r','i','n','t',0};
675static const WCHAR baseInterfaceW[] = {'b','a','s','e','I','n','t','e','r','f','a','c','e',0};
676static const WCHAR nummethodsW[] = {'n','u','m','M','e','t','h','o','d','s',0};
677static const WCHAR proxyStubClsid32W[] = {'p','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0};
678static const WCHAR runtimeVersionW[] = {'r','u','n','t','i','m','e','V','e','r','s','i','o','n',0};
679static const WCHAR mscoreeW[] = {'M','S','C','O','R','E','E','.','D','L','L',0};
680static const WCHAR mscoree2W[] = {'m','s','c','o','r','e','e','.','d','l','l',0};
681
682static const WCHAR activatewhenvisibleW[] = {'a','c','t','i','v','a','t','e','w','h','e','n','v','i','s','i','b','l','e',0};
683static const WCHAR actslikebuttonW[] = {'a','c','t','s','l','i','k','e','b','u','t','t','o','n',0};
684static const WCHAR actslikelabelW[] = {'a','c','t','s','l','i','k','e','l','a','b','e','l',0};
685static const WCHAR alignableW[] = {'a','l','i','g','n','a','b','l','e',0};
686static const WCHAR alwaysrunW[] = {'a','l','w','a','y','s','r','u','n',0};
687static const WCHAR canlinkbyole1W[] = {'c','a','n','l','i','n','k','b','y','o','l','e','1',0};
688static const WCHAR cantlinkinsideW[] = {'c','a','n','t','l','i','n','k','i','n','s','i','d','e',0};
689static const WCHAR ignoreactivatewhenvisibleW[] = {'i','g','n','o','r','e','a','c','t','i','v','a','t','e','w','h','e','n','v','i','s','i','b','l','e',0};
690static const WCHAR imemodeW[] = {'i','m','e','m','o','d','e',0};
691static const WCHAR insertnotreplaceW[] = {'i','n','s','e','r','t','n','o','t','r','e','p','l','a','c','e',0};
692static const WCHAR insideoutW[] = {'i','n','s','i','d','e','o','u','t',0};
693static const WCHAR invisibleatruntimeW[] = {'i','n','v','i','s','i','b','l','e','a','t','r','u','n','t','i','m','e',0};
694static const WCHAR islinkobjectW[] = {'i','s','l','i','n','k','o','b','j','e','c','t',0};
695static const WCHAR nouiactivateW[] = {'n','o','u','i','a','c','t','i','v','a','t','e',0};
696static const WCHAR onlyiconicW[] = {'o','n','l','y','i','c','o','n','i','c',0};
697static const WCHAR recomposeonresizeW[] = {'r','e','c','o','m','p','o','s','e','o','n','r','e','s','i','z','e',0};
698static const WCHAR renderingisdeviceindependentW[] = {'r','e','n','d','e','r','i','n','g','i','s','d','e','v','i','c','e','i','n','d','e','p','e','n','d','e','n','t',0};
699static const WCHAR setclientsitefirstW[] = {'s','e','t','c','l','i','e','n','t','s','i','t','e','f','i','r','s','t',0};
700static const WCHAR simpleframeW[] = {'s','i','m','p','l','e','f','r','a','m','e',0};
701static const WCHAR staticW[] = {'s','t','a','t','i','c',0};
702static const WCHAR supportsmultilevelundoW[] = {'s','u','p','p','o','r','t','s','m','u','l','t','i','l','e','v','e','l','u','n','d','o',0};
703static const WCHAR wantstomenumergeW[] = {'w','a','n','t','s','t','o','m','e','n','u','m','e','r','g','e',0};
704
705static const WCHAR compatibilityW[] = {'c','o','m','p','a','t','i','b','i','l','i','t','y',0};
706static const WCHAR compatibilityNSW[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','c','o','m','p','a','t','i','b','i','l','i','t','y','.','v','1',0};
707static const WCHAR applicationW[] = {'a','p','p','l','i','c','a','t','i','o','n',0};
708static const WCHAR supportedOSW[] = {'s','u','p','p','o','r','t','e','d','O','S',0};
709static const WCHAR IdW[] = {'I','d',0};
710static const WCHAR requestedExecutionLevelW[] = {'r','e','q','u','e','s','t','e','d','E','x','e','c','u','t','i','o','n','L','e','v','e','l',0};
711static const WCHAR requestedPrivilegesW[] = {'r','e','q','u','e','s','t','e','d','P','r','i','v','i','l','e','g','e','s',0};
712static const WCHAR securityW[] = {'s','e','c','u','r','i','t','y',0};
713static const WCHAR trustInfoW[] = {'t','r','u','s','t','I','n','f','o',0};
714static const WCHAR windowsSettingsW[] = {'w','i','n','d','o','w','s','S','e','t','t','i','n','g','s',0};
715static const WCHAR autoElevateW[] = {'a','u','t','o','E','l','e','v','a','t','e',0};
716static const WCHAR disableThemingW[] = {'d','i','s','a','b','l','e','T','h','e','m','i','n','g',0};
717static const WCHAR disableWindowFilteringW[] = {'d','i','s','a','b','l','e','W','i','n','d','o','w','F','i','l','t','e','r','i','n','g',0};
718static const WCHAR windowsSettings2005NSW[] = {'h','t','t','p',':','/','/','s','c','h','e','m','a','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','S','M','I','/','2','0','0','5','/','W','i','n','d','o','w','s','S','e','t','t','i','n','g','s',0};
719static const WCHAR windowsSettings2011NSW[] = {'h','t','t','p',':','/','/','s','c','h','e','m','a','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','S','M','I','/','2','0','1','1','/','W','i','n','d','o','w','s','S','e','t','t','i','n','g','s',0};
720static const WCHAR windowsSettings2016NSW[] = {'h','t','t','p',':','/','/','s','c','h','e','m','a','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','S','M','I','/','2','0','1','6','/','W','i','n','d','o','w','s','S','e','t','t','i','n','g','s',0};
721static const WCHAR windowsSettings2017NSW[] = {'h','t','t','p',':','/','/','s','c','h','e','m','a','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','S','M','I','/','2','0','1','7','/','W','i','n','d','o','w','s','S','e','t','t','i','n','g','s',0};
722static const WCHAR dpiAwareW[] = {'d','p','i','A','w','a','r','e',0};
723static const WCHAR dpiAwarenessW[] = {'d','p','i','A','w','a','r','e','n','e','s','s',0};
724static const WCHAR gdiScalingW[] = {'g','d','i','S','c','a','l','i','n','g',0};
725static const WCHAR highResolutionScrollingAwareW[] = {'h','i','g','h','R','e','s','o','l','u','t','i','o','n','S','c','r','o','l','l','i','n','g','A','w','a','r','e',0};
726static const WCHAR longPathAwareW[] = {'l','o','n','g','P','a','t','h','A','w','a','r','e',0};
727static const WCHAR magicFutureSettingW[] = {'m','a','g','i','c','F','u','t','u','r','e','S','e','t','t','i','n','g',0};
728static const WCHAR printerDriverIsolationW[] = {'p','r','i','n','t','e','r','D','r','i','v','e','r','I','s','o','l','a','t','i','o','n',0};
729static const WCHAR ultraHighResolutionScrollingAwareW[] = {'u','l','t','r','a','H','i','g','h','R','e','s','o','l','u','t','i','o','n','S','c','r','o','l','l','i','n','g','A','w','a','r','e',0};
730
732{
733 const WCHAR *name;
735};
736
737static const struct olemisc_entry olemisc_values[] =
738{
761};
762
763static const WCHAR g_xmlW[] = {'?','x','m','l',0};
764
765static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0};
766static const WCHAR version_formatW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
767static const WCHAR wildcardW[] = {'*',0};
768
772
773static WCHAR *strdupW(const WCHAR* str)
774{
775 WCHAR* ptr;
776
777 if (!(ptr = RtlAllocateHeap(GetProcessHeap(), 0, (wcslen(str) + 1) * sizeof(WCHAR))))
778 return NULL;
779 return wcscpy(ptr, str);
780}
781
783{
784 WCHAR *strW;
785
786 if ((strW = RtlAllocateHeap(GetProcessHeap(), 0, (str->len + 1) * sizeof(WCHAR))))
787 {
788 memcpy( strW, str->ptr, str->len * sizeof(WCHAR) );
789 strW[str->len] = 0;
790 }
791 return strW;
792}
793
794static inline BOOL xmlstr_cmp(const xmlstr_t* xmlstr, const WCHAR *str)
795{
796 return !wcsncmp(xmlstr->ptr, str, xmlstr->len) && !str[xmlstr->len];
797}
798
799static inline BOOL xmlstr_cmpi(const xmlstr_t* xmlstr, const WCHAR *str)
800{
801 return !wcsnicmp(xmlstr->ptr, str, xmlstr->len) && !str[xmlstr->len];
802}
803
804static BOOL xml_attr_cmp( const struct xml_attr *attr, const WCHAR *str )
805{
806 return xmlstr_cmp( &attr->name, str );
807}
808
809static BOOL xml_name_cmp( const struct xml_elem *elem1, const struct xml_elem *elem2 )
810{
811 return (elem1->name.len == elem2->name.len &&
812 elem1->ns.len == elem2->ns.len &&
813 !wcsncmp( elem1->name.ptr, elem2->name.ptr, elem1->name.len ) &&
814 !wcsncmp( elem1->ns.ptr, elem2->ns.ptr, elem1->ns.len ));
815}
816
817static inline BOOL xml_elem_cmp(const struct xml_elem *elem, const WCHAR *str, const WCHAR *namespace)
818{
819 if (!xmlstr_cmp( &elem->name, str )) return FALSE;
820 if (xmlstr_cmp( &elem->ns, namespace )) return TRUE;
821 if (!wcscmp( namespace, asmv1W ))
822 {
823 if (xmlstr_cmp( &elem->ns, asmv2W )) return TRUE;
824 if (xmlstr_cmp( &elem->ns, asmv3W )) return TRUE;
825 }
826 else if (!wcscmp( namespace, asmv2W ))
827 {
828 if (xmlstr_cmp( &elem->ns, asmv3W )) return TRUE;
829 }
830 return FALSE;
831}
832
833static inline BOOL isxmlspace( WCHAR ch )
834{
835 return (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t');
836}
837
838static inline const char* debugstr_xmlstr(const xmlstr_t* str)
839{
840 return debugstr_wn(str->ptr, str->len);
841}
842
843static inline const char *debugstr_xml_elem( const struct xml_elem *elem )
844{
845 return wine_dbg_sprintf( "%s ns %s", debugstr_wn( elem->name.ptr, elem->name.len ),
846 debugstr_wn( elem->ns.ptr, elem->ns.len ));
847}
848
849static inline const char *debugstr_xml_attr( const struct xml_attr *attr )
850{
851 return wine_dbg_sprintf( "%s=%s", debugstr_wn( attr->name.ptr, attr->name.len ),
852 debugstr_wn( attr->value.ptr, attr->value.len ));
853}
854
855static inline const char* debugstr_version(const struct assembly_version *ver)
856{
857 return wine_dbg_sprintf("%u.%u.%u.%u", ver->major, ver->minor, ver->build, ver->revision);
858}
859
860static NTSTATUS get_module_filename( HMODULE module, UNICODE_STRING *str, unsigned int extra_len )
861{
863 ULONG_PTR magic;
865
866 LdrLockLoaderLock(0, NULL, &magic);
868 if (status == STATUS_SUCCESS)
869 {
870 if ((str->Buffer = RtlAllocateHeap( GetProcessHeap(), 0,
871 pldr->FullDllName.Length + extra_len + sizeof(WCHAR) )))
872 {
873 memcpy( str->Buffer, pldr->FullDllName.Buffer, pldr->FullDllName.Length + sizeof(WCHAR) );
874 str->Length = pldr->FullDllName.Length;
875 str->MaximumLength = pldr->FullDllName.Length + extra_len + sizeof(WCHAR);
876 }
878 }
879 LdrUnlockLoaderLock(0, magic);
880 return status;
881}
882
884{
885 struct assembly *assembly;
886
887 DPRINT("add_assembly() actctx %p, activeframe ??\n", actctx);
888
889 if (actctx->num_assemblies == actctx->allocated_assemblies)
890 {
891 void *ptr;
892 unsigned int new_count;
893 if (actctx->assemblies)
894 {
895 new_count = actctx->allocated_assemblies * 2;
897 actctx->assemblies, new_count * sizeof(*assembly) );
898 }
899 else
900 {
901 new_count = 4;
902 ptr = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*assembly) );
903 }
904 if (!ptr) return NULL;
905 actctx->assemblies = ptr;
906 actctx->allocated_assemblies = new_count;
907 }
908
909 assembly = &actctx->assemblies[actctx->num_assemblies++];
910 assembly->type = at;
911 return assembly;
912}
913
915{
916 DPRINT("add_dll_redirect() to assembly %p, num_dlls %d\n", assembly, assembly->allocated_dlls);
917
919 {
920 void *ptr;
921 unsigned int new_count;
922 if (assembly->dlls)
923 {
924 new_count = assembly->allocated_dlls * 2;
926 assembly->dlls, new_count * sizeof(*assembly->dlls) );
927 }
928 else
929 {
930 new_count = 4;
931 ptr = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*assembly->dlls) );
932 }
933 if (!ptr) return NULL;
934 assembly->dlls = ptr;
935 assembly->allocated_dlls = new_count;
936 }
937 return &assembly->dlls[assembly->num_dlls++];
938}
939
940static PCOMPATIBILITY_CONTEXT_ELEMENT add_compat_context(struct assembly* assembly)
941{
942 void *ptr;
944 {
945 unsigned int new_count = assembly->num_compat_contexts + 1;
948 new_count * sizeof(COMPATIBILITY_CONTEXT_ELEMENT) );
949 }
950 else
951 {
952 ptr = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(COMPATIBILITY_CONTEXT_ELEMENT) );
953 }
954 if (!ptr) return NULL;
957}
958
960{
961 RtlFreeHeap( GetProcessHeap(), 0, ai->name );
962 RtlFreeHeap( GetProcessHeap(), 0, ai->arch );
965 RtlFreeHeap( GetProcessHeap(), 0, ai->type );
966}
967
969{
970 struct entity* entity;
971
972 if (array->num == array->allocated)
973 {
974 void *ptr;
975 unsigned int new_count;
976 if (array->base)
977 {
978 new_count = array->allocated * 2;
980 array->base, new_count * sizeof(*array->base) );
981 }
982 else
983 {
984 new_count = 4;
985 ptr = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*array->base) );
986 }
987 if (!ptr) return NULL;
988 array->base = ptr;
989 array->allocated = new_count;
990 }
991 entity = &array->base[array->num++];
992 entity->kind = kind;
993 return entity;
994}
995
997{
998 unsigned int i, j;
999 for (i = 0; i < array->num; i++)
1000 {
1001 struct entity *entity = &array->base[i];
1002 switch (entity->kind)
1003 {
1004 case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION:
1009 RtlFreeHeap(GetProcessHeap(), 0, entity->u.comclass.version);
1010 for (j = 0; j < entity->u.comclass.progids.num; j++)
1011 RtlFreeHeap(GetProcessHeap(), 0, entity->u.comclass.progids.progids[j]);
1012 RtlFreeHeap(GetProcessHeap(), 0, entity->u.comclass.progids.progids);
1013 break;
1014 case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION:
1020 break;
1021 case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION:
1023 RtlFreeHeap(GetProcessHeap(), 0, entity->u.typelib.helpdir);
1024 break;
1025 case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION:
1027 break;
1028 case ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES:
1032 break;
1033 case ACTIVATION_CONTEXT_SECTION_APPLICATION_SETTINGS:
1037 break;
1038 default:
1039 FIXME("Unknown entity kind %d\n", entity->kind);
1040 }
1041 }
1042 RtlFreeHeap( GetProcessHeap(), 0, array->base );
1043}
1044
1045static BOOL is_matching_string( const WCHAR *str1, const WCHAR *str2 )
1046{
1047 if (!str1) return !str2;
1048 return str2 && !RtlCompareUnicodeStrings( str1, wcslen(str1), str2, wcslen(str2), TRUE );
1049}
1050
1052 const struct assembly_identity *id2 )
1053{
1054 if (!is_matching_string( id1->name, id2->name )) return FALSE;
1055 if (!is_matching_string( id1->arch, id2->arch )) return FALSE;
1056 if (!is_matching_string( id1->public_key, id2->public_key )) return FALSE;
1057
1058 if (id1->language && id2->language && !is_matching_string( id1->language, id2->language ))
1059 {
1060 if (wcscmp( wildcardW, id1->language ) && wcscmp( wildcardW, id2->language ))
1061 return FALSE;
1062 }
1063 if (id1->version.major != id2->version.major) return FALSE;
1064 if (id1->version.minor != id2->version.minor) return FALSE;
1065 if (id1->version.build > id2->version.build) return FALSE;
1066 if (id1->version.build == id2->version.build &&
1067 id1->version.revision > id2->version.revision) return FALSE;
1068 return TRUE;
1069}
1070
1072 struct assembly_identity* ai)
1073{
1074 unsigned int i;
1075
1076 /* check if we already have that assembly */
1077
1078 for (i = 0; i < acl->actctx->num_assemblies; i++)
1079 if (is_matching_identity( ai, &acl->actctx->assemblies[i].id ))
1080 {
1081 TRACE( "reusing existing assembly for %s arch %s version %u.%u.%u.%u\n",
1082 debugstr_w(ai->name), debugstr_w(ai->arch), ai->version.major, ai->version.minor,
1083 ai->version.build, ai->version.revision );
1084 return TRUE;
1085 }
1086
1087 for (i = 0; i < acl->num_dependencies; i++)
1088 if (is_matching_identity( ai, &acl->dependencies[i] ))
1089 {
1090 TRACE( "reusing existing dependency for %s arch %s version %u.%u.%u.%u\n",
1091 debugstr_w(ai->name), debugstr_w(ai->arch), ai->version.major, ai->version.minor,
1092 ai->version.build, ai->version.revision );
1093 return TRUE;
1094 }
1095
1097 {
1098 void *ptr;
1099 unsigned int new_count;
1100 if (acl->dependencies)
1101 {
1102 new_count = acl->allocated_dependencies * 2;
1104 new_count * sizeof(acl->dependencies[0]));
1105 }
1106 else
1107 {
1108 new_count = 4;
1109 ptr = RtlAllocateHeap(GetProcessHeap(), 0, new_count * sizeof(acl->dependencies[0]));
1110 }
1111 if (!ptr) return FALSE;
1112 acl->dependencies = ptr;
1113 acl->allocated_dependencies = new_count;
1114 }
1115 acl->dependencies[acl->num_dependencies++] = *ai;
1116
1117 return TRUE;
1118}
1119
1120static void free_depend_manifests(struct actctx_loader* acl)
1121{
1122 unsigned int i;
1123 for (i = 0; i < acl->num_dependencies; i++)
1126}
1127
1129{
1130 static const WCHAR undW[] = {'_',0};
1131 static const WCHAR noneW[] = {'n','o','n','e',0};
1132 static const WCHAR mskeyW[] = {'d','e','a','d','b','e','e','f',0};
1133
1134 const WCHAR *arch = ai->arch ? ai->arch : noneW;
1135 const WCHAR *key = ai->public_key ? ai->public_key : noneW;
1136 const WCHAR *lang = ai->language ? ai->language : noneW;
1137 const WCHAR *name = ai->name ? ai->name : noneW;
1138 SIZE_T size = (wcslen(arch) + 1 + wcslen(name) + 1 + wcslen(key) + 24 + 1 +
1139 wcslen(lang) + 1) * sizeof(WCHAR) + sizeof(mskeyW);
1140 WCHAR *ret;
1141
1142 if (!(ret = RtlAllocateHeap( GetProcessHeap(), 0, size ))) return NULL;
1143
1144 wcscpy( ret, arch );
1145 wcscat( ret, undW );
1146 wcscat( ret, name );
1147 wcscat( ret, undW );
1148 wcscat( ret, key );
1149 wcscat( ret, undW );
1151 ai->version.major, ai->version.minor, ai->version.build, ai->version.revision );
1152 wcscat( ret, undW );
1153 wcscat( ret, lang );
1154 wcscat( ret, undW );
1155 wcscat( ret, mskeyW );
1156 return ret;
1157}
1158
1159static inline void append_string( WCHAR *buffer, const WCHAR *prefix, const WCHAR *str )
1160{
1161 WCHAR *p = buffer;
1162
1163 if (!str) return;
1164 wcscat( buffer, prefix );
1165 p += wcslen(p);
1166 *p++ = '"';
1167 wcscpy( p, str );
1168 p += wcslen(p);
1169 *p++ = '"';
1170 *p = 0;
1171}
1172
1173static WCHAR *build_assembly_id( const struct assembly_identity *ai )
1174{
1175 static const WCHAR archW[] =
1176 {',','p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e','=',0};
1177 static const WCHAR public_keyW[] =
1178 {',','p','u','b','l','i','c','K','e','y','T','o','k','e','n','=',0};
1179 static const WCHAR typeW2[] =
1180 {',','t','y','p','e','=',0};
1181 static const WCHAR versionW2[] =
1182 {',','v','e','r','s','i','o','n','=',0};
1183
1184 WCHAR version[64], *ret;
1185 SIZE_T size = 0;
1186
1188 ai->version.major, ai->version.minor, ai->version.build, ai->version.revision );
1189 if (ai->name) size += wcslen(ai->name) * sizeof(WCHAR);
1190 if (ai->arch) size += wcslen(archW) + wcslen(ai->arch) + 2;
1191 if (ai->public_key) size += wcslen(public_keyW) + wcslen(ai->public_key) + 2;
1192 if (ai->type) size += wcslen(typeW2) + wcslen(ai->type) + 2;
1193 size += wcslen(versionW2) + wcslen(version) + 2;
1194
1195 if (!(ret = RtlAllocateHeap( GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR) )))
1196 return NULL;
1197
1198 if (ai->name) wcscpy( ret, ai->name );
1199 else *ret = 0;
1200 append_string( ret, archW, ai->arch );
1201 append_string( ret, public_keyW, ai->public_key );
1202 append_string( ret, typeW2, ai->type );
1203 append_string( ret, versionW2, version );
1204 return ret;
1205}
1206
1208{
1210
1211 if (!h || h == INVALID_HANDLE_VALUE) return NULL;
1212 __TRY
1213 {
1214 if (actctx->magic == ACTCTX_MAGIC) ret = actctx;
1215 }
1217 {
1218 DPRINT1("Invalid activation context handle!\n");
1219 }
1220 __ENDTRY
1221 return ret;
1222}
1223
1225{
1226 InterlockedIncrement( &actctx->ref_count );
1227}
1228
1230{
1231 if (!InterlockedDecrement( &actctx->ref_count ))
1232 {
1233 unsigned int i, j;
1234
1235 for (i = 0; i < actctx->num_assemblies; i++)
1236 {
1237 struct assembly *assembly = &actctx->assemblies[i];
1238 for (j = 0; j < assembly->num_dlls; j++)
1239 {
1240 struct dll_redirect *dll = &assembly->dlls[j];
1241 free_entity_array( &dll->entities );
1242 RtlFreeHeap( GetProcessHeap(), 0, dll->name );
1243 RtlFreeHeap( GetProcessHeap(), 0, dll->hash );
1244 }
1251 }
1252 RtlFreeHeap( GetProcessHeap(), 0, actctx->config.info );
1253 RtlFreeHeap( GetProcessHeap(), 0, actctx->appdir.info );
1254 RtlFreeHeap( GetProcessHeap(), 0, actctx->assemblies );
1255 RtlFreeHeap( GetProcessHeap(), 0, actctx->dllredirect_section );
1256 RtlFreeHeap( GetProcessHeap(), 0, actctx->wndclass_section );
1257 RtlFreeHeap( GetProcessHeap(), 0, actctx->tlib_section );
1258 RtlFreeHeap( GetProcessHeap(), 0, actctx->comserver_section );
1259 RtlFreeHeap( GetProcessHeap(), 0, actctx->ifaceps_section );
1260 RtlFreeHeap( GetProcessHeap(), 0, actctx->clrsurrogate_section );
1261 RtlFreeHeap( GetProcessHeap(), 0, actctx->progid_section );
1262 actctx->magic = 0;
1264 }
1265}
1266
1267static BOOL set_error( xmlbuf_t *xmlbuf )
1268{
1269 xmlbuf->error = TRUE;
1270 return FALSE;
1271}
1272
1273static BOOL is_xmlns_attr( const struct xml_attr *attr )
1274{
1275 const int len = wcslen( xmlnsW );
1276 if (attr->name.len < len) return FALSE;
1277 if (wcsncmp( attr->name.ptr, xmlnsW, len )) return FALSE;
1278 return (attr->name.len == len || attr->name.ptr[len] == ':');
1279}
1280
1281static void push_xmlns( xmlbuf_t *xmlbuf, const struct xml_attr *attr )
1282{
1283 const int len = wcslen( xmlnsW );
1284 struct xml_attr *ns;
1285
1286 if (xmlbuf->ns_pos == MAX_NAMESPACES - 1)
1287 {
1288 FIXME( "too many namespaces in manifest\n" );
1289 set_error( xmlbuf );
1290 return;
1291 }
1292 ns = &xmlbuf->namespaces[xmlbuf->ns_pos++];
1293 ns->value = attr->value;
1294 if (attr->name.len > len)
1295 {
1296 ns->name.ptr = attr->name.ptr + len + 1;
1297 ns->name.len = attr->name.len - len - 1;
1298 }
1299 else ns->name = empty_xmlstr;
1300}
1301
1302static xmlstr_t find_xmlns( xmlbuf_t *xmlbuf, const xmlstr_t *name )
1303{
1304 int i;
1305
1306 for (i = xmlbuf->ns_pos - 1; i >= 0; i--)
1307 {
1308 if (xmlbuf->namespaces[i].name.len == name->len &&
1309 !wcsncmp( xmlbuf->namespaces[i].name.ptr, name->ptr, name->len ))
1310 return xmlbuf->namespaces[i].value;
1311 }
1312 if (xmlbuf->ns_pos) WARN( "namespace %s not found\n", debugstr_xmlstr( name ));
1313 return empty_xmlstr;
1314}
1315
1316static BOOL next_xml_attr(xmlbuf_t *xmlbuf, struct xml_attr *attr, BOOL *end)
1317{
1318 const WCHAR* ptr;
1319 WCHAR quote;
1320
1321 if (xmlbuf->error) return FALSE;
1322
1323 while (xmlbuf->ptr < xmlbuf->end && isxmlspace(*xmlbuf->ptr))
1324 xmlbuf->ptr++;
1325
1326 if (xmlbuf->ptr == xmlbuf->end) return set_error( xmlbuf );
1327
1328 if (*xmlbuf->ptr == '/')
1329 {
1330 xmlbuf->ptr++;
1331 if (xmlbuf->ptr == xmlbuf->end || *xmlbuf->ptr != '>')
1332 return set_error( xmlbuf );
1333
1334 xmlbuf->ptr++;
1335 *end = TRUE;
1336 return FALSE;
1337 }
1338
1339 if (*xmlbuf->ptr == '>')
1340 {
1341 xmlbuf->ptr++;
1342 return FALSE;
1343 }
1344
1345 ptr = xmlbuf->ptr;
1346 while (ptr < xmlbuf->end && *ptr != '=' && *ptr != '>' && !isxmlspace(*ptr)) ptr++;
1347
1348 if (ptr == xmlbuf->end) return set_error( xmlbuf );
1349
1350 attr->name.ptr = xmlbuf->ptr;
1351 attr->name.len = ptr-xmlbuf->ptr;
1352 xmlbuf->ptr = ptr;
1353
1354 /* skip spaces before '=' */
1355 while (ptr < xmlbuf->end && *ptr != '=' && isxmlspace(*ptr)) ptr++;
1356 if (ptr == xmlbuf->end || *ptr != '=') return set_error( xmlbuf );
1357
1358 /* skip '=' itself */
1359 ptr++;
1360 if (ptr == xmlbuf->end) return set_error( xmlbuf );
1361
1362 /* skip spaces after '=' */
1363 while (ptr < xmlbuf->end && *ptr != '"' && *ptr != '\'' && isxmlspace(*ptr)) ptr++;
1364
1365 if (ptr == xmlbuf->end || (*ptr != '"' && *ptr != '\'')) return set_error( xmlbuf );
1366
1367 quote = *ptr++;
1368 attr->value.ptr = ptr;
1369 if (ptr == xmlbuf->end) return set_error( xmlbuf );
1370
1371 while (ptr < xmlbuf->end && *ptr != quote) ptr++;
1372 if (ptr == xmlbuf->end)
1373 {
1374 xmlbuf->ptr = xmlbuf->end;
1375 return set_error( xmlbuf );
1376 }
1377
1378 attr->value.len = ptr - attr->value.ptr;
1379 xmlbuf->ptr = ptr + 1;
1380 if (xmlbuf->ptr != xmlbuf->end) return TRUE;
1381
1382 return set_error( xmlbuf );
1383}
1384
1385static void read_xml_elem( xmlbuf_t *xmlbuf, struct xml_elem *elem )
1386{
1387 const WCHAR* ptr = xmlbuf->ptr;
1388
1389 elem->ns = empty_xmlstr;
1390 elem->name.ptr = ptr;
1391 while (ptr < xmlbuf->end && !isxmlspace(*ptr) && *ptr != '>' && *ptr != '/')
1392 {
1393 if (*ptr == ':')
1394 {
1395 elem->ns.ptr = elem->name.ptr;
1396 elem->ns.len = ptr - elem->ns.ptr;
1397 elem->name.ptr = ptr + 1;
1398 }
1399 ptr++;
1400 }
1401 elem->name.len = ptr - elem->name.ptr;
1402 xmlbuf->ptr = ptr;
1403}
1404
1405static BOOL next_xml_elem( xmlbuf_t *xmlbuf, struct xml_elem *elem, const struct xml_elem *parent )
1406{
1407 const WCHAR* ptr;
1408 struct xml_attr attr;
1409 xmlbuf_t attr_buf;
1410 BOOL end = FALSE;
1411
1412 xmlbuf->ns_pos = parent->ns_pos; /* restore namespace stack to parent state */
1413
1414 if (xmlbuf->error) return FALSE;
1415
1416 for (;;)
1417 {
1418 for (ptr = xmlbuf->ptr; ptr < xmlbuf->end; ptr++) if (*ptr == '<') break;
1419 if (ptr == xmlbuf->end)
1420 {
1421 xmlbuf->ptr = xmlbuf->end;
1422 return set_error( xmlbuf );
1423 }
1424 ptr++;
1425 if (ptr + 3 < xmlbuf->end && ptr[0] == '!' && ptr[1] == '-' && ptr[2] == '-') /* skip comment */
1426 {
1427 for (ptr += 3; ptr + 3 <= xmlbuf->end; ptr++)
1428 if (ptr[0] == '-' && ptr[1] == '-' && ptr[2] == '>') break;
1429
1430 if (ptr + 3 > xmlbuf->end)
1431 {
1432 xmlbuf->ptr = xmlbuf->end;
1433 return set_error( xmlbuf );
1434 }
1435 xmlbuf->ptr = ptr + 3;
1436 }
1437 else break;
1438 }
1439
1440 xmlbuf->ptr = ptr;
1441 /* check for element terminating the parent element */
1442 if (ptr < xmlbuf->end && *ptr == '/')
1443 {
1444 xmlbuf->ptr++;
1445 read_xml_elem( xmlbuf, elem );
1446 elem->ns = find_xmlns( xmlbuf, &elem->ns );
1447 if (!xml_name_cmp( elem, parent ))
1448 {
1449 ERR( "wrong closing element %s for %s\n",
1450 debugstr_xmlstr(&elem->name), debugstr_xmlstr(&parent->name ));
1451 return set_error( xmlbuf );
1452 }
1453 while (xmlbuf->ptr < xmlbuf->end && isxmlspace(*xmlbuf->ptr)) xmlbuf->ptr++;
1454 if (xmlbuf->ptr == xmlbuf->end || *xmlbuf->ptr++ != '>') return set_error( xmlbuf );
1455 return FALSE;
1456 }
1457
1458 read_xml_elem( xmlbuf, elem );
1459
1460 /* parse namespace attributes */
1461 attr_buf = *xmlbuf;
1462 while (next_xml_attr( &attr_buf, &attr, &end ))
1463 {
1464 if (is_xmlns_attr( &attr )) push_xmlns( xmlbuf, &attr );
1465 }
1466 elem->ns = find_xmlns( xmlbuf, &elem->ns );
1467 elem->ns_pos = xmlbuf->ns_pos;
1468
1469 if (xmlbuf->ptr != xmlbuf->end) return TRUE;
1470
1471 return set_error( xmlbuf );
1472}
1473
1475{
1476 /* FIXME: parse attributes */
1477 const WCHAR *ptr;
1478
1479 for (ptr = xmlbuf->ptr; ptr < xmlbuf->end - 1; ptr++)
1480 {
1481 if (ptr[0] == '?' && ptr[1] == '>')
1482 {
1483 xmlbuf->ptr = ptr + 2;
1484 return TRUE;
1485 }
1486 }
1487 return FALSE;
1488}
1489
1491{
1492 const WCHAR *ptr;
1493
1494 if (xmlbuf->error) return FALSE;
1495
1496 for (ptr = xmlbuf->ptr; ptr < xmlbuf->end; ptr++) if (*ptr == '<') break;
1497 if (ptr == xmlbuf->end) return set_error( xmlbuf );
1498
1499 content->ptr = xmlbuf->ptr;
1500 content->len = ptr - xmlbuf->ptr;
1501 xmlbuf->ptr = ptr;
1502
1503 return TRUE;
1504}
1505
1507{
1508 unsigned int ver[4];
1509 unsigned int pos;
1510 const WCHAR *curr;
1511
1512 /* major.minor.build.revision */
1513 ver[0] = ver[1] = ver[2] = ver[3] = pos = 0;
1514 for (curr = str->ptr; curr < str->ptr + str->len; curr++)
1515 {
1516 if (*curr >= '0' && *curr <= '9')
1517 {
1518 ver[pos] = ver[pos] * 10 + *curr - '0';
1519 if (ver[pos] >= 0x10000) goto error;
1520 }
1521 else if (*curr == '.')
1522 {
1523 if (++pos >= 4) goto error;
1524 }
1525 else goto error;
1526 }
1527 version->major = ver[0];
1528 version->minor = ver[1];
1529 version->build = ver[2];
1530 version->revision = ver[3];
1531 return TRUE;
1532
1533error:
1534 FIXME( "Wrong version definition in manifest file (%s)\n", debugstr_xmlstr(str) );
1535 return FALSE;
1536}
1537
1539{
1540 struct xml_attr attr;
1541
1542 while (next_xml_attr(xmlbuf, &attr, end))
1543 {
1544 if (!is_xmlns_attr( &attr )) WARN("unexpected attr %s\n", debugstr_xml_attr(&attr));
1545 }
1546}
1547
1548static void parse_expect_end_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent )
1549{
1550 struct xml_elem elem;
1551
1552 if (next_xml_elem(xmlbuf, &elem, parent))
1553 {
1554 FIXME( "unexpected element %s\n", debugstr_xml_elem(&elem) );
1555 set_error( xmlbuf );
1556 }
1557}
1558
1559static void parse_unknown_elem(xmlbuf_t *xmlbuf, const struct xml_elem *parent)
1560{
1561 struct xml_elem elem;
1562 struct xml_attr attr;
1563 BOOL end = FALSE;
1564
1565 while (next_xml_attr(xmlbuf, &attr, &end));
1566 if (end) return;
1567
1568 while (next_xml_elem(xmlbuf, &elem, parent))
1569 parse_unknown_elem(xmlbuf, &elem);
1570}
1571
1573 struct assembly_identity* ai, const struct xml_elem *parent)
1574{
1575 struct xml_attr attr;
1576 BOOL end = FALSE;
1577
1578 while (next_xml_attr(xmlbuf, &attr, &end))
1579 {
1580 if (xml_attr_cmp(&attr, g_nameW))
1581 {
1582 if (!(ai->name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1583 }
1584 else if (xml_attr_cmp(&attr, typeW))
1585 {
1586 if (!(ai->type = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1587 }
1588 else if (xml_attr_cmp(&attr, versionW))
1589 {
1590 if (!parse_version(&attr.value, &ai->version)) set_error( xmlbuf );
1591 }
1593 {
1594 if (!(ai->arch = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1595 }
1596 else if (xml_attr_cmp(&attr, publicKeyTokenW))
1597 {
1598 if (!(ai->public_key = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1599 }
1600 else if (xml_attr_cmp(&attr, languageW))
1601 {
1602 if (!(ai->language = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1603 }
1604 else if (!is_xmlns_attr( &attr ))
1605 {
1606 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
1607 }
1608 }
1609
1610 TRACE( "name=%s version=%s arch=%s\n",
1612
1613 if (!end) parse_expect_end_elem(xmlbuf, parent);
1614}
1615
1617{
1618 static const WCHAR apartW[] = {'A','p','a','r','t','m','e','n','t',0};
1619 static const WCHAR neutralW[] = {'N','e','u','t','r','a','l',0};
1620 static const WCHAR freeW[] = {'F','r','e','e',0};
1621 static const WCHAR bothW[] = {'B','o','t','h',0};
1622
1623 if (value->len == 0) return ThreadingModel_No;
1624 if (xmlstr_cmp(value, apartW))
1626 else if (xmlstr_cmp(value, freeW))
1627 return ThreadingModel_Free;
1628 else if (xmlstr_cmp(value, bothW))
1629 return ThreadingModel_Both;
1630 else if (xmlstr_cmp(value, neutralW))
1632 else
1633 return ThreadingModel_No;
1634};
1635
1637{
1638 int min, max;
1639
1640 min = 0;
1642
1643 while (min <= max)
1644 {
1645 int n, c;
1646
1647 n = (min+max)/2;
1648
1650 if (!c && !olemisc_values[n].name[len])
1651 return olemisc_values[n].value;
1652
1653 if (c >= 0)
1654 max = n-1;
1655 else
1656 min = n+1;
1657 }
1658
1659 WARN("unknown flag %s\n", debugstr_wn(str, len));
1660 return 0;
1661}
1662
1664{
1665 const WCHAR *str = value->ptr, *start;
1666 DWORD flags = 0;
1667 int i = 0;
1668
1669 /* it's comma separated list of flags */
1670 while (i < value->len)
1671 {
1672 start = str;
1673 while (*str != ',' && (i++ < value->len)) str++;
1674
1676
1677 /* skip separator */
1678 str++;
1679 i++;
1680 }
1681
1682 return flags;
1683}
1684
1686{
1687 struct progids *progids = &entity->u.comclass.progids;
1688
1689 if (progids->allocated == 0)
1690 {
1691 progids->allocated = 4;
1692 if (!(progids->progids = RtlAllocateHeap(GetProcessHeap(), 0, progids->allocated * sizeof(WCHAR*)))) return FALSE;
1693 }
1694
1695 if (progids->allocated == progids->num)
1696 {
1697 WCHAR **new_progids = RtlReAllocateHeap(GetProcessHeap(), 0, progids->progids,
1698 2 * progids->allocated * sizeof(WCHAR*));
1699 if (!new_progids) return FALSE;
1700 progids->allocated *= 2;
1701 progids->progids = new_progids;
1702 }
1703
1704 if (!(progids->progids[progids->num] = xmlstrdupW(progid))) return FALSE;
1705 progids->num++;
1706
1707 return TRUE;
1708}
1709
1710static void parse_com_class_progid(xmlbuf_t *xmlbuf, struct entity *entity, const struct xml_elem *parent)
1711{
1713 BOOL end = FALSE;
1714
1715 parse_expect_no_attr(xmlbuf, &end);
1716 if (end) set_error( xmlbuf );
1717 if (!parse_text_content(xmlbuf, &content)) return;
1718
1719 if (!com_class_add_progid(&content, entity)) set_error( xmlbuf );
1721}
1722
1723static void parse_com_class_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll, struct actctx_loader *acl,
1724 const struct xml_elem *parent )
1725{
1726 struct xml_elem elem;
1727 struct xml_attr attr;
1728 BOOL end = FALSE;
1729 struct entity* entity;
1730
1731 if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)))
1732 {
1733 set_error( xmlbuf );
1734 return;
1735 }
1736
1737 while (next_xml_attr(xmlbuf, &attr, &end))
1738 {
1739 if (xml_attr_cmp(&attr, clsidW))
1740 {
1741 if (!(entity->u.comclass.clsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1742 }
1743 else if (xml_attr_cmp(&attr, progidW))
1744 {
1745 if (!(entity->u.comclass.progid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1746 }
1747 else if (xml_attr_cmp(&attr, tlbidW))
1748 {
1749 if (!(entity->u.comclass.tlbid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1750 }
1751 else if (xml_attr_cmp(&attr, threadingmodelW))
1752 {
1754 }
1755 else if (xml_attr_cmp(&attr, miscstatusW))
1756 {
1758 }
1760 {
1761 entity->u.comclass.miscstatuscontent = parse_com_class_misc(&attr.value);
1762 }
1764 {
1765 entity->u.comclass.miscstatusthumbnail = parse_com_class_misc(&attr.value);
1766 }
1767 else if (xml_attr_cmp(&attr, miscstatusiconW))
1768 {
1769 entity->u.comclass.miscstatusicon = parse_com_class_misc(&attr.value);
1770 }
1772 {
1773 entity->u.comclass.miscstatusdocprint = parse_com_class_misc(&attr.value);
1774 }
1775 else if (xml_attr_cmp(&attr, descriptionW))
1776 {
1777 /* not stored */
1778 }
1779 else if (!is_xmlns_attr( &attr ))
1780 {
1781 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
1782 }
1783 }
1784
1786 if (entity->u.comclass.progid)
1788
1789 if (end) return;
1790
1791 while (next_xml_elem(xmlbuf, &elem, parent))
1792 {
1794 {
1796 }
1797 else
1798 {
1799 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
1800 parse_unknown_elem(xmlbuf, &elem);
1801 }
1802 }
1803
1804 if (entity->u.comclass.progids.num)
1806}
1807
1809{
1810 const WCHAR *curr;
1811 ULONG num = 0;
1812
1813 for (curr = str->ptr; curr < str->ptr + str->len; curr++)
1814 {
1815 if (*curr >= '0' && *curr <= '9')
1816 num = num * 10 + *curr - '0';
1817 else
1818 {
1819 ERR("wrong numeric value %s\n", debugstr_xmlstr(str));
1820 return FALSE;
1821 }
1822 }
1823 entity->u.ifaceps.nummethods = num;
1824
1825 return TRUE;
1826}
1827
1828static void parse_add_interface_class( xmlbuf_t *xmlbuf, struct entity_array *entities,
1829 struct actctx_loader *acl, WCHAR *clsid )
1830{
1831 struct entity *entity;
1832 WCHAR *str;
1833
1834 if (!clsid) return;
1835
1836 if (!(str = strdupW(clsid)))
1837 {
1838 set_error( xmlbuf );
1839 return;
1840 }
1841
1842 if (!(entity = add_entity(entities, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)))
1843 {
1845 set_error( xmlbuf );
1846 return;
1847 }
1848
1849 entity->u.comclass.clsid = str;
1851
1853}
1854
1856 struct actctx_loader *acl, const struct xml_elem *parent )
1857{
1858 WCHAR *psclsid = NULL;
1859 struct entity *entity;
1860 struct xml_attr attr;
1861 BOOL end = FALSE;
1862
1863 if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION)))
1864 {
1865 set_error( xmlbuf );
1866 return;
1867 }
1868
1869 while (next_xml_attr(xmlbuf, &attr, &end))
1870 {
1871 if (xml_attr_cmp(&attr, iidW))
1872 {
1873 if (!(entity->u.ifaceps.iid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1874 }
1875 else if (xml_attr_cmp(&attr, g_nameW))
1876 {
1877 if (!(entity->u.ifaceps.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1878 }
1879 else if (xml_attr_cmp(&attr, baseInterfaceW))
1880 {
1881 if (!(entity->u.ifaceps.base = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1882 entity->u.ifaceps.mask |= BaseIface;
1883 }
1884 else if (xml_attr_cmp(&attr, nummethodsW))
1885 {
1886 if (!(parse_nummethods(&attr.value, entity))) set_error( xmlbuf );
1887 entity->u.ifaceps.mask |= NumMethods;
1888 }
1889 else if (xml_attr_cmp(&attr, tlbidW))
1890 {
1891 if (!(entity->u.ifaceps.tlib = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1892 }
1894 {
1895 if (!(psclsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1896 }
1897 /* not used */
1898 else if (xml_attr_cmp(&attr, threadingmodelW))
1899 {
1900 }
1901 else if (!is_xmlns_attr( &attr ))
1902 {
1903 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
1904 }
1905 }
1906
1908 if (!end) parse_expect_end_elem(xmlbuf, parent);
1909
1910 parse_add_interface_class(xmlbuf, &dll->entities, acl, psclsid ? psclsid : entity->u.ifaceps.iid);
1911
1912 RtlFreeHeap(GetProcessHeap(), 0, psclsid);
1913}
1914
1916{
1917 WORD *flags = &entity->u.typelib.flags;
1918 const WCHAR *str = value->ptr, *start;
1919 int i = 0;
1920
1921 *flags = 0;
1922
1923 /* it's comma separated list of flags */
1924 while (i < value->len)
1925 {
1926 start = str;
1927 while (*str != ',' && (i++ < value->len)) str++;
1928
1931 else if (!wcsnicmp(start, controlW, str-start))
1933 else if (!wcsnicmp(start, hiddenW, str-start))
1935 else if (!wcsnicmp(start, hasdiskimageW, str-start))
1937 else
1938 {
1939 WARN("unknown flags value %s\n", debugstr_xmlstr(value));
1940 return FALSE;
1941 }
1942
1943 /* skip separator */
1944 str++;
1945 i++;
1946 }
1947
1948 return TRUE;
1949}
1950
1952{
1953 unsigned int ver[2];
1954 unsigned int pos;
1955 const WCHAR *curr;
1956
1957 /* major.minor */
1958 ver[0] = ver[1] = pos = 0;
1959 for (curr = str->ptr; curr < str->ptr + str->len; curr++)
1960 {
1961 if (*curr >= '0' && *curr <= '9')
1962 {
1963 ver[pos] = ver[pos] * 10 + *curr - '0';
1964 if (ver[pos] >= 0x10000) goto error;
1965 }
1966 else if (*curr == '.')
1967 {
1968 if (++pos >= 2) goto error;
1969 }
1970 else goto error;
1971 }
1972 entity->u.typelib.major = ver[0];
1973 entity->u.typelib.minor = ver[1];
1974 return TRUE;
1975
1976error:
1977 FIXME("wrong typelib version value (%s)\n", debugstr_xmlstr(str));
1978 return FALSE;
1979}
1980
1981static void parse_typelib_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll,
1982 struct actctx_loader *acl, const struct xml_elem *parent )
1983{
1984 struct xml_attr attr;
1985 BOOL end = FALSE;
1986 struct entity* entity;
1987
1988 if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION)))
1989 {
1990 set_error( xmlbuf );
1991 return;
1992 }
1993
1994 while (next_xml_attr(xmlbuf, &attr, &end))
1995 {
1996 if (xml_attr_cmp(&attr, tlbidW))
1997 {
1998 if (!(entity->u.typelib.tlbid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1999 }
2000 else if (xml_attr_cmp(&attr, versionW))
2001 {
2002 if (!parse_typelib_version(&attr.value, entity)) set_error( xmlbuf );
2003 }
2004 else if (xml_attr_cmp(&attr, helpdirW))
2005 {
2006 if (!(entity->u.typelib.helpdir = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2007 }
2008 else if (xml_attr_cmp(&attr, flagsW))
2009 {
2010 if (!parse_typelib_flags(&attr.value, entity)) set_error( xmlbuf );
2011 }
2012 else if (!is_xmlns_attr( &attr ))
2013 {
2014 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2015 }
2016 }
2017
2019 if (!end) parse_expect_end_elem(xmlbuf, parent);
2020}
2021
2022static inline int aligned_string_len(int len)
2023{
2024 return (len + 3) & ~3;
2025}
2026
2028{
2029 static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
2030 struct assembly_version *ver = &assembly->id.version;
2031 WCHAR buff[25];
2032
2033 if (!ret) ret = buff;
2034 return swprintf(ret, ARRAY_SIZE(buff), fmtW, ver->major, ver->minor, ver->build, ver->revision);
2035}
2036
2037static void parse_window_class_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll,
2038 struct actctx_loader *acl, const struct xml_elem *parent )
2039{
2040 struct xml_elem elem;
2041 struct xml_attr attr;
2043 BOOL end = FALSE;
2044 struct entity* entity;
2045
2046 if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION)))
2047 {
2048 set_error( xmlbuf );
2049 return;
2050 }
2051 entity->u.class.versioned = TRUE;
2052 while (next_xml_attr(xmlbuf, &attr, &end))
2053 {
2055 {
2056 if (xmlstr_cmpi(&attr.value, noW))
2057 entity->u.class.versioned = FALSE;
2058 else if (!xmlstr_cmpi(&attr.value, yesW))
2059 set_error( xmlbuf );
2060 }
2061 else if (!is_xmlns_attr( &attr ))
2062 {
2063 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2064 }
2065 }
2066
2067 if (end) return;
2068
2069 if (!parse_text_content(xmlbuf, &content)) return;
2070 if (!(entity->u.class.name = xmlstrdupW(&content))) set_error( xmlbuf );
2071
2073
2074 while (next_xml_elem(xmlbuf, &elem, parent))
2075 {
2076 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2077 parse_unknown_elem(xmlbuf, &elem);
2078 }
2079}
2080
2081static void parse_binding_redirect_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent )
2082{
2083 struct xml_attr attr;
2084 BOOL end = FALSE;
2085
2086 while (next_xml_attr(xmlbuf, &attr, &end))
2087 {
2089 {
2090 FIXME("Not stored yet %s\n", debugstr_xml_attr(&attr));
2091 }
2092 else if (xml_attr_cmp(&attr, newVersionW))
2093 {
2094 FIXME("Not stored yet %s\n", debugstr_xml_attr(&attr));
2095 }
2096 else if (!is_xmlns_attr( &attr ))
2097 {
2098 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2099 }
2100 }
2101
2102 if (!end) parse_expect_end_elem(xmlbuf, parent);
2103}
2104
2105static void parse_description_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent )
2106{
2107 struct xml_elem elem;
2108 struct xml_attr attr;
2110 BOOL end = FALSE;
2111
2112 while (next_xml_attr(xmlbuf, &attr, &end))
2113 {
2114 if (!is_xmlns_attr( &attr )) WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2115 }
2116
2117 if (end) return;
2118 if (!parse_text_content(xmlbuf, &content)) return;
2119
2120 TRACE("Got description %s\n", debugstr_xmlstr(&content));
2121
2122 while (next_xml_elem(xmlbuf, &elem, parent))
2123 {
2124 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2125 parse_unknown_elem(xmlbuf, &elem);
2126 }
2127}
2128
2130 struct assembly* assembly,
2131 struct actctx_loader* acl,
2132 const struct xml_elem *parent)
2133{
2134 struct xml_attr attr;
2135 BOOL end = FALSE;
2136 struct entity* entity;
2137
2138 if (!(entity = add_entity(&assembly->entities, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION)))
2139 {
2140 set_error( xmlbuf );
2141 return;
2142 }
2143
2144 while (next_xml_attr(xmlbuf, &attr, &end))
2145 {
2146 if (xml_attr_cmp(&attr, iidW))
2147 {
2148 if (!(entity->u.ifaceps.iid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2149 }
2150 else if (xml_attr_cmp(&attr, g_nameW))
2151 {
2152 if (!(entity->u.ifaceps.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2153 }
2154 else if (xml_attr_cmp(&attr, baseInterfaceW))
2155 {
2156 if (!(entity->u.ifaceps.base = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2157 entity->u.ifaceps.mask |= BaseIface;
2158 }
2159 else if (xml_attr_cmp(&attr, nummethodsW))
2160 {
2161 if (!(parse_nummethods(&attr.value, entity))) set_error( xmlbuf );
2162 entity->u.ifaceps.mask |= NumMethods;
2163 }
2165 {
2166 if (!(entity->u.ifaceps.ps32 = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2167 }
2168 else if (xml_attr_cmp(&attr, tlbidW))
2169 {
2170 if (!(entity->u.ifaceps.tlib = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2171 }
2172 else if (!is_xmlns_attr( &attr ))
2173 {
2174 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2175 }
2176 }
2177
2179 if (!end) parse_expect_end_elem(xmlbuf, parent);
2180}
2181
2182static void parse_clr_class_elem( xmlbuf_t* xmlbuf, struct assembly* assembly,
2183 struct actctx_loader *acl, const struct xml_elem *parent )
2184
2185{
2186 struct xml_elem elem;
2187 struct xml_attr attr;
2188 BOOL end = FALSE;
2189 struct entity* entity;
2190
2191 if (!(entity = add_entity(&assembly->entities, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)))
2192 {
2193 set_error( xmlbuf );
2194 return;
2195 }
2196
2197 while (next_xml_attr(xmlbuf, &attr, &end))
2198 {
2199 if (xml_attr_cmp(&attr, g_nameW))
2200 {
2201 if (!(entity->u.comclass.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2202 }
2203 else if (xml_attr_cmp(&attr, clsidW))
2204 {
2205 if (!(entity->u.comclass.clsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2206 }
2207 else if (xml_attr_cmp(&attr, progidW))
2208 {
2209 if (!(entity->u.comclass.progid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2210 }
2211 else if (xml_attr_cmp(&attr, tlbidW))
2212 {
2213 if (!(entity->u.comclass.tlbid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2214 }
2215 else if (xml_attr_cmp(&attr, threadingmodelW))
2216 {
2218 }
2219 else if (xml_attr_cmp(&attr, runtimeVersionW))
2220 {
2221 if (!(entity->u.comclass.version = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2222 }
2223 else if (!is_xmlns_attr( &attr ))
2224 {
2225 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2226 }
2227 }
2228
2230 if (entity->u.comclass.progid)
2232 if (end) return;
2233
2234 while (next_xml_elem(xmlbuf, &elem, parent))
2235 {
2237 {
2239 }
2240 else
2241 {
2242 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2243 parse_unknown_elem(xmlbuf, &elem);
2244 }
2245 }
2246
2247 if (entity->u.comclass.progids.num)
2249}
2250
2252 struct actctx_loader *acl, const struct xml_elem *parent )
2253{
2254 struct xml_attr attr;
2255 BOOL end = FALSE;
2256 struct entity* entity;
2257
2258 if (!(entity = add_entity(&assembly->entities, ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES)))
2259 {
2260 set_error( xmlbuf );
2261 return;
2262 }
2263
2264 while (next_xml_attr(xmlbuf, &attr, &end))
2265 {
2266 if (xml_attr_cmp(&attr, g_nameW))
2267 {
2268 if (!(entity->u.clrsurrogate.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2269 }
2270 else if (xml_attr_cmp(&attr, clsidW))
2271 {
2272 if (!(entity->u.clrsurrogate.clsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2273 }
2274 else if (xml_attr_cmp(&attr, runtimeVersionW))
2275 {
2276 if (!(entity->u.clrsurrogate.version = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2277 }
2278 else if (!is_xmlns_attr( &attr ))
2279 {
2280 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2281 }
2282 }
2283
2285 if (!end) parse_expect_end_elem(xmlbuf, parent);
2286}
2287
2288static void parse_dependent_assembly_elem( xmlbuf_t *xmlbuf, struct actctx_loader *acl,
2289 const struct xml_elem *parent, BOOL optional )
2290{
2291 struct xml_elem elem;
2292 struct xml_attr attr;
2293 struct assembly_identity ai;
2294 BOOL end = FALSE;
2295
2296 memset(&ai, 0, sizeof(ai));
2297 ai.optional = optional;
2298
2299 while (next_xml_attr(xmlbuf, &attr, &end))
2300 {
2301 static const WCHAR allowDelayedBindingW[] = {'a','l','l','o','w','D','e','l','a','y','e','d','B','i','n','d','i','n','g',0};
2302 static const WCHAR trueW[] = {'t','r','u','e',0};
2303
2304 if (xml_attr_cmp(&attr, allowDelayedBindingW))
2306 else if (!is_xmlns_attr( &attr ))
2307 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2308 }
2309
2310 if (end) return;
2311
2312 while (next_xml_elem(xmlbuf, &elem, parent))
2313 {
2315 {
2316 parse_assembly_identity_elem(xmlbuf, acl->actctx, &ai, &elem);
2317 /* store the newly found identity for later loading */
2318 if (ai.arch && !wcscmp(ai.arch, wildcardW))
2319 {
2320 RtlFreeHeap( GetProcessHeap(), 0, ai.arch );
2321 ai.arch = strdupW( current_archW );
2322 }
2323 TRACE( "adding name=%s version=%s arch=%s\n",
2325 if (!add_dependent_assembly_id(acl, &ai)) set_error( xmlbuf );
2326 }
2328 {
2330 }
2331 else
2332 {
2333 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2334 parse_unknown_elem(xmlbuf, &elem);
2335 }
2336 }
2337}
2338
2339static void parse_dependency_elem( xmlbuf_t *xmlbuf, struct actctx_loader *acl,
2340 const struct xml_elem *parent )
2341
2342{
2343 struct xml_elem elem;
2344 struct xml_attr attr;
2346
2347 while (next_xml_attr(xmlbuf, &attr, &end))
2348 {
2350 {
2352 TRACE("optional=%s\n", debugstr_xmlstr(&attr.value));
2353 }
2354 else if (!is_xmlns_attr( &attr ))
2355 {
2356 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2357 }
2358 }
2359
2360 while (next_xml_elem(xmlbuf, &elem, parent))
2361 {
2363 {
2365 }
2366 else
2367 {
2368 WARN("unknown element %s\n", debugstr_xml_elem(&elem));
2369 parse_unknown_elem(xmlbuf, &elem);
2370 }
2371 }
2372}
2373
2374static void parse_noinherit_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent )
2375{
2376 BOOL end = FALSE;
2377
2378 parse_expect_no_attr(xmlbuf, &end);
2379 if (!end) parse_expect_end_elem(xmlbuf, parent);
2380}
2381
2382static void parse_noinheritable_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent )
2383{
2384 BOOL end = FALSE;
2385
2386 parse_expect_no_attr(xmlbuf, &end);
2387 if (!end) parse_expect_end_elem(xmlbuf, parent);
2388}
2389
2390static void parse_file_elem( xmlbuf_t* xmlbuf, struct assembly* assembly,
2391 struct actctx_loader* acl, const struct xml_elem *parent )
2392{
2393 struct xml_elem elem;
2394 struct xml_attr attr;
2395 BOOL end = FALSE;
2396 struct dll_redirect* dll;
2397
2398 if (!(dll = add_dll_redirect(assembly)))
2399 {
2400 set_error( xmlbuf );
2401 return;
2402 }
2403
2404 while (next_xml_attr(xmlbuf, &attr, &end))
2405 {
2406 if (xml_attr_cmp(&attr, g_nameW))
2407 {
2408 if (!(dll->name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2409 TRACE("name=%s\n", debugstr_xmlstr(&attr.value));
2410 }
2411 else if (xml_attr_cmp(&attr, hashW))
2412 {
2413 if (!(dll->hash = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2414 }
2415 else if (xml_attr_cmp(&attr, hashalgW))
2416 {
2417 static const WCHAR sha1W[] = {'S','H','A','1',0};
2418 if (!xmlstr_cmpi(&attr.value, sha1W))
2419 FIXME("hashalg should be SHA1, got %s\n", debugstr_xmlstr(&attr.value));
2420 }
2421 else if (!is_xmlns_attr( &attr ))
2422 {
2423 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2424 }
2425 }
2426
2427 if (!dll->name) set_error( xmlbuf );
2428
2430
2431 if (end) return;
2432
2433 while (next_xml_elem(xmlbuf, &elem, parent))
2434 {
2436 {
2437 parse_com_class_elem(xmlbuf, dll, acl, &elem);
2438 }
2440 {
2442 }
2443 else if (xml_elem_cmp(&elem, hashW, asmv2W))
2444 {
2445 WARN("asmv2:hash (undocumented) not supported\n");
2446 parse_unknown_elem(xmlbuf, &elem);
2447 }
2448 else if (xml_elem_cmp(&elem, typelibW, asmv1W))
2449 {
2450 parse_typelib_elem(xmlbuf, dll, acl, &elem);
2451 }
2452 else if (xml_elem_cmp(&elem, windowClassW, asmv1W))
2453 {
2454 parse_window_class_elem(xmlbuf, dll, acl, &elem);
2455 }
2456 else
2457 {
2458 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2459 parse_unknown_elem( xmlbuf, &elem );
2460 }
2461 }
2462}
2463
2464static void parse_supportedos_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
2465 struct actctx_loader *acl, const struct xml_elem *parent )
2466{
2467 struct xml_attr attr;
2468 BOOL end = FALSE;
2469
2470 while (next_xml_attr(xmlbuf, &attr, &end))
2471 {
2472 if (xml_attr_cmp(&attr, IdW))
2473 {
2474 COMPATIBILITY_CONTEXT_ELEMENT *compat;
2476 GUID compat_id;
2477
2478 str.Buffer = (PWSTR)attr.value.ptr;
2479 str.Length = str.MaximumLength = (USHORT)attr.value.len * sizeof(WCHAR);
2480 if (RtlGUIDFromString(&str, &compat_id) == STATUS_SUCCESS)
2481 {
2482 if (!(compat = add_compat_context(assembly)))
2483 {
2484 set_error( xmlbuf );
2485 return;
2486 }
2487 compat->Type = ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS;
2488 compat->Id = compat_id;
2489 }
2490 else
2491 {
2492 WARN("Invalid guid %s\n", debugstr_xmlstr(&attr.value));
2493 }
2494 }
2495 else if (!is_xmlns_attr( &attr ))
2496 {
2497 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2498 }
2499 }
2500
2501 if (!end) parse_expect_end_elem(xmlbuf, parent);
2502}
2503
2505 struct actctx_loader* acl, const struct xml_elem *parent)
2506{
2507 struct xml_elem elem;
2508
2509 while (next_xml_elem(xmlbuf, &elem, parent))
2510 {
2512 {
2513 parse_supportedos_elem(xmlbuf, assembly, acl, &elem);
2514 }
2515 else
2516 {
2517 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2518 parse_unknown_elem(xmlbuf, &elem);
2519 }
2520 }
2521}
2522
2524 struct actctx_loader* acl, const struct xml_elem *parent)
2525{
2526 struct xml_elem elem;
2527
2528 while (next_xml_elem(xmlbuf, &elem, parent))
2529 {
2531 {
2533 }
2534 else
2535 {
2536 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2537 parse_unknown_elem(xmlbuf, &elem);
2538 }
2539 }
2540}
2541
2542static void parse_settings_elem( xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl,
2543 struct xml_elem *parent )
2544{
2545 struct xml_elem elem;
2546 struct xml_attr attr;
2548 BOOL end = FALSE;
2549 struct entity *entity;
2550
2551 while (next_xml_attr( xmlbuf, &attr, &end ))
2552 {
2553 if (!is_xmlns_attr( &attr )) WARN( "unknown attr %s\n", debugstr_xml_attr(&attr) );
2554 }
2555
2556 if (end) return;
2557
2558 if (!parse_text_content( xmlbuf, &content )) return;
2559 TRACE( "got %s %s\n", debugstr_xmlstr(&parent->name), debugstr_xmlstr(&content) );
2560
2561 entity = add_entity( &assembly->entities, ACTIVATION_CONTEXT_SECTION_APPLICATION_SETTINGS );
2562 if (!entity)
2563 {
2564 set_error( xmlbuf );
2565 return;
2566 }
2567 entity->u.settings.name = xmlstrdupW( &parent->name );
2568 entity->u.settings.value = xmlstrdupW( &content );
2569 entity->u.settings.ns = xmlstrdupW( &parent->ns );
2570
2571 while (next_xml_elem(xmlbuf, &elem, parent))
2572 {
2573 WARN( "unknown elem %s\n", debugstr_xml_elem(&elem) );
2574 parse_unknown_elem( xmlbuf, &elem );
2575 }
2576}
2577
2579 struct actctx_loader *acl, const struct xml_elem *parent )
2580{
2581 struct xml_elem elem;
2582
2583 while (next_xml_elem( xmlbuf, &elem, parent ))
2584 {
2596 {
2597 parse_settings_elem( xmlbuf, assembly, acl, &elem );
2598 }
2599 else
2600 {
2601 WARN( "unknown elem %s\n", debugstr_xml_elem(&elem) );
2602 parse_unknown_elem( xmlbuf, &elem );
2603 }
2604 }
2605}
2606
2607static void parse_application_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
2608 struct actctx_loader *acl, const struct xml_elem *parent )
2609{
2610 struct xml_elem elem;
2611
2612 while (next_xml_elem( xmlbuf, &elem, parent ))
2613 {
2615 {
2616 parse_windows_settings_elem( xmlbuf, assembly, acl, &elem );
2617 }
2618 else
2619 {
2620 WARN( "unknown elem %s\n", debugstr_xml_elem(&elem) );
2621 parse_unknown_elem( xmlbuf, &elem );
2622 }
2623 }
2624}
2625
2627 struct actctx_loader *acl, const struct xml_elem *parent )
2628{
2629 static const WCHAR levelW[] = {'l','e','v','e','l',0};
2630 static const WCHAR asInvokerW[] = {'a','s','I','n','v','o','k','e','r',0};
2631 static const WCHAR requireAdministratorW[] = {'r','e','q','u','i','r','e','A','d','m','i','n','i','s','t','r','a','t','o','r',0};
2632 static const WCHAR highestAvailableW[] = {'h','i','g','h','e','s','t','A','v','a','i','l','a','b','l','e',0};
2633 static const WCHAR uiAccessW[] = {'u','i','A','c','c','e','s','s',0};
2634 static const WCHAR falseW[] = {'f','a','l','s','e',0};
2635 static const WCHAR trueW[] = {'t','r','u','e',0};
2636
2637 struct xml_elem elem;
2638 struct xml_attr attr;
2639 BOOL end = FALSE;
2640
2641 /* Multiple requestedExecutionLevel elements are not supported. */
2642 if (assembly->run_level != ACTCTX_RUN_LEVEL_UNSPECIFIED) set_error( xmlbuf );
2643
2644 while (next_xml_attr(xmlbuf, &attr, &end))
2645 {
2646 if (xml_attr_cmp(&attr, levelW))
2647 {
2648 if (xmlstr_cmpi(&attr.value, asInvokerW))
2649 assembly->run_level = ACTCTX_RUN_LEVEL_AS_INVOKER;
2650 else if (xmlstr_cmpi(&attr.value, highestAvailableW))
2651 assembly->run_level = ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE;
2652 else if (xmlstr_cmpi(&attr.value, requireAdministratorW))
2653 assembly->run_level = ACTCTX_RUN_LEVEL_REQUIRE_ADMIN;
2654 else
2655 FIXME("unknown execution level: %s\n", debugstr_xmlstr(&attr.value));
2656 }
2657 else if (xml_attr_cmp(&attr, uiAccessW))
2658 {
2661 else if (xmlstr_cmpi(&attr.value, trueW))
2663 else
2664 FIXME("unknown uiAccess value: %s\n", debugstr_xmlstr(&attr.value));
2665 }
2666 else if (!is_xmlns_attr( &attr ))
2667 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2668 }
2669
2670 if (end) return;
2671
2672 while (next_xml_elem(xmlbuf, &elem, parent))
2673 {
2674 WARN("unknown element %s\n", debugstr_xml_elem(&elem));
2675 parse_unknown_elem(xmlbuf, &elem);
2676 }
2677}
2678
2680 struct actctx_loader *acl, const struct xml_elem *parent )
2681{
2682 struct xml_elem elem;
2683
2684 while (next_xml_elem(xmlbuf, &elem, parent))
2685 {
2687 {
2689 }
2690 else
2691 {
2692 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2693 parse_unknown_elem(xmlbuf, &elem);
2694 }
2695 }
2696}
2697
2698static void parse_security_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
2699 struct actctx_loader *acl, const struct xml_elem *parent )
2700{
2701 struct xml_elem elem;
2702
2703 while (next_xml_elem(xmlbuf, &elem, parent))
2704 {
2706 {
2708 }
2709 else
2710 {
2711 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2712 parse_unknown_elem(xmlbuf, &elem);
2713 }
2714 }
2715}
2716
2717static void parse_trust_info_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
2718 struct actctx_loader *acl, const struct xml_elem *parent )
2719{
2720 struct xml_elem elem;
2721
2722 while (next_xml_elem(xmlbuf, &elem, parent))
2723 {
2725 {
2726 parse_security_elem(xmlbuf, assembly, acl, &elem);
2727 }
2728 else
2729 {
2730 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2731 parse_unknown_elem(xmlbuf, &elem);
2732 }
2733 }
2734}
2735
2736static void parse_assembly_elem( xmlbuf_t *xmlbuf, struct assembly* assembly,
2737 struct actctx_loader* acl, const struct xml_elem *parent,
2738 struct assembly_identity* expected_ai)
2739{
2740 struct xml_elem elem;
2741 struct xml_attr attr;
2742 BOOL end = FALSE, version = FALSE;
2743
2744 TRACE("(%p)\n", xmlbuf);
2745
2746 while (next_xml_attr(xmlbuf, &attr, &end))
2747 {
2749 {
2750 static const WCHAR v10W[] = {'1','.','0',0};
2751 if (!xmlstr_cmp(&attr.value, v10W))
2752 {
2753 FIXME("wrong version %s\n", debugstr_xmlstr(&attr.value));
2754 break;
2755 }
2756 version = TRUE;
2757 }
2758 else if (!is_xmlns_attr( &attr ))
2759 {
2760 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2761 }
2762 }
2763
2764 if (end || !version)
2765 {
2766 set_error( xmlbuf );
2767 return;
2768 }
2769
2770 while (next_xml_elem(xmlbuf, &elem, parent))
2771 {
2773 {
2774 parse_noinherit_elem(xmlbuf, &elem);
2776 }
2778 {
2780 }
2781 else if (xml_elem_cmp(&elem, descriptionW, asmv1W))
2782 {
2783 parse_description_elem(xmlbuf, &elem);
2784 }
2786 {
2788 }
2789 else if (xml_elem_cmp(&elem, dependencyW, asmv1W))
2790 {
2791 parse_dependency_elem(xmlbuf, acl, &elem);
2792 }
2793 else if (xml_elem_cmp(&elem, fileW, asmv1W))
2794 {
2795 parse_file_elem(xmlbuf, assembly, acl, &elem);
2796 }
2797 else if (xml_elem_cmp(&elem, clrClassW, asmv1W))
2798 {
2799 parse_clr_class_elem(xmlbuf, assembly, acl, &elem);
2800 }
2802 {
2803 parse_clr_surrogate_elem(xmlbuf, assembly, acl, &elem);
2804 }
2805 else if (xml_elem_cmp(&elem, trustInfoW, asmv1W))
2806 {
2807 parse_trust_info_elem(xmlbuf, assembly, acl, &elem);
2808 }
2810 {
2812
2813 if (!xmlbuf->error && expected_ai)
2814 {
2815 /* FIXME: more tests */
2817 memcmp(&assembly->id.version, &expected_ai->version, sizeof(assembly->id.version)))
2818 {
2819 FIXME("wrong version for assembly manifest: %u.%u.%u.%u / %u.%u.%u.%u\n",
2820 expected_ai->version.major, expected_ai->version.minor,
2821 expected_ai->version.build, expected_ai->version.revision,
2822 assembly->id.version.major, assembly->id.version.minor,
2823 assembly->id.version.build, assembly->id.version.revision);
2824 set_error( xmlbuf );
2825 }
2826 else if (assembly->type == ASSEMBLY_SHARED_MANIFEST &&
2827 (assembly->id.version.major != expected_ai->version.major ||
2828 assembly->id.version.minor != expected_ai->version.minor ||
2829 assembly->id.version.build < expected_ai->version.build ||
2830 (assembly->id.version.build == expected_ai->version.build &&
2831 assembly->id.version.revision < expected_ai->version.revision)))
2832 {
2833 FIXME("wrong version for shared assembly manifest\n");
2834 set_error( xmlbuf );
2835 }
2836 }
2837 }
2839 {
2840 parse_compatibility_elem(xmlbuf, assembly, acl, &elem);
2841 }
2842 else if (xml_elem_cmp(&elem, applicationW, asmv3W))
2843 {
2844 parse_application_elem(xmlbuf, assembly, acl, &elem);
2845 }
2846 else
2847 {
2848 WARN("unknown element %s\n", debugstr_xml_elem(&elem));
2849 parse_unknown_elem(xmlbuf, &elem);
2850 }
2851 }
2852
2855 {
2856 set_error( xmlbuf );
2857 }
2858}
2859
2861 struct assembly_identity* ai, xmlbuf_t *xmlbuf )
2862{
2863 struct xml_elem elem;
2864 struct xml_elem parent = {0};
2865
2866 xmlbuf->error = FALSE;
2867 xmlbuf->ns_pos = 0;
2868
2869 if (!next_xml_elem(xmlbuf, &elem, &parent)) return STATUS_SXS_CANT_GEN_ACTCTX;
2870
2871 if (xmlstr_cmp(&elem.name, g_xmlW) &&
2872 (!parse_xml_header(xmlbuf) || !next_xml_elem(xmlbuf, &elem, &parent)))
2874
2876 {
2877 FIXME("root element is %s, not <assembly>\n", debugstr_xml_elem(&elem));
2879 }
2880
2881 parse_assembly_elem(xmlbuf, assembly, acl, &elem, ai);
2882 if (xmlbuf->error)
2883 {
2884 FIXME("failed to parse manifest %s\n", debugstr_w(assembly->manifest.info) );
2886 }
2887
2888 if (next_xml_elem(xmlbuf, &elem, &parent))
2889 {
2890 FIXME("unexpected element %s\n", debugstr_xml_elem(&elem));
2892 }
2893
2894 if (xmlbuf->ptr != xmlbuf->end)
2895 {
2896 FIXME("parse error\n");
2898 }
2899 return STATUS_SUCCESS;
2900}
2901
2904 const void *buffer, SIZE_T size )
2905{
2906 xmlbuf_t xmlbuf;
2908 struct assembly *assembly;
2909 int unicode_tests;
2910
2911 TRACE( "parsing manifest loaded from %s base dir %s\n", debugstr_w(filename), debugstr_w(directory) );
2912
2915
2917 return STATUS_NO_MEMORY;
2918
2919 if (!filename)
2920 {
2921 UNICODE_STRING module_path;
2922 if ((status = get_module_filename( module, &module_path, 0 ))) return status;
2923 assembly->manifest.info = module_path.Buffer;
2924 }
2925 else if(!(assembly->manifest.info = strdupW( filename + 4 /* skip \??\ prefix */ ))) return STATUS_NO_MEMORY;
2926
2927 assembly->manifest.type = assembly->manifest.info ? ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE
2928 : ACTIVATION_CONTEXT_PATH_TYPE_NONE;
2929
2931 if (RtlIsTextUnicode( buffer, size, &unicode_tests ))
2932 {
2933 xmlbuf.ptr = buffer;
2934 xmlbuf.end = xmlbuf.ptr + size / sizeof(WCHAR);
2935 status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf );
2936 }
2937 else if (unicode_tests & IS_TEXT_UNICODE_REVERSE_SIGNATURE)
2938 {
2939 const WCHAR *buf = buffer;
2940 WCHAR *new_buff;
2941 unsigned int i;
2942
2943 if (!(new_buff = RtlAllocateHeap( GetProcessHeap(), 0, size )))
2944 return STATUS_NO_MEMORY;
2945 for (i = 0; i < size / sizeof(WCHAR); i++)
2946 new_buff[i] = RtlUshortByteSwap( buf[i] );
2947 xmlbuf.ptr = new_buff;
2948 xmlbuf.end = xmlbuf.ptr + size / sizeof(WCHAR);
2949 status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf );
2950 RtlFreeHeap( GetProcessHeap(), 0, new_buff );
2951 }
2952 else
2953 {
2954 DWORD len;
2955 WCHAR *new_buff;
2956
2957 /* let's assume utf-8 for now */
2959 if (!NT_SUCCESS(status))
2960 {
2961 DPRINT1("RtlMultiByteToUnicodeSize failed with %lx\n", status);
2963 }
2964
2965 if (!(new_buff = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return STATUS_NO_MEMORY;
2966 status = RtlUTF8ToUnicodeN( new_buff, len, &len, buffer, size );
2967 if (!NT_SUCCESS(status))
2968 {
2969 DPRINT1("RtlMultiByteToUnicodeN failed with %lx\n", status);
2971 }
2972
2973 xmlbuf.ptr = new_buff;
2974 xmlbuf.end = xmlbuf.ptr + len / sizeof(WCHAR);
2975 status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf );
2976 RtlFreeHeap( GetProcessHeap(), 0, new_buff );
2977 }
2978 return status;
2979}
2980
2982{
2985
2986 attr.Length = sizeof(attr);
2987 attr.RootDirectory = 0;
2988 attr.Attributes = OBJ_CASE_INSENSITIVE;
2989 attr.ObjectName = name;
2990 attr.SecurityDescriptor = NULL;
2991 attr.SecurityQualityOfService = NULL;
2993}
2994
2997 HANDLE hModule, LPCWSTR resname, ULONG lang )
2998{
3003 void *ptr;
3004
3005 //DPRINT( "looking for res %s in module %p %s\n", resname,
3006 // hModule, filename );
3007 DPRINT("get_manifest_in_module %p\n", hModule);
3008
3009#if 0
3010 if (TRACE_ON(actctx))
3011 {
3012 if (!filename && !get_module_filename( hModule, &nameW, 0 ))
3013 {
3014 TRACE( "looking for res %s in module %p %s\n", debugstr_w(resname),
3015 hModule, debugstr_w(nameW.Buffer) );
3017 }
3018 else TRACE( "looking for res %s in module %p %s\n", debugstr_w(resname),
3020 }
3021#endif
3022
3023 if (!resname) return STATUS_INVALID_PARAMETER;
3024
3025 info.Type = RT_MANIFEST;
3026 info.Language = lang;
3027 if (!((ULONG_PTR)resname >> 16))
3028 {
3029 info.Name = (ULONG_PTR)resname;
3031 }
3032 else if (resname[0] == '#')
3033 {
3034 ULONG value;
3035 RtlInitUnicodeString(&nameW, resname + 1);
3038 info.Name = value;
3040 }
3041 else
3042 {
3043 RtlCreateUnicodeString(&nameW, resname);
3045 info.Name = (ULONG_PTR)nameW.Buffer;
3048 }
3050
3051 if (status == STATUS_SUCCESS)
3052 status = parse_manifest(acl, ai, filename, hModule, directory, shared, ptr, entry->Size);
3053
3054 return status;
3055}
3056
3057#ifdef __REACTOS__
3059 LPCWSTR name, void *root,
3060 int want_dir );
3061
3063 void *root, int want_dir );
3064
3065
3066static IMAGE_RESOURCE_DIRECTORY *find_first_id_entry( IMAGE_RESOURCE_DIRECTORY *dir,
3067 void *root, int want_dir )
3068{
3070 int pos;
3071
3072 for (pos = dir->NumberOfNamedEntries; pos < dir->NumberOfNamedEntries + dir->NumberOfIdEntries; pos++)
3073 {
3074 if (!entry[pos].DataIsDirectory == !want_dir)
3075 return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry[pos].OffsetToDirectory);
3076 }
3077 return NULL;
3078}
3079
3080
3081static NTSTATUS search_manifest_in_module( struct actctx_loader* acl, struct assembly_identity* ai,
3084{
3085 ULONG size;
3086 PVOID root, ptr;
3087 IMAGE_RESOURCE_DIRECTORY *resdirptr;
3090
3093 if (size < sizeof(*resdirptr)) return STATUS_RESOURCE_DATA_NOT_FOUND;