ReactOS 0.4.16-dev-2354-g16de117
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#include <stdlib.h>
18
19#include <rtl.h>
20#include <ntstrsafe.h>
21#include <compat_undoc.h>
22
23#include <wine/unicode.h>
24#include "wine/exception.h"
25#include "wine/debug.h"
26
28
29#define GetProcessHeap() RtlGetProcessHeap()
30#define GetCurrentProcess() NtCurrentProcess()
31#define DPRINT1 FIXME
32#define DPRINT TRACE
33#define FILE_END_OF_FILE_INFORMATION FILE_STANDARD_INFORMATION
34#define FileEndOfFileInformation FileStandardInformation
35#define RELATIVE_PATH RtlPathTypeRelative
36#define windows_dir SharedUserData->NtSystemRoot
37#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
38#define wcsnicmp _wcsnicmp
39#define swprintf _snwprintf
40#define wcsicmp _wcsicmp
42
43#undef RT_MANIFEST
44#undef CREATEPROCESS_MANIFEST_RESOURCE_ID
45
46BOOLEAN RtlpNotAllowingMultipleActivation;
47
48#endif // __REACTOS__
49
50#define ACTCTX_FLAGS_ALL (\
51 ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID |\
52 ACTCTX_FLAG_LANGID_VALID |\
53 ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID |\
54 ACTCTX_FLAG_RESOURCE_NAME_VALID |\
55 ACTCTX_FLAG_SET_PROCESS_DEFAULT |\
56 ACTCTX_FLAG_APPLICATION_NAME_VALID |\
57 ACTCTX_FLAG_SOURCE_IS_ASSEMBLYREF |\
58 ACTCTX_FLAG_HMODULE_VALID )
59
60#define ACTCTX_MAGIC 0xC07E3E11
61#define STRSECTION_MAGIC 0x64487353 /* dHsS */
62#define GUIDSECTION_MAGIC 0x64487347 /* dHsG */
63
64#define ACTCTX_FAKE_HANDLE ((HANDLE) 0xf00baa)
65
66/* we don't want to include winuser.h */
67#define RT_MANIFEST ((ULONG_PTR)24)
68#define CREATEPROCESS_MANIFEST_RESOURCE_ID ((ULONG_PTR)1)
69
70#ifndef __REACTOS__ // defined in oaidl.h
71/* from oaidl.h */
72typedef enum tagLIBFLAGS {
78
79/* from oleidl.idl */
80typedef enum tagOLEMISC
81{
105#endif // !__REACTOS__
106
107#define MAX_NAMESPACES 64
108
109typedef struct
110{
111 const WCHAR *ptr;
112 unsigned int len;
113} xmlstr_t;
114
116{
120};
121
123{
126};
127
128typedef struct
129{
130 const WCHAR *ptr;
131 const WCHAR *end;
132 struct xml_attr namespaces[MAX_NAMESPACES];
135} xmlbuf_t;
136
138{
141};
142
144{
149};
150
152{
161};
162
164{
165 DWORD magic;
166 ULONG size;
167 DWORD unk1[3];
168 ULONG count;
170 DWORD unk2[2];
173};
174
175struct string_index
176{
177 ULONG hash; /* key string hash */
180 ULONG data_offset; /* redirect data offset */
183};
184
186{
187 DWORD magic;
188 ULONG size;
189 DWORD unk[3];
190 ULONG count;
192 DWORD unk2;
195};
196
197struct guid_index
198{
199 GUID guid;
203};
204
206{
207 ULONG size;
208 DWORD res;
210 ULONG name_offset; /* versioned name offset */
212 ULONG module_offset;/* container name offset */
213};
214
216{
217 ULONG size;
218 DWORD res;
222 WORD flags;
227};
228
230{
237
239{
246
248{
249 ULONG size;
250 ULONG flags;
251 DWORD model;
252 GUID clsid;
253 GUID alias;
254 GUID clsid2;
255 GUID tlbid;
267};
268
270{
272 BaseIface = 2
274
276{
277 ULONG size;
278 DWORD mask;
279 GUID iid;
281 GUID tlbid;
282 GUID base;
285};
286
288{
289 ULONG size;
290 DWORD res;
291 GUID clsid;
296};
297
298struct clrclass_data
299{
300 ULONG size;
301 DWORD res[2];
308 DWORD res2[2];
309};
310
312{
313 ULONG size;
316};
317
319{
320 ULONG size;
321 DWORD unk;
325};
326
327/*
328
329 Sections structure.
330
331 Sections are accessible by string or guid key, that defines two types of sections.
332 All sections of each type have same magic value and header structure, index
333 data could be of two possible types too. So every string based section uses
334 the same index format, same applies to guid sections - they share same guid index
335 format.
336
337 - window class redirection section is a plain buffer with following format:
338
339 <section header>
340 <index[]>
341 <data[]> --- <original name>
342 <redirect data>
343 <versioned name>
344 <module name>
345
346 Header is fixed length structure - struct strsection_header,
347 contains redirected classes count;
348
349 Index is an array of fixed length index records, each record is
350 struct string_index.
351
352 All strings in data itself are WCHAR, null terminated, 4-bytes aligned.
353
354 Versioned name offset is relative to redirect data structure (struct wndclass_redirect_data),
355 others are relative to section itself.
356
357 - dll redirect section format:
358
359 <section header>
360 <index[]>
361 <data[]> --- <dll name>
362 <data>
363
364 This section doesn't seem to carry any payload data except dll names.
365
366 - typelib section format:
367
368 <section header>
369 <module names[]>
370 <index[]>
371 <data[]> --- <data>
372 <helpstring>
373
374 Header is fixed length, index is an array of fixed length 'struct guid_index'.
375 All strings are WCHAR, null terminated, 4-bytes aligned. Module names part is
376 4-bytes aligned as a whole.
377
378 Module name offsets are relative to section, helpstring offset is relative to data
379 structure itself.
380
381 - comclass section format:
382
383 <section header>
384 <module names[]>
385 <index[]>
386 <data[]> --- <data> --- <data>
387 <progid> <clrdata>
388 <name>
389 <version>
390 <progid>
391
392 This section uses two index records per comclass, one entry contains original guid
393 as specified by context, another one has a generated guid. Index and strings handling
394 is similar to typelib sections.
395
396 For CLR classes additional data is stored after main COM class data, it contains
397 class name and runtime version string, see 'struct clrclass_data'.
398
399 Module name offsets are relative to section, progid offset is relative to data
400 structure itself.
401
402 - COM interface section format:
403
404 <section header>
405 <index[]>
406 <data[]> --- <data>
407 <name>
408
409 Interface section contains data for proxy/stubs and external proxy/stubs. External
410 ones are defined at assembly level, so this section has no module information.
411 All records are indexed with 'iid' value from manifest. There an exception for
412 external variants - if 'proxyStubClsid32' is specified, it's stored as iid in
413 redirect data, but index is still 'iid' from manifest.
414
415 Interface name offset is relative to data structure itself.
416
417 - CLR surrogates section format:
418
419 <section header>
420 <index[]>
421 <data[]> --- <data>
422 <name>
423 <version>
424
425 There's nothing special about this section, same way to store strings is used,
426 no modules part as it belongs to assembly level, not a file.
427
428 - ProgID section format:
429
430 <section header>
431 <guids[]>
432 <index[]>
433 <data[]> --- <progid>
434 <data>
435
436 This sections uses generated alias guids from COM server section. This way
437 ProgID -> CLSID mapping returns generated guid, not the real one. ProgID string
438 is stored too, aligned.
439
440 - WinRT activatable class section is a plain buffer with following format:
441
442 <section header>
443 <module names[]>
444 <index[]>
445 <data[]> --- <class name>
446 <data>
447
448 Header is fixed length structure - struct strsection_header,
449 contains classes count;
450
451 Index is an array of fixed length index records, each record is
452 struct string_index.
453
454 All strings in data itself are WCHAR, null terminated, 4-bytes aligned.
455
456 All offsets are relative to section itself.
457
458*/
459
461{
463 unsigned int num;
464 unsigned int allocated;
465};
466
467struct entity
468{
470 union
471 {
472 struct
473 {
480 struct
481 {
483 WCHAR *tlbid;
485 WCHAR *name; /* clrClass: class name */
486 WCHAR *version; /* clrClass: CLR runtime version */
495 struct {
499 WCHAR *name;
500 WCHAR *ps32; /* only stored for 'comInterfaceExternalProxyStub' */
504 struct
505 {
506 WCHAR *name;
508 } class;
509 struct
510 {
511 WCHAR *name;
512 WCHAR *clsid;
513 WCHAR *version;
515 struct
516 {
517 WCHAR *name;
521 struct
522 {
523 WCHAR *name;
526 } u;
527};
528
530{
531 struct entity *base;
532 unsigned int num;
533 unsigned int allocated;
534};
535
537{
542};
543
545{
549};
550
551struct assembly
552{
559 unsigned int num_dlls;
560 unsigned int allocated_dlls;
562 COMPATIBILITY_CONTEXT_ELEMENT *compat_contexts;
564 ACTCTX_REQUESTED_RUN_LEVEL run_level;
566};
567
569{
578};
579
580#ifdef __REACTOS__
581typedef struct _ASSEMBLY_STORAGE_MAP_ENTRY
582{
583 ULONG Flags;
584 UNICODE_STRING DosPath;
586} ASSEMBLY_STORAGE_MAP_ENTRY, *PASSEMBLY_STORAGE_MAP_ENTRY;
587
588typedef struct _ASSEMBLY_STORAGE_MAP
589{
590 ULONG Flags;
591 ULONG AssemblyCount;
592 PASSEMBLY_STORAGE_MAP_ENTRY *AssemblyArray;
593} ASSEMBLY_STORAGE_MAP, *PASSEMBLY_STORAGE_MAP;
594#endif // __REACTOS__
595
597{
600#ifdef __REACTOS__
601 ULONG Flags;
602 LIST_ENTRY Links;
603 PACTIVATION_CONTEXT_DATA ActivationContextData;
604 PVOID NotificationRoutine;
606 ULONG SentNotifications[8];
607 ULONG DisabledNotifications[8];
608 ASSEMBLY_STORAGE_MAP StorageMap;
609 PASSEMBLY_STORAGE_MAP_ENTRY InlineStorageMapEntries;
610 ULONG StackTraceIndex;
611 PVOID StackTraces[4][4];
612#endif // __REACTOS__
616 unsigned int num_assemblies;
618 /* section data */
629
631{
634 unsigned int num_dependencies;
636};
637
639
640#ifdef __i386__
641static const WCHAR current_archW[] = L"x86";
642#elif defined __aarch64__ || defined __arm64ec__
643static const WCHAR current_archW[] = L"arm64";
644#elif defined __x86_64__
645static const WCHAR current_archW[] = L"amd64";
646#elif defined __arm__
647static const WCHAR current_archW[] = L"arm";
648#else
649static const WCHAR current_archW[] = L"none";
650#endif
651
652static const WCHAR asmv1W[] = L"urn:schemas-microsoft-com:asm.v1";
653static const WCHAR asmv2W[] = L"urn:schemas-microsoft-com:asm.v2";
654static const WCHAR asmv3W[] = L"urn:schemas-microsoft-com:asm.v3";
655static const WCHAR winrtv1W[] = L"urn:schemas-microsoft-com:winrt.v1";
656static const WCHAR compatibilityNSW[] = L"urn:schemas-microsoft-com:compatibility.v1";
657static const WCHAR windowsSettings2005NSW[] = L"http://schemas.microsoft.com/SMI/2005/WindowsSettings";
658static const WCHAR windowsSettings2011NSW[] = L"http://schemas.microsoft.com/SMI/2011/WindowsSettings";
659static const WCHAR windowsSettings2016NSW[] = L"http://schemas.microsoft.com/SMI/2016/WindowsSettings";
660static const WCHAR windowsSettings2017NSW[] = L"http://schemas.microsoft.com/SMI/2017/WindowsSettings";
661static const WCHAR windowsSettings2019NSW[] = L"http://schemas.microsoft.com/SMI/2019/WindowsSettings";
662static const WCHAR windowsSettings2020NSW[] = L"http://schemas.microsoft.com/SMI/2020/WindowsSettings";
663
665{
666 const WCHAR *name;
668};
669
670static const struct olemisc_entry olemisc_values[] =
671{
672 { L"activatewhenvisible", OLEMISC_ACTIVATEWHENVISIBLE },
673 { L"actslikebutton", OLEMISC_ACTSLIKEBUTTON },
674 { L"actslikelabel", OLEMISC_ACTSLIKELABEL },
675 { L"alignable", OLEMISC_ALIGNABLE },
676 { L"alwaysrun", OLEMISC_ALWAYSRUN },
677 { L"canlinkbyole1", OLEMISC_CANLINKBYOLE1 },
678 { L"cantlinkinside", OLEMISC_CANTLINKINSIDE },
679 { L"ignoreactivatewhenvisible", OLEMISC_IGNOREACTIVATEWHENVISIBLE },
680 { L"imemode", OLEMISC_IMEMODE },
681 { L"insertnotreplace", OLEMISC_INSERTNOTREPLACE },
682 { L"insideout", OLEMISC_INSIDEOUT },
683 { L"invisibleatruntime", OLEMISC_INVISIBLEATRUNTIME },
684 { L"islinkobject", OLEMISC_ISLINKOBJECT },
685 { L"nouiactivate", OLEMISC_NOUIACTIVATE },
686 { L"onlyiconic", OLEMISC_ONLYICONIC },
687 { L"recomposeonresize", OLEMISC_RECOMPOSEONRESIZE },
688 { L"renderingisdeviceindependent", OLEMISC_RENDERINGISDEVICEINDEPENDENT },
689 { L"setclientsitefirst", OLEMISC_SETCLIENTSITEFIRST },
690 { L"simpleframe", OLEMISC_SIMPLEFRAME },
691 { L"static", OLEMISC_STATIC },
692 { L"supportsmultilevelundo", OLEMISC_SUPPORTSMULTILEVELUNDO },
693 { L"wantstomenumerge", OLEMISC_WANTSTOMENUMERGE }
694};
695
699
700static WCHAR *strdupW(const WCHAR* str)
701{
702 WCHAR* ptr;
703
704 if (!(ptr = RtlAllocateHeap(GetProcessHeap(), 0, (wcslen(str) + 1) * sizeof(WCHAR))))
705 return NULL;
706 return wcscpy(ptr, str);
707}
708
710{
711 WCHAR *strW;
712
713 if ((strW = RtlAllocateHeap(GetProcessHeap(), 0, (str->len + 1) * sizeof(WCHAR))))
714 {
715 memcpy( strW, str->ptr, str->len * sizeof(WCHAR) );
716 strW[str->len] = 0;
717 }
718 return strW;
719}
720
721static inline BOOL xmlstr_cmp(const xmlstr_t* xmlstr, const WCHAR *str)
722{
723 return !wcsncmp(xmlstr->ptr, str, xmlstr->len) && !str[xmlstr->len];
724}
725
726static inline BOOL xmlstr_cmpi(const xmlstr_t* xmlstr, const WCHAR *str)
727{
728 return !wcsnicmp(xmlstr->ptr, str, xmlstr->len) && !str[xmlstr->len];
729}
730
731static BOOL xml_attr_cmp( const struct xml_attr *attr, const WCHAR *str )
732{
733 return xmlstr_cmp( &attr->name, str );
734}
735
736static BOOL xml_name_cmp( const struct xml_elem *elem1, const struct xml_elem *elem2 )
737{
738 return (elem1->name.len == elem2->name.len &&
739 elem1->ns.len == elem2->ns.len &&
740 !wcsncmp( elem1->name.ptr, elem2->name.ptr, elem1->name.len ) &&
741 !wcsncmp( elem1->ns.ptr, elem2->ns.ptr, elem1->ns.len ));
742}
743
744static inline BOOL xml_elem_cmp(const struct xml_elem *elem, const WCHAR *str, const WCHAR *namespace)
745{
746 if (!xmlstr_cmp( &elem->name, str )) return FALSE;
747 if (xmlstr_cmp( &elem->ns, namespace )) return TRUE;
748 if (!wcscmp( namespace, asmv1W ))
749 {
750 if (xmlstr_cmp( &elem->ns, asmv2W )) return TRUE;
751 if (xmlstr_cmp( &elem->ns, asmv3W )) return TRUE;
752 }
753 else if (!wcscmp( namespace, asmv2W ))
754 {
755 if (xmlstr_cmp( &elem->ns, asmv3W )) return TRUE;
756 }
757 return FALSE;
758}
759
760static inline BOOL isxmlspace( WCHAR ch )
761{
762 return (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t');
763}
764
765static inline const char* debugstr_xmlstr(const xmlstr_t* str)
766{
767 return debugstr_wn(str->ptr, str->len);
768}
769
770static inline const char *debugstr_xml_elem( const struct xml_elem *elem )
771{
772 return wine_dbg_sprintf( "%s ns %s", debugstr_wn( elem->name.ptr, elem->name.len ),
773 debugstr_wn( elem->ns.ptr, elem->ns.len ));
774}
775
776static inline const char *debugstr_xml_attr( const struct xml_attr *attr )
777{
778 return wine_dbg_sprintf( "%s=%s", debugstr_wn( attr->name.ptr, attr->name.len ),
779 debugstr_wn( attr->value.ptr, attr->value.len ));
780}
781
782static inline const char* debugstr_version(const struct assembly_version *ver)
783{
784 return wine_dbg_sprintf("%u.%u.%u.%u", ver->major, ver->minor, ver->build, ver->revision);
785}
786
787static NTSTATUS get_module_filename( HMODULE module, UNICODE_STRING *str, unsigned int extra_len )
788{
790 ULONG_PTR magic;
792
793 LdrLockLoaderLock(0, NULL, &magic);
795 if (status == STATUS_SUCCESS)
796 {
797 if ((str->Buffer = RtlAllocateHeap( GetProcessHeap(), 0,
798 pldr->FullDllName.Length + extra_len + sizeof(WCHAR) )))
799 {
800 memcpy( str->Buffer, pldr->FullDllName.Buffer, pldr->FullDllName.Length + sizeof(WCHAR) );
801 str->Length = pldr->FullDllName.Length;
802 str->MaximumLength = pldr->FullDllName.Length + extra_len + sizeof(WCHAR);
803 }
805 }
806 LdrUnlockLoaderLock(0, magic);
807 return status;
808}
809
811{
812 struct assembly *assembly;
813
814 DPRINT("add_assembly() actctx %p, activeframe ??\n", actctx);
815
816 if (actctx->num_assemblies == actctx->allocated_assemblies)
817 {
818 void *ptr;
819 unsigned int new_count;
820 if (actctx->assemblies)
821 {
822 new_count = actctx->allocated_assemblies * 2;
824 actctx->assemblies, new_count * sizeof(*assembly) );
825 }
826 else
827 {
828 new_count = 4;
829 ptr = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*assembly) );
830 }
831 if (!ptr) return NULL;
832 actctx->assemblies = ptr;
833 actctx->allocated_assemblies = new_count;
834 }
835
836 assembly = &actctx->assemblies[actctx->num_assemblies++];
837 assembly->type = at;
838 return assembly;
839}
840
842{
843 DPRINT("add_dll_redirect() to assembly %p, num_dlls %d\n", assembly, assembly->allocated_dlls);
844
846 {
847 void *ptr;
848 unsigned int new_count;
849 if (assembly->dlls)
850 {
851 new_count = assembly->allocated_dlls * 2;
853 assembly->dlls, new_count * sizeof(*assembly->dlls) );
854 }
855 else
856 {
857 new_count = 4;
858 ptr = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*assembly->dlls) );
859 }
860 if (!ptr) return NULL;
861 assembly->dlls = ptr;
862 assembly->allocated_dlls = new_count;
863 }
864 return &assembly->dlls[assembly->num_dlls++];
865}
866
867static PCOMPATIBILITY_CONTEXT_ELEMENT add_compat_context(struct assembly* assembly)
868{
869 void *ptr;
871 {
872 unsigned int new_count = assembly->num_compat_contexts + 1;
875 new_count * sizeof(COMPATIBILITY_CONTEXT_ELEMENT) );
876 }
877 else
878 {
879 ptr = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(COMPATIBILITY_CONTEXT_ELEMENT) );
880 }
881 if (!ptr) return NULL;
884}
885
887{
888 RtlFreeHeap( GetProcessHeap(), 0, ai->name );
889 RtlFreeHeap( GetProcessHeap(), 0, ai->arch );
892 RtlFreeHeap( GetProcessHeap(), 0, ai->type );
893}
894
896{
897 struct entity* entity;
898
899 if (array->num == array->allocated)
900 {
901 void *ptr;
902 unsigned int new_count;
903 if (array->base)
904 {
905 new_count = array->allocated * 2;
907 array->base, new_count * sizeof(*array->base) );
908 }
909 else
910 {
911 new_count = 4;
912 ptr = RtlAllocateHeap( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * sizeof(*array->base) );
913 }
914 if (!ptr) return NULL;
915 array->base = ptr;
916 array->allocated = new_count;
917 }
918 entity = &array->base[array->num++];
919 entity->kind = kind;
920 return entity;
921}
922
924{
925 unsigned int i, j;
926 for (i = 0; i < array->num; i++)
927 {
928 struct entity *entity = &array->base[i];
929 switch (entity->kind)
930 {
931 case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION:
937 for (j = 0; j < entity->u.comclass.progids.num; j++)
938 RtlFreeHeap(GetProcessHeap(), 0, entity->u.comclass.progids.progids[j]);
939 RtlFreeHeap(GetProcessHeap(), 0, entity->u.comclass.progids.progids);
940 break;
941 case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION:
947 break;
948 case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION:
950 RtlFreeHeap(GetProcessHeap(), 0, entity->u.typelib.helpdir);
951 break;
952 case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION:
954 break;
955 case ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES:
959 break;
960 case ACTIVATION_CONTEXT_SECTION_APPLICATION_SETTINGS:
964 break;
965 case ACTIVATION_CONTEXT_SECTION_WINRT_ACTIVATABLE_CLASSES:
967 break;
968 default:
969 FIXME("Unknown entity kind %ld\n", entity->kind);
970 }
971 }
972 RtlFreeHeap( GetProcessHeap(), 0, array->base );
973}
974
975static BOOL is_matching_string( const WCHAR *str1, const WCHAR *str2 )
976{
977 if (!str1) return !str2;
979}
980
982 const struct assembly_identity *id2 )
983{
984 if (!is_matching_string( id1->name, id2->name )) return FALSE;
985 if (!is_matching_string( id1->arch, id2->arch )) return FALSE;
986 if (!is_matching_string( id1->public_key, id2->public_key )) return FALSE;
987
988 if (id1->language && id2->language && !is_matching_string( id1->language, id2->language ))
989 {
990 if (wcscmp( L"*", id1->language ) && wcscmp( L"*", id2->language ))
991 return FALSE;
992 }
993 if (id1->version.major != id2->version.major) return FALSE;
994 if (id1->version.minor != id2->version.minor) return FALSE;
995 if (id1->version.build > id2->version.build) return FALSE;
996 if (id1->version.build == id2->version.build &&
997 id1->version.revision > id2->version.revision) return FALSE;
998 return TRUE;
999}
1000
1002 struct assembly_identity* ai)
1003{
1004 unsigned int i;
1005
1006 /* check if we already have that assembly */
1007
1008 for (i = 0; i < acl->actctx->num_assemblies; i++)
1009 if (is_matching_identity( ai, &acl->actctx->assemblies[i].id ))
1010 {
1011 TRACE( "reusing existing assembly for %s arch %s version %u.%u.%u.%u\n",
1012 debugstr_w(ai->name), debugstr_w(ai->arch), ai->version.major, ai->version.minor,
1013 ai->version.build, ai->version.revision );
1014 return TRUE;
1015 }
1016
1017 for (i = 0; i < acl->num_dependencies; i++)
1018 if (is_matching_identity( ai, &acl->dependencies[i] ))
1019 {
1020 TRACE( "reusing existing dependency for %s arch %s version %u.%u.%u.%u\n",
1021 debugstr_w(ai->name), debugstr_w(ai->arch), ai->version.major, ai->version.minor,
1022 ai->version.build, ai->version.revision );
1023 return TRUE;
1024 }
1025
1027 {
1028 void *ptr;
1029 unsigned int new_count;
1030 if (acl->dependencies)
1031 {
1032 new_count = acl->allocated_dependencies * 2;
1034 new_count * sizeof(acl->dependencies[0]));
1035 }
1036 else
1037 {
1038 new_count = 4;
1039 ptr = RtlAllocateHeap(GetProcessHeap(), 0, new_count * sizeof(acl->dependencies[0]));
1040 }
1041 if (!ptr) return FALSE;
1042 acl->dependencies = ptr;
1043 acl->allocated_dependencies = new_count;
1044 }
1045 acl->dependencies[acl->num_dependencies++] = *ai;
1046
1047 return TRUE;
1048}
1049
1050static void free_depend_manifests(struct actctx_loader* acl)
1051{
1052 unsigned int i;
1053 for (i = 0; i < acl->num_dependencies; i++)
1056}
1057
1059{
1060 static const WCHAR mskeyW[] = L"deadbeef";
1061 const WCHAR *arch = ai->arch ? ai->arch : L"none";
1062 const WCHAR *key = ai->public_key ? ai->public_key : L"none";
1063 const WCHAR *lang = ai->language ? ai->language : L"none";
1064 const WCHAR *name = ai->name ? ai->name : L"none";
1065 SIZE_T size = (wcslen(arch) + 1 + wcslen(name) + 1 + wcslen(key) + 24 + 1 +
1066 wcslen(lang) + 1) * sizeof(WCHAR) + sizeof(mskeyW);
1067 WCHAR *ret;
1068
1069 if (!(ret = RtlAllocateHeap( GetProcessHeap(), 0, size ))) return NULL;
1070
1071 wcscpy( ret, arch );
1072 wcscat( ret, L"_" );
1073 wcscat( ret, name );
1074 wcscat( ret, L"_" );
1075 wcscat( ret, key );
1076 wcscat( ret, L"_" );
1077 swprintf( ret + wcslen(ret), size - wcslen(ret), L"%u.%u.%u.%u",
1078 ai->version.major, ai->version.minor, ai->version.build, ai->version.revision );
1079 wcscat( ret, L"_" );
1080 wcscat( ret, lang );
1081 wcscat( ret, L"_" );
1082 wcscat( ret, mskeyW );
1083 return ret;
1084}
1085
1086static inline void append_string( WCHAR *buffer, const WCHAR *prefix, const WCHAR *str )
1087{
1088 WCHAR *p = buffer;
1089
1090 if (!str) return;
1091 wcscat( buffer, prefix );
1092 p += wcslen(p);
1093 *p++ = '"';
1094 wcscpy( p, str );
1095 p += wcslen(p);
1096 *p++ = '"';
1097 *p = 0;
1098}
1099
1100static WCHAR *build_assembly_id( const struct assembly_identity *ai )
1101{
1102 WCHAR version[64], *ret;
1103 SIZE_T size = 0;
1104
1105 swprintf( version, ARRAY_SIZE(version), L"%u.%u.%u.%u",
1106 ai->version.major, ai->version.minor, ai->version.build, ai->version.revision );
1107 if (ai->name) size += wcslen(ai->name) * sizeof(WCHAR);
1108 if (ai->arch) size += wcslen(L",processorArchitecture=") + wcslen(ai->arch) + 2;
1109 if (ai->public_key) size += wcslen(L",publicKeyToken=") + wcslen(ai->public_key) + 2;
1110 if (ai->type) size += wcslen(L",type=") + wcslen(ai->type) + 2;
1111 size += wcslen(L",version=") + wcslen(version) + 2;
1112
1113 if (!(ret = RtlAllocateHeap( GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR) )))
1114 return NULL;
1115
1116 if (ai->name) wcscpy( ret, ai->name );
1117 else *ret = 0;
1118 append_string( ret, L",processorArchitecture=", ai->arch );
1119 append_string( ret, L",publicKeyToken=", ai->public_key );
1120 append_string( ret, L",type=", ai->type );
1121 append_string( ret, L",version=", version );
1122 return ret;
1123}
1124
1126{
1128
1129 if (!h || h == INVALID_HANDLE_VALUE) return NULL;
1130 __TRY
1131 {
1132 if (actctx->magic == ACTCTX_MAGIC) ret = actctx;
1133 }
1135 {
1136 DPRINT1("Invalid activation context handle!\n");
1137 }
1138 __ENDTRY
1139 return ret;
1140}
1141
1143{
1144 InterlockedIncrement( &actctx->ref_count );
1145}
1146
1148{
1149 if (!InterlockedDecrement( &actctx->ref_count ))
1150 {
1151 unsigned int i, j;
1152
1153 for (i = 0; i < actctx->num_assemblies; i++)
1154 {
1155 struct assembly *assembly = &actctx->assemblies[i];
1156 for (j = 0; j < assembly->num_dlls; j++)
1157 {
1158 struct dll_redirect *dll = &assembly->dlls[j];
1159 free_entity_array( &dll->entities );
1160 RtlFreeHeap( GetProcessHeap(), 0, dll->name );
1161 RtlFreeHeap( GetProcessHeap(), 0, dll->load_from );
1162 RtlFreeHeap( GetProcessHeap(), 0, dll->hash );
1163 }
1170 }
1171 RtlFreeHeap( GetProcessHeap(), 0, actctx->config.info );
1172 RtlFreeHeap( GetProcessHeap(), 0, actctx->appdir.info );
1173 RtlFreeHeap( GetProcessHeap(), 0, actctx->assemblies );
1174 RtlFreeHeap( GetProcessHeap(), 0, actctx->dllredirect_section );
1175 RtlFreeHeap( GetProcessHeap(), 0, actctx->wndclass_section );
1176 RtlFreeHeap( GetProcessHeap(), 0, actctx->tlib_section );
1177 RtlFreeHeap( GetProcessHeap(), 0, actctx->comserver_section );
1178 RtlFreeHeap( GetProcessHeap(), 0, actctx->ifaceps_section );
1179 RtlFreeHeap( GetProcessHeap(), 0, actctx->clrsurrogate_section );
1180 RtlFreeHeap( GetProcessHeap(), 0, actctx->progid_section );
1181 RtlFreeHeap( GetProcessHeap(), 0, actctx->activatable_class_section );
1182 actctx->magic = 0;
1184 }
1185}
1186
1187static BOOL set_error( xmlbuf_t *xmlbuf )
1188{
1189 xmlbuf->error = TRUE;
1190 return FALSE;
1191}
1192
1193static BOOL is_xmlns_attr( const struct xml_attr *attr )
1194{
1195 const int len = wcslen( L"xmlns" );
1196 if (attr->name.len < len) return FALSE;
1197 if (wcsncmp( attr->name.ptr, L"xmlns", len )) return FALSE;
1198 return (attr->name.len == len || attr->name.ptr[len] == ':');
1199}
1200
1201static void push_xmlns( xmlbuf_t *xmlbuf, const struct xml_attr *attr )
1202{
1203 const int len = wcslen( L"xmlns" );
1204 struct xml_attr *ns;
1205
1206 if (xmlbuf->ns_pos == MAX_NAMESPACES - 1)
1207 {
1208 FIXME( "too many namespaces in manifest\n" );
1209 set_error( xmlbuf );
1210 return;
1211 }
1212 ns = &xmlbuf->namespaces[xmlbuf->ns_pos++];
1213 ns->value = attr->value;
1214 if (attr->name.len > len)
1215 {
1216 ns->name.ptr = attr->name.ptr + len + 1;
1217 ns->name.len = attr->name.len - len - 1;
1218 }
1219 else ns->name = empty_xmlstr;
1220}
1221
1222static xmlstr_t find_xmlns( xmlbuf_t *xmlbuf, const xmlstr_t *name )
1223{
1224 int i;
1225
1226 for (i = xmlbuf->ns_pos - 1; i >= 0; i--)
1227 {
1228 if (xmlbuf->namespaces[i].name.len == name->len &&
1229 !wcsncmp( xmlbuf->namespaces[i].name.ptr, name->ptr, name->len ))
1230 return xmlbuf->namespaces[i].value;
1231 }
1232 if (xmlbuf->ns_pos) WARN( "namespace %s not found\n", debugstr_xmlstr( name ));
1233 return empty_xmlstr;
1234}
1235
1236static BOOL next_xml_attr(xmlbuf_t *xmlbuf, struct xml_attr *attr, BOOL *end)
1237{
1238 const WCHAR* ptr;
1239 WCHAR quote;
1240
1241 if (xmlbuf->error) return FALSE;
1242
1243 while (xmlbuf->ptr < xmlbuf->end && isxmlspace(*xmlbuf->ptr))
1244 xmlbuf->ptr++;
1245
1246 if (xmlbuf->ptr == xmlbuf->end) return set_error( xmlbuf );
1247
1248 if (*xmlbuf->ptr == '/')
1249 {
1250 xmlbuf->ptr++;
1251 if (xmlbuf->ptr == xmlbuf->end || *xmlbuf->ptr != '>')
1252 return set_error( xmlbuf );
1253
1254 xmlbuf->ptr++;
1255 *end = TRUE;
1256 return FALSE;
1257 }
1258
1259 if (*xmlbuf->ptr == '>')
1260 {
1261 xmlbuf->ptr++;
1262 return FALSE;
1263 }
1264
1265 ptr = xmlbuf->ptr;
1266 while (ptr < xmlbuf->end && *ptr != '=' && *ptr != '>' && !isxmlspace(*ptr)) ptr++;
1267
1268 if (ptr == xmlbuf->end) return set_error( xmlbuf );
1269
1270 attr->name.ptr = xmlbuf->ptr;
1271 attr->name.len = ptr-xmlbuf->ptr;
1272 xmlbuf->ptr = ptr;
1273
1274 /* skip spaces before '=' */
1275 while (ptr < xmlbuf->end && *ptr != '=' && isxmlspace(*ptr)) ptr++;
1276 if (ptr == xmlbuf->end || *ptr != '=') return set_error( xmlbuf );
1277
1278 /* skip '=' itself */
1279 ptr++;
1280 if (ptr == xmlbuf->end) return set_error( xmlbuf );
1281
1282 /* skip spaces after '=' */
1283 while (ptr < xmlbuf->end && *ptr != '"' && *ptr != '\'' && isxmlspace(*ptr)) ptr++;
1284
1285 if (ptr == xmlbuf->end || (*ptr != '"' && *ptr != '\'')) return set_error( xmlbuf );
1286
1287 quote = *ptr++;
1288 attr->value.ptr = ptr;
1289 if (ptr == xmlbuf->end) return set_error( xmlbuf );
1290
1291 while (ptr < xmlbuf->end && *ptr != quote) ptr++;
1292 if (ptr == xmlbuf->end)
1293 {
1294 xmlbuf->ptr = xmlbuf->end;
1295 return set_error( xmlbuf );
1296 }
1297
1298 attr->value.len = ptr - attr->value.ptr;
1299 xmlbuf->ptr = ptr + 1;
1300 if (xmlbuf->ptr != xmlbuf->end) return TRUE;
1301
1302 return set_error( xmlbuf );
1303}
1304
1305static void read_xml_elem( xmlbuf_t *xmlbuf, struct xml_elem *elem )
1306{
1307 const WCHAR* ptr = xmlbuf->ptr;
1308
1309 elem->ns = empty_xmlstr;
1310 elem->name.ptr = ptr;
1311 while (ptr < xmlbuf->end && !isxmlspace(*ptr) && *ptr != '>' && *ptr != '/')
1312 {
1313 if (*ptr == ':')
1314 {
1315 elem->ns.ptr = elem->name.ptr;
1316 elem->ns.len = ptr - elem->ns.ptr;
1317 elem->name.ptr = ptr + 1;
1318 }
1319 ptr++;
1320 }
1321 elem->name.len = ptr - elem->name.ptr;
1322 xmlbuf->ptr = ptr;
1323}
1324
1325static BOOL next_xml_elem( xmlbuf_t *xmlbuf, struct xml_elem *elem, const struct xml_elem *parent )
1326{
1327 const WCHAR* ptr;
1328 struct xml_attr attr;
1329 xmlbuf_t attr_buf;
1330 BOOL end = FALSE;
1331
1332 xmlbuf->ns_pos = parent->ns_pos; /* restore namespace stack to parent state */
1333
1334 if (xmlbuf->error) return FALSE;
1335
1336 for (;;)
1337 {
1338 for (ptr = xmlbuf->ptr; ptr < xmlbuf->end; ptr++) if (*ptr == '<') break;
1339 if (ptr == xmlbuf->end)
1340 {
1341 xmlbuf->ptr = xmlbuf->end;
1342 return set_error( xmlbuf );
1343 }
1344 ptr++;
1345 if (ptr + 3 < xmlbuf->end && ptr[0] == '!' && ptr[1] == '-' && ptr[2] == '-') /* skip comment */
1346 {
1347 for (ptr += 3; ptr + 3 <= xmlbuf->end; ptr++)
1348 if (ptr[0] == '-' && ptr[1] == '-' && ptr[2] == '>') break;
1349
1350 if (ptr + 3 > xmlbuf->end)
1351 {
1352 xmlbuf->ptr = xmlbuf->end;
1353 return set_error( xmlbuf );
1354 }
1355 xmlbuf->ptr = ptr + 3;
1356 }
1357 else break;
1358 }
1359
1360 xmlbuf->ptr = ptr;
1361 /* check for element terminating the parent element */
1362 if (ptr < xmlbuf->end && *ptr == '/')
1363 {
1364 xmlbuf->ptr++;
1365 read_xml_elem( xmlbuf, elem );
1366 elem->ns = find_xmlns( xmlbuf, &elem->ns );
1367 if (!xml_name_cmp( elem, parent ))
1368 {
1369 ERR( "wrong closing element %s for %s\n",
1370 debugstr_xmlstr(&elem->name), debugstr_xmlstr(&parent->name ));
1371 return set_error( xmlbuf );
1372 }
1373 while (xmlbuf->ptr < xmlbuf->end && isxmlspace(*xmlbuf->ptr)) xmlbuf->ptr++;
1374 if (xmlbuf->ptr == xmlbuf->end || *xmlbuf->ptr++ != '>') return set_error( xmlbuf );
1375 return FALSE;
1376 }
1377
1378 read_xml_elem( xmlbuf, elem );
1379
1380 /* parse namespace attributes */
1381 attr_buf = *xmlbuf;
1382 while (next_xml_attr( &attr_buf, &attr, &end ))
1383 {
1384 if (is_xmlns_attr( &attr )) push_xmlns( xmlbuf, &attr );
1385 }
1386 elem->ns = find_xmlns( xmlbuf, &elem->ns );
1387 elem->ns_pos = xmlbuf->ns_pos;
1388
1389 if (xmlbuf->ptr != xmlbuf->end) return TRUE;
1390
1391 return set_error( xmlbuf );
1392}
1393
1395{
1396 /* FIXME: parse attributes */
1397 const WCHAR *ptr;
1398
1399 for (ptr = xmlbuf->ptr; ptr < xmlbuf->end - 1; ptr++)
1400 {
1401 if (ptr[0] == '?' && ptr[1] == '>')
1402 {
1403 xmlbuf->ptr = ptr + 2;
1404 return TRUE;
1405 }
1406 }
1407 return FALSE;
1408}
1409
1411{
1412 const WCHAR *ptr;
1413
1414 if (xmlbuf->error) return FALSE;
1415
1416 for (ptr = xmlbuf->ptr; ptr < xmlbuf->end; ptr++) if (*ptr == '<') break;
1417 if (ptr == xmlbuf->end) return set_error( xmlbuf );
1418
1419 content->ptr = xmlbuf->ptr;
1420 content->len = ptr - xmlbuf->ptr;
1421 xmlbuf->ptr = ptr;
1422
1423 return TRUE;
1424}
1425
1427{
1428 unsigned int ver[4];
1429 unsigned int pos;
1430 const WCHAR *curr;
1431
1432 /* major.minor.build.revision */
1433 ver[0] = ver[1] = ver[2] = ver[3] = pos = 0;
1434 for (curr = str->ptr; curr < str->ptr + str->len; curr++)
1435 {
1436 if (*curr >= '0' && *curr <= '9')
1437 {
1438 ver[pos] = ver[pos] * 10 + *curr - '0';
1439 if (ver[pos] >= 0x10000) goto error;
1440 }
1441 else if (*curr == '.')
1442 {
1443 if (++pos >= 4) goto error;
1444 }
1445 else goto error;
1446 }
1447 version->major = ver[0];
1448 version->minor = ver[1];
1449 version->build = ver[2];
1450 version->revision = ver[3];
1451 return TRUE;
1452
1453error:
1454 FIXME( "Wrong version definition in manifest file (%s)\n", debugstr_xmlstr(str) );
1455 return FALSE;
1456}
1457
1459{
1460 struct xml_attr attr;
1461
1462 while (next_xml_attr(xmlbuf, &attr, end))
1463 {
1464 if (!is_xmlns_attr( &attr )) WARN("unexpected attr %s\n", debugstr_xml_attr(&attr));
1465 }
1466}
1467
1468static void parse_expect_end_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent )
1469{
1470 struct xml_elem elem;
1471
1472 if (next_xml_elem(xmlbuf, &elem, parent))
1473 {
1474 FIXME( "unexpected element %s\n", debugstr_xml_elem(&elem) );
1475 set_error( xmlbuf );
1476 }
1477}
1478
1479static void parse_unknown_elem(xmlbuf_t *xmlbuf, const struct xml_elem *parent)
1480{
1481 struct xml_elem elem;
1482 struct xml_attr attr;
1483 BOOL end = FALSE;
1484
1485 while (next_xml_attr(xmlbuf, &attr, &end));
1486 if (end) return;
1487
1488 while (next_xml_elem(xmlbuf, &elem, parent))
1489 parse_unknown_elem(xmlbuf, &elem);
1490}
1491
1493 struct assembly_identity* ai, const struct xml_elem *parent)
1494{
1495 struct xml_attr attr;
1496 BOOL end = FALSE;
1497
1498 while (next_xml_attr(xmlbuf, &attr, &end))
1499 {
1500 if (xml_attr_cmp(&attr, L"name"))
1501 {
1502 if (!(ai->name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1503 }
1504 else if (xml_attr_cmp(&attr, L"type"))
1505 {
1506 if (!(ai->type = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1507 }
1508 else if (xml_attr_cmp(&attr, L"version"))
1509 {
1510 if (!parse_version(&attr.value, &ai->version)) set_error( xmlbuf );
1511 }
1512 else if (xml_attr_cmp(&attr, L"processorArchitecture"))
1513 {
1514 if (!(ai->arch = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1515 }
1516 else if (xml_attr_cmp(&attr, L"publicKeyToken"))
1517 {
1518 if (!(ai->public_key = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1519 }
1520 else if (xml_attr_cmp(&attr, L"language"))
1521 {
1522 if (!(ai->language = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1523 }
1524 else if (!is_xmlns_attr( &attr ))
1525 {
1526 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
1527 }
1528 }
1529
1530 TRACE( "name=%s version=%s arch=%s\n",
1532
1533 if (!end) parse_expect_end_elem(xmlbuf, parent);
1534}
1535
1537{
1538 if (value->len == 0) return ThreadingModel_No;
1539 if (xmlstr_cmp(value, L"Apartment"))
1541 else if (xmlstr_cmp(value, L"Free"))
1542 return ThreadingModel_Free;
1543 else if (xmlstr_cmp(value, L"Both"))
1544 return ThreadingModel_Both;
1545 else if (xmlstr_cmp(value, L"Neutral"))
1547 else
1548 return ThreadingModel_No;
1549};
1550
1552{
1553 int min, max;
1554
1555 min = 0;
1557
1558 while (min <= max)
1559 {
1560 int n, c;
1561
1562 n = (min+max)/2;
1563
1565 if (!c && !olemisc_values[n].name[len])
1566 return olemisc_values[n].value;
1567
1568 if (c >= 0)
1569 max = n-1;
1570 else
1571 min = n+1;
1572 }
1573
1574 WARN("unknown flag %s\n", debugstr_wn(str, len));
1575 return 0;
1576}
1577
1579{
1580 const WCHAR *str = value->ptr, *start;
1581 DWORD flags = 0;
1582 int i = 0;
1583
1584 /* it's comma separated list of flags */
1585 while (i < value->len)
1586 {
1587 start = str;
1588 while (*str != ',' && (i++ < value->len)) str++;
1589
1591
1592 /* skip separator */
1593 str++;
1594 i++;
1595 }
1596
1597 return flags;
1598}
1599
1601{
1602 struct progids *progids = &entity->u.comclass.progids;
1603
1604 if (progids->allocated == 0)
1605 {
1606 progids->allocated = 4;
1607 if (!(progids->progids = RtlAllocateHeap(GetProcessHeap(), 0, progids->allocated * sizeof(WCHAR*)))) return FALSE;
1608 }
1609
1610 if (progids->allocated == progids->num)
1611 {
1612 WCHAR **new_progids = RtlReAllocateHeap(GetProcessHeap(), 0, progids->progids,
1613 2 * progids->allocated * sizeof(WCHAR*));
1614 if (!new_progids) return FALSE;
1615 progids->allocated *= 2;
1616 progids->progids = new_progids;
1617 }
1618
1619 if (!(progids->progids[progids->num] = xmlstrdupW(progid))) return FALSE;
1620 progids->num++;
1621
1622 return TRUE;
1623}
1624
1625static void parse_com_class_progid(xmlbuf_t *xmlbuf, struct entity *entity, const struct xml_elem *parent)
1626{
1628 BOOL end = FALSE;
1629
1630 parse_expect_no_attr(xmlbuf, &end);
1631 if (end) set_error( xmlbuf );
1632 if (!parse_text_content(xmlbuf, &content)) return;
1633
1634 if (!com_class_add_progid(&content, entity)) set_error( xmlbuf );
1636}
1637
1638static void parse_com_class_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll, struct actctx_loader *acl,
1639 const struct xml_elem *parent )
1640{
1641 struct xml_elem elem;
1642 struct xml_attr attr;
1643 BOOL end = FALSE;
1644 struct entity* entity;
1645
1646 if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)))
1647 {
1648 set_error( xmlbuf );
1649 return;
1650 }
1651
1652 while (next_xml_attr(xmlbuf, &attr, &end))
1653 {
1654 if (xml_attr_cmp(&attr, L"clsid"))
1655 {
1656 if (!(entity->u.comclass.clsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1657 }
1658 else if (xml_attr_cmp(&attr, L"progid"))
1659 {
1660 if (!(entity->u.comclass.progid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1661 }
1662 else if (xml_attr_cmp(&attr, L"tlbid"))
1663 {
1664 if (!(entity->u.comclass.tlbid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1665 }
1666 else if (xml_attr_cmp(&attr, L"threadingModel"))
1667 {
1669 }
1670 else if (xml_attr_cmp(&attr, L"miscStatus"))
1671 {
1673 }
1674 else if (xml_attr_cmp(&attr, L"miscStatusContent"))
1675 {
1676 entity->u.comclass.miscstatuscontent = parse_com_class_misc(&attr.value);
1677 }
1678 else if (xml_attr_cmp(&attr, L"miscStatusThumbnail"))
1679 {
1680 entity->u.comclass.miscstatusthumbnail = parse_com_class_misc(&attr.value);
1681 }
1682 else if (xml_attr_cmp(&attr, L"miscStatusIcon"))
1683 {
1684 entity->u.comclass.miscstatusicon = parse_com_class_misc(&attr.value);
1685 }
1686 else if (xml_attr_cmp(&attr, L"miscStatusDocPrint"))
1687 {
1688 entity->u.comclass.miscstatusdocprint = parse_com_class_misc(&attr.value);
1689 }
1690 else if (xml_attr_cmp(&attr, L"description"))
1691 {
1692 /* not stored */
1693 }
1694 else if (!is_xmlns_attr( &attr ))
1695 {
1696 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
1697 }
1698 }
1699
1701 if (entity->u.comclass.progid)
1703
1704 if (end) return;
1705
1706 while (next_xml_elem(xmlbuf, &elem, parent))
1707 {
1708 if (xml_elem_cmp(&elem, L"progid", asmv1W))
1709 {
1711 }
1712 else
1713 {
1714 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
1715 parse_unknown_elem(xmlbuf, &elem);
1716 }
1717 }
1718
1719 if (entity->u.comclass.progids.num)
1721}
1722
1724{
1725 const WCHAR *curr;
1726 ULONG num = 0;
1727
1728 for (curr = str->ptr; curr < str->ptr + str->len; curr++)
1729 {
1730 if (*curr >= '0' && *curr <= '9')
1731 num = num * 10 + *curr - '0';
1732 else
1733 {
1734 ERR("wrong numeric value %s\n", debugstr_xmlstr(str));
1735 return FALSE;
1736 }
1737 }
1738 entity->u.ifaceps.nummethods = num;
1739
1740 return TRUE;
1741}
1742
1743static void parse_add_interface_class( xmlbuf_t *xmlbuf, struct entity_array *entities,
1744 struct actctx_loader *acl, WCHAR *clsid )
1745{
1746 struct entity *entity;
1747 WCHAR *str;
1748
1749 if (!clsid) return;
1750
1751 if (!(str = strdupW(clsid)))
1752 {
1753 set_error( xmlbuf );
1754 return;
1755 }
1756
1757 if (!(entity = add_entity(entities, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)))
1758 {
1760 set_error( xmlbuf );
1761 return;
1762 }
1763
1764 entity->u.comclass.clsid = str;
1766
1768}
1769
1771 struct actctx_loader *acl, const struct xml_elem *parent )
1772{
1773 WCHAR *psclsid = NULL;
1774 struct entity *entity;
1775 struct xml_attr attr;
1776 BOOL end = FALSE;
1777
1778 if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION)))
1779 {
1780 set_error( xmlbuf );
1781 return;
1782 }
1783
1784 while (next_xml_attr(xmlbuf, &attr, &end))
1785 {
1786 if (xml_attr_cmp(&attr, L"iid"))
1787 {
1788 if (!(entity->u.ifaceps.iid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1789 }
1790 else if (xml_attr_cmp(&attr, L"name"))
1791 {
1792 if (!(entity->u.ifaceps.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1793 }
1794 else if (xml_attr_cmp(&attr, L"baseInterface"))
1795 {
1796 if (!(entity->u.ifaceps.base = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1797 entity->u.ifaceps.mask |= BaseIface;
1798 }
1799 else if (xml_attr_cmp(&attr, L"numMethods"))
1800 {
1801 if (!(parse_nummethods(&attr.value, entity))) set_error( xmlbuf );
1802 entity->u.ifaceps.mask |= NumMethods;
1803 }
1804 else if (xml_attr_cmp(&attr, L"tlbid"))
1805 {
1806 if (!(entity->u.ifaceps.tlib = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1807 }
1808 else if (xml_attr_cmp(&attr, L"proxyStubClsid32"))
1809 {
1810 if (!(psclsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1811 }
1812 /* not used */
1813 else if (xml_attr_cmp(&attr, L"threadingModel"))
1814 {
1815 }
1816 else if (!is_xmlns_attr( &attr ))
1817 {
1818 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
1819 }
1820 }
1821
1823 if (!end) parse_expect_end_elem(xmlbuf, parent);
1824
1825 parse_add_interface_class(xmlbuf, &dll->entities, acl, psclsid ? psclsid : entity->u.ifaceps.iid);
1826
1827 RtlFreeHeap(GetProcessHeap(), 0, psclsid);
1828}
1829
1831{
1832 WORD *flags = &entity->u.typelib.flags;
1833 const WCHAR *str = value->ptr, *start;
1834 int i = 0;
1835
1836 *flags = 0;
1837
1838 /* it's comma separated list of flags */
1839 while (i < value->len)
1840 {
1841 start = str;
1842 while (*str != ',' && (i++ < value->len)) str++;
1843
1844 if (!wcsnicmp(start, L"RESTRICTED", str-start))
1846 else if (!wcsnicmp(start, L"CONTROL", str-start))
1848 else if (!wcsnicmp(start, L"HIDDEN", str-start))
1850 else if (!wcsnicmp(start, L"HASDISKIMAGE", str-start))
1852 else
1853 {
1854 WARN("unknown flags value %s\n", debugstr_xmlstr(value));
1855 return FALSE;
1856 }
1857
1858 /* skip separator */
1859 str++;
1860 i++;
1861 }
1862
1863 return TRUE;
1864}
1865
1867{
1868 unsigned int ver[2];
1869 unsigned int pos;
1870 const WCHAR *curr;
1871
1872 /* major.minor */
1873 ver[0] = ver[1] = pos = 0;
1874 for (curr = str->ptr; curr < str->ptr + str->len; curr++)
1875 {
1876 if (*curr >= '0' && *curr <= '9')
1877 {
1878 ver[pos] = ver[pos] * 10 + *curr - '0';
1879 if (ver[pos] >= 0x10000) goto error;
1880 }
1881 else if (*curr == '.')
1882 {
1883 if (++pos >= 2) goto error;
1884 }
1885 else goto error;
1886 }
1887 entity->u.typelib.major = ver[0];
1888 entity->u.typelib.minor = ver[1];
1889 return TRUE;
1890
1891error:
1892 FIXME("wrong typelib version value (%s)\n", debugstr_xmlstr(str));
1893 return FALSE;
1894}
1895
1896static void parse_typelib_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll,
1897 struct actctx_loader *acl, const struct xml_elem *parent )
1898{
1899 struct xml_attr attr;
1900 BOOL end = FALSE;
1901 struct entity* entity;
1902
1903 if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION)))
1904 {
1905 set_error( xmlbuf );
1906 return;
1907 }
1908
1909 while (next_xml_attr(xmlbuf, &attr, &end))
1910 {
1911 if (xml_attr_cmp(&attr, L"tlbid"))
1912 {
1913 if (!(entity->u.typelib.tlbid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1914 }
1915 else if (xml_attr_cmp(&attr, L"version"))
1916 {
1917 if (!parse_typelib_version(&attr.value, entity)) set_error( xmlbuf );
1918 }
1919 else if (xml_attr_cmp(&attr, L"helpdir"))
1920 {
1921 if (!(entity->u.typelib.helpdir = xmlstrdupW(&attr.value))) set_error( xmlbuf );
1922 }
1923 else if (xml_attr_cmp(&attr, L"flags"))
1924 {
1925 if (!parse_typelib_flags(&attr.value, entity)) set_error( xmlbuf );
1926 }
1927 else if (!is_xmlns_attr( &attr ))
1928 {
1929 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
1930 }
1931 }
1932
1934 if (!end) parse_expect_end_elem(xmlbuf, parent);
1935}
1936
1937static inline int aligned_string_len(int len)
1938{
1939 return (len + 3) & ~3;
1940}
1941
1943{
1944 struct assembly_version *ver = &assembly->id.version;
1945 WCHAR buff[25];
1946
1947 if (!ret) ret = buff;
1948 return swprintf(ret, ARRAY_SIZE(buff), L"%u.%u.%u.%u", ver->major, ver->minor, ver->build, ver->revision);
1949}
1950
1951static void parse_window_class_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll,
1952 struct actctx_loader *acl, const struct xml_elem *parent )
1953{
1954 struct xml_elem elem;
1955 struct xml_attr attr;
1957 BOOL end = FALSE;
1958 struct entity* entity;
1959
1960 if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION)))
1961 {
1962 set_error( xmlbuf );
1963 return;
1964 }
1965 entity->u.class.versioned = TRUE;
1966 while (next_xml_attr(xmlbuf, &attr, &end))
1967 {
1968 if (xml_attr_cmp(&attr, L"versioned"))
1969 {
1970 if (xmlstr_cmpi(&attr.value, L"no"))
1971 entity->u.class.versioned = FALSE;
1972 else if (!xmlstr_cmpi(&attr.value, L"yes"))
1973 set_error( xmlbuf );
1974 }
1975 else if (!is_xmlns_attr( &attr ))
1976 {
1977 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
1978 }
1979 }
1980
1981 if (end) return;
1982
1983 if (!parse_text_content(xmlbuf, &content)) return;
1984 if (!(entity->u.class.name = xmlstrdupW(&content))) set_error( xmlbuf );
1985
1987
1988 while (next_xml_elem(xmlbuf, &elem, parent))
1989 {
1990 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
1991 parse_unknown_elem(xmlbuf, &elem);
1992 }
1993}
1994
1995static void parse_binding_redirect_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent )
1996{
1997 struct xml_attr attr;
1998 BOOL end = FALSE;
1999
2000 while (next_xml_attr(xmlbuf, &attr, &end))
2001 {
2002 if (xml_attr_cmp(&attr, L"oldVersion"))
2003 {
2004 FIXME("Not stored yet %s\n", debugstr_xml_attr(&attr));
2005 }
2006 else if (xml_attr_cmp(&attr, L"newVersion"))
2007 {
2008 FIXME("Not stored yet %s\n", debugstr_xml_attr(&attr));
2009 }
2010 else if (!is_xmlns_attr( &attr ))
2011 {
2012 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2013 }
2014 }
2015
2016 if (!end) parse_expect_end_elem(xmlbuf, parent);
2017}
2018
2019static void parse_description_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent )
2020{
2021 struct xml_elem elem;
2022 struct xml_attr attr;
2024 BOOL end = FALSE;
2025
2026 while (next_xml_attr(xmlbuf, &attr, &end))
2027 {
2028 if (!is_xmlns_attr( &attr )) WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2029 }
2030
2031 if (end) return;
2032 if (!parse_text_content(xmlbuf, &content)) return;
2033
2034 TRACE("Got description %s\n", debugstr_xmlstr(&content));
2035
2036 while (next_xml_elem(xmlbuf, &elem, parent))
2037 {
2038 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2039 parse_unknown_elem(xmlbuf, &elem);
2040 }
2041}
2042
2044 struct assembly* assembly,
2045 struct actctx_loader* acl,
2046 const struct xml_elem *parent)
2047{
2048 struct xml_attr attr;
2049 BOOL end = FALSE;
2050 struct entity* entity;
2051
2052 if (!(entity = add_entity(&assembly->entities, ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION)))
2053 {
2054 set_error( xmlbuf );
2055 return;
2056 }
2057
2058 while (next_xml_attr(xmlbuf, &attr, &end))
2059 {
2060 if (xml_attr_cmp(&attr, L"iid"))
2061 {
2062 if (!(entity->u.ifaceps.iid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2063 }
2064 else if (xml_attr_cmp(&attr, L"name"))
2065 {
2066 if (!(entity->u.ifaceps.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2067 }
2068 else if (xml_attr_cmp(&attr, L"baseInterface"))
2069 {
2070 if (!(entity->u.ifaceps.base = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2071 entity->u.ifaceps.mask |= BaseIface;
2072 }
2073 else if (xml_attr_cmp(&attr, L"numMethods"))
2074 {
2075 if (!(parse_nummethods(&attr.value, entity))) set_error( xmlbuf );
2076 entity->u.ifaceps.mask |= NumMethods;
2077 }
2078 else if (xml_attr_cmp(&attr, L"proxyStubClsid32"))
2079 {
2080 if (!(entity->u.ifaceps.ps32 = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2081 }
2082 else if (xml_attr_cmp(&attr, L"tlbid"))
2083 {
2084 if (!(entity->u.ifaceps.tlib = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2085 }
2086 else if (!is_xmlns_attr( &attr ))
2087 {
2088 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2089 }
2090 }
2091
2093 if (!end) parse_expect_end_elem(xmlbuf, parent);
2094}
2095
2096static void parse_clr_class_elem( xmlbuf_t* xmlbuf, struct assembly* assembly,
2097 struct actctx_loader *acl, const struct xml_elem *parent )
2098
2099{
2100 struct xml_elem elem;
2101 struct xml_attr attr;
2102 BOOL end = FALSE;
2103 struct entity* entity;
2104
2105 if (!(entity = add_entity(&assembly->entities, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)))
2106 {
2107 set_error( xmlbuf );
2108 return;
2109 }
2110
2111 while (next_xml_attr(xmlbuf, &attr, &end))
2112 {
2113 if (xml_attr_cmp(&attr, L"name"))
2114 {
2115 if (!(entity->u.comclass.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2116 }
2117 else if (xml_attr_cmp(&attr, L"clsid"))
2118 {
2119 if (!(entity->u.comclass.clsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2120 }
2121 else if (xml_attr_cmp(&attr, L"progid"))
2122 {
2123 if (!(entity->u.comclass.progid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2124 }
2125 else if (xml_attr_cmp(&attr, L"tlbid"))
2126 {
2127 if (!(entity->u.comclass.tlbid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2128 }
2129 else if (xml_attr_cmp(&attr, L"threadingModel"))
2130 {
2132 }
2133 else if (xml_attr_cmp(&attr, L"runtimeVersion"))
2134 {
2135 if (!(entity->u.comclass.version = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2136 }
2137 else if (!is_xmlns_attr( &attr ))
2138 {
2139 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2140 }
2141 }
2142
2144 if (entity->u.comclass.progid)
2146 if (end) return;
2147
2148 while (next_xml_elem(xmlbuf, &elem, parent))
2149 {
2150 if (xml_elem_cmp(&elem, L"progid", asmv1W))
2151 {
2153 }
2154 else
2155 {
2156 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2157 parse_unknown_elem(xmlbuf, &elem);
2158 }
2159 }
2160
2161 if (entity->u.comclass.progids.num)
2163}
2164
2166 struct actctx_loader *acl, const struct xml_elem *parent )
2167{
2168 struct xml_attr attr;
2169 BOOL end = FALSE;
2170 struct entity* entity;
2171
2172 if (!(entity = add_entity(&assembly->entities, ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES)))
2173 {
2174 set_error( xmlbuf );
2175 return;
2176 }
2177
2178 while (next_xml_attr(xmlbuf, &attr, &end))
2179 {
2180 if (xml_attr_cmp(&attr, L"name"))
2181 {
2182 if (!(entity->u.clrsurrogate.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2183 }
2184 else if (xml_attr_cmp(&attr, L"clsid"))
2185 {
2186 if (!(entity->u.clrsurrogate.clsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2187 }
2188 else if (xml_attr_cmp(&attr, L"runtimeVersion"))
2189 {
2190 if (!(entity->u.clrsurrogate.version = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2191 }
2192 else if (!is_xmlns_attr( &attr ))
2193 {
2194 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2195 }
2196 }
2197
2199 if (!end) parse_expect_end_elem(xmlbuf, parent);
2200}
2201
2202static void parse_dependent_assembly_elem( xmlbuf_t *xmlbuf, struct actctx_loader *acl,
2203 const struct xml_elem *parent, BOOL optional )
2204{
2205 struct xml_elem elem;
2206 struct xml_attr attr;
2207 struct assembly_identity ai;
2208 BOOL end = FALSE;
2209
2210 memset(&ai, 0, sizeof(ai));
2211 ai.optional = optional;
2212
2213 while (next_xml_attr(xmlbuf, &attr, &end))
2214 {
2215 if (xml_attr_cmp(&attr, L"allowDelayedBinding"))
2216 ai.delayed = xmlstr_cmp(&attr.value, L"true");
2217 else if (!is_xmlns_attr( &attr ))
2218 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2219 }
2220
2221 if (end) return;
2222
2223 while (next_xml_elem(xmlbuf, &elem, parent))
2224 {
2225 if (xml_elem_cmp(&elem, L"assemblyIdentity", asmv1W))
2226 {
2227 parse_assembly_identity_elem(xmlbuf, acl->actctx, &ai, &elem);
2228 /* store the newly found identity for later loading */
2229 if (ai.arch && !wcscmp(ai.arch, L"*"))
2230 {
2231 RtlFreeHeap( GetProcessHeap(), 0, ai.arch );
2232 ai.arch = strdupW( current_archW );
2233 }
2234 TRACE( "adding name=%s version=%s arch=%s\n",
2236 if (!add_dependent_assembly_id(acl, &ai)) set_error( xmlbuf );
2237 }
2238 else if (xml_elem_cmp(&elem, L"bindingRedirect", asmv1W))
2239 {
2241 }
2242 else
2243 {
2244 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2245 parse_unknown_elem(xmlbuf, &elem);
2246 }
2247 }
2248}
2249
2250static void parse_dependency_elem( xmlbuf_t *xmlbuf, struct actctx_loader *acl,
2251 const struct xml_elem *parent )
2252
2253{
2254 struct xml_elem elem;
2255 struct xml_attr attr;
2257
2258 while (next_xml_attr(xmlbuf, &attr, &end))
2259 {
2260 if (xml_attr_cmp(&attr, L"optional"))
2261 {
2262 optional = xmlstr_cmpi( &attr.value, L"yes" );
2263 TRACE("optional=%s\n", debugstr_xmlstr(&attr.value));
2264 }
2265 else if (!is_xmlns_attr( &attr ))
2266 {
2267 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2268 }
2269 }
2270
2271 if (end) return;
2272
2273 while (next_xml_elem(xmlbuf, &elem, parent))
2274 {
2275 if (xml_elem_cmp(&elem, L"dependentAssembly", asmv1W))
2276 {
2278 }
2279 else
2280 {
2281 WARN("unknown element %s\n", debugstr_xml_elem(&elem));
2282 parse_unknown_elem(xmlbuf, &elem);
2283 }
2284 }
2285}
2286
2287static void parse_noinherit_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent )
2288{
2289 BOOL end = FALSE;
2290
2291 parse_expect_no_attr(xmlbuf, &end);
2292 if (!end) parse_expect_end_elem(xmlbuf, parent);
2293}
2294
2295static void parse_noinheritable_elem( xmlbuf_t *xmlbuf, const struct xml_elem *parent )
2296{
2297 BOOL end = FALSE;
2298
2299 parse_expect_no_attr(xmlbuf, &end);
2300 if (!end) parse_expect_end_elem(xmlbuf, parent);
2301}
2302
2303static void parse_activatable_class_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll,
2304 struct actctx_loader *acl, const struct xml_elem *parent )
2305{
2306 struct xml_elem elem;
2307 struct xml_attr attr;
2308 BOOL end = FALSE;
2309 struct entity *entity;
2310
2311 if (!(entity = add_entity(&dll->entities, ACTIVATION_CONTEXT_SECTION_WINRT_ACTIVATABLE_CLASSES)))
2312 {
2313 set_error( xmlbuf );
2314 return;
2315 }
2316 while (next_xml_attr(xmlbuf, &attr, &end))
2317 {
2318 if (xml_attr_cmp(&attr, L"name"))
2319 {
2320 if (!(entity->u.activatable_class.name = xmlstrdupW(&attr.value)))
2321 set_error( xmlbuf );
2322 }
2323 else if (xml_attr_cmp(&attr, L"threadingModel"))
2324 {
2325 if (xmlstr_cmpi(&attr.value, L"both"))
2326 entity->u.activatable_class.threading_model = 0;
2327 else if (xmlstr_cmpi(&attr.value, L"sta"))
2328 entity->u.activatable_class.threading_model = 1;
2329 else if (xmlstr_cmpi(&attr.value, L"mta"))
2330 entity->u.activatable_class.threading_model = 2;
2331 else
2332 set_error( xmlbuf );
2333 }
2334 else if (!is_xmlns_attr( &attr ))
2335 {
2336 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2337 }
2338 }
2339
2341
2342 if (end) return;
2343
2344 while (next_xml_elem(xmlbuf, &elem, parent))
2345 {
2346 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2347 parse_unknown_elem(xmlbuf, &elem);
2348 }
2349}
2350
2351static void parse_file_elem( xmlbuf_t* xmlbuf, struct assembly* assembly,
2352 struct actctx_loader* acl, const struct xml_elem *parent )
2353{
2354 struct xml_elem elem;
2355 struct xml_attr attr;
2356 BOOL end = FALSE;
2357 struct dll_redirect* dll;
2358
2359 if (!(dll = add_dll_redirect(assembly)))
2360 {
2361 set_error( xmlbuf );
2362 return;
2363 }
2364
2365 while (next_xml_attr(xmlbuf, &attr, &end))
2366 {
2367 if (xml_attr_cmp(&attr, L"name"))
2368 {
2369 if (!(dll->name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2370 TRACE("name=%s\n", debugstr_xmlstr(&attr.value));
2371 }
2372 else if (xml_attr_cmp(&attr, L"loadFrom"))
2373 {
2374 if (!(dll->load_from = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2375 }
2376 else if (xml_attr_cmp(&attr, L"hash"))
2377 {
2378 if (!(dll->hash = xmlstrdupW(&attr.value))) set_error( xmlbuf );
2379 }
2380 else if (xml_attr_cmp(&attr, L"hashalg"))
2381 {
2382 if (!xmlstr_cmpi(&attr.value, L"SHA1"))
2383 FIXME("hashalg should be SHA1, got %s\n", debugstr_xmlstr(&attr.value));
2384 }
2385 else if (!is_xmlns_attr( &attr ))
2386 {
2387 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2388 }
2389 }
2390
2391 if (!dll->name) set_error( xmlbuf );
2392
2394
2395 if (end) return;
2396
2397 while (next_xml_elem(xmlbuf, &elem, parent))
2398 {
2399 if (xml_elem_cmp(&elem, L"comClass", asmv1W))
2400 {
2401 parse_com_class_elem(xmlbuf, dll, acl, &elem);
2402 }
2403 else if (xml_elem_cmp(&elem, L"comInterfaceProxyStub", asmv1W))
2404 {
2405 parse_cominterface_proxy_stub_elem(xmlbuf, dll, acl, &elem);
2406 }
2407 else if (xml_elem_cmp(&elem, L"hash", asmv2W))
2408 {
2409 WARN("asmv2:hash (undocumented) not supported\n");
2410 parse_unknown_elem(xmlbuf, &elem);
2411 }
2412 else if (xml_elem_cmp(&elem, L"typelib", asmv1W))
2413 {
2414 parse_typelib_elem(xmlbuf, dll, acl, &elem);
2415 }
2416 else if (xml_elem_cmp(&elem, L"windowClass", asmv1W))
2417 {
2418 parse_window_class_elem(xmlbuf, dll, acl, &elem);
2419 }
2420 else if (xml_elem_cmp(&elem, L"activatableClass", winrtv1W))
2421 {
2422 parse_activatable_class_elem(xmlbuf, dll, acl, &elem);
2423 }
2424 else
2425 {
2426 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2427 parse_unknown_elem( xmlbuf, &elem );
2428 }
2429 }
2430}
2431
2432static void parse_supportedos_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
2433 struct actctx_loader *acl, const struct xml_elem *parent )
2434{
2435 struct xml_attr attr;
2436 BOOL end = FALSE;
2437
2438 while (next_xml_attr(xmlbuf, &attr, &end))
2439 {
2440 if (xml_attr_cmp(&attr, L"Id"))
2441 {
2442 COMPATIBILITY_CONTEXT_ELEMENT *compat;
2444 GUID compat_id;
2445
2446 str.Buffer = (PWSTR)attr.value.ptr;
2447 str.Length = str.MaximumLength = (USHORT)attr.value.len * sizeof(WCHAR);
2448 if (RtlGUIDFromString(&str, &compat_id) == STATUS_SUCCESS)
2449 {
2450 if (!(compat = add_compat_context(assembly)))
2451 {
2452 set_error( xmlbuf );
2453 return;
2454 }
2455 compat->Type = ACTCTX_COMPATIBILITY_ELEMENT_TYPE_OS;
2456 compat->Id = compat_id;
2457 }
2458 else
2459 {
2460 WARN("Invalid guid %s\n", debugstr_xmlstr(&attr.value));
2461 }
2462 }
2463 else if (!is_xmlns_attr( &attr ))
2464 {
2465 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2466 }
2467 }
2468
2469 if (!end) parse_expect_end_elem(xmlbuf, parent);
2470}
2471
2472#if (NTDDI_VERSION >= NTDDI_WIN10_19H1)
2474 struct actctx_loader *acl, const struct xml_elem *parent )
2475{
2476 struct xml_attr attr;
2477 BOOL end = FALSE;
2478
2479 while (next_xml_attr(xmlbuf, &attr, &end))
2480 {
2481 if (xml_attr_cmp(&attr, L"Id"))
2482 {
2483 COMPATIBILITY_CONTEXT_ELEMENT *compat;
2485
2486 if (!(compat = add_compat_context(assembly)))
2487 {
2488 set_error( xmlbuf );
2489 return;
2490 }
2492 compat->Type = ACTCTX_COMPATIBILITY_ELEMENT_TYPE_MAXVERSIONTESTED;
2493 compat->MaxVersionTested = (ULONGLONG)version.major << 48 |
2494 (ULONGLONG)version.minor << 32 | version.build << 16 | version.revision;
2495 }
2496 else if (!is_xmlns_attr( &attr ))
2497 {
2498 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2499 }
2500 }
2501
2502 if (!end) parse_expect_end_elem(xmlbuf, parent);
2503}
2504#endif // NTDDI_VERSION >= NTDDI_WIN10_19H1
2505
2507 struct actctx_loader* acl, const struct xml_elem *parent)
2508{
2509 struct xml_elem elem;
2510
2511 while (next_xml_elem(xmlbuf, &elem, parent))
2512 {
2513 if (xml_elem_cmp(&elem, L"supportedOS", compatibilityNSW))
2514 {
2515 parse_supportedos_elem(xmlbuf, assembly, acl, &elem);
2516 }
2517#if (NTDDI_VERSION >= NTDDI_WIN10_19H1)
2518 else if (xml_elem_cmp(&elem, L"maxversiontested", compatibilityNSW))
2519 {
2521 }
2522#endif // NTDDI_VERSION >= NTDDI_WIN10_19H1
2523 else
2524 {
2525 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2526 parse_unknown_elem(xmlbuf, &elem);
2527 }
2528 }
2529}
2530
2532 struct actctx_loader* acl, const struct xml_elem *parent)
2533{
2534 struct xml_elem elem;
2535
2536 while (next_xml_elem(xmlbuf, &elem, parent))
2537 {
2538 if (xml_elem_cmp(&elem, L"application", compatibilityNSW))
2539 {
2541 }
2542 else
2543 {
2544 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2545 parse_unknown_elem(xmlbuf, &elem);
2546 }
2547 }
2548}
2549
2550static void parse_settings_elem( xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl,
2551 struct xml_elem *parent )
2552{
2553 struct xml_elem elem;
2554 struct xml_attr attr;
2556 BOOL end = FALSE;
2557 struct entity *entity;
2558
2559 while (next_xml_attr( xmlbuf, &attr, &end ))
2560 {
2561 if (!is_xmlns_attr( &attr )) WARN( "unknown attr %s\n", debugstr_xml_attr(&attr) );
2562 }
2563
2564 if (end) return;
2565
2566 if (!parse_text_content( xmlbuf, &content )) return;
2567 TRACE( "got %s %s\n", debugstr_xmlstr(&parent->name), debugstr_xmlstr(&content) );
2568
2569 entity = add_entity( &assembly->entities, ACTIVATION_CONTEXT_SECTION_APPLICATION_SETTINGS );
2570 if (!entity)
2571 {
2572 set_error( xmlbuf );
2573 return;
2574 }
2575 entity->u.settings.name = xmlstrdupW( &parent->name );
2576 entity->u.settings.value = xmlstrdupW( &content );
2577 entity->u.settings.ns = xmlstrdupW( &parent->ns );
2578
2579 while (next_xml_elem(xmlbuf, &elem, parent))
2580 {
2581 WARN( "unknown elem %s\n", debugstr_xml_elem(&elem) );
2582 parse_unknown_elem( xmlbuf, &elem );
2583 }
2584}
2585
2587 struct actctx_loader *acl, const struct xml_elem *parent )
2588{
2589 struct xml_elem elem;
2590
2591 while (next_xml_elem( xmlbuf, &elem, parent ))
2592 {
2593 if (xml_elem_cmp( &elem, L"activeCodePage", windowsSettings2019NSW ) ||
2594 xml_elem_cmp( &elem, L"autoElevate", windowsSettings2005NSW ) ||
2595 xml_elem_cmp( &elem, L"disableTheming", windowsSettings2005NSW ) ||
2596 xml_elem_cmp( &elem, L"disableWindowFiltering", windowsSettings2011NSW ) ||
2597 xml_elem_cmp( &elem, L"dpiAware", windowsSettings2005NSW ) ||
2598 xml_elem_cmp( &elem, L"dpiAwareness", windowsSettings2016NSW ) ||
2599 xml_elem_cmp( &elem, L"gdiScaling", windowsSettings2017NSW ) ||
2600 xml_elem_cmp( &elem, L"heapType", windowsSettings2020NSW ) ||
2601 xml_elem_cmp( &elem, L"highResolutionScrollingAware", windowsSettings2017NSW ) ||
2602 xml_elem_cmp( &elem, L"longPathAware", windowsSettings2016NSW ) ||
2603 xml_elem_cmp( &elem, L"magicFutureSetting", windowsSettings2017NSW ) ||
2604 xml_elem_cmp( &elem, L"printerDriverIsolation", windowsSettings2011NSW ) ||
2605 xml_elem_cmp( &elem, L"ultraHighResolutionScrollingAware", windowsSettings2017NSW ))
2606 {
2607 parse_settings_elem( xmlbuf, assembly, acl, &elem );
2608 }
2609 else
2610 {
2611 WARN( "unknown elem %s\n", debugstr_xml_elem(&elem) );
2612 parse_unknown_elem( xmlbuf, &elem );
2613 }
2614 }
2615}
2616
2617static void parse_application_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
2618 struct actctx_loader *acl, const struct xml_elem *parent )
2619{
2620 struct xml_elem elem;
2621 struct xml_attr attr;
2622 BOOL end = FALSE;
2623
2624 while (next_xml_attr(xmlbuf, &attr, &end))
2625 {
2626 if (!is_xmlns_attr( &attr )) WARN( "unknown attr %s\n", debugstr_xml_attr(&attr) );
2627 }
2628
2629 if (end) return;
2630
2631 while (next_xml_elem( xmlbuf, &elem, parent ))
2632 {
2633 if (xml_elem_cmp( &elem, L"windowsSettings", asmv1W ))
2634 {
2635 parse_windows_settings_elem( xmlbuf, assembly, acl, &elem );
2636 }
2637 else
2638 {
2639 WARN( "unknown elem %s\n", debugstr_xml_elem(&elem) );
2640 parse_unknown_elem( xmlbuf, &elem );
2641 }
2642 }
2643}
2644
2646 struct actctx_loader *acl, const struct xml_elem *parent )
2647{
2648 struct xml_elem elem;
2649 struct xml_attr attr;
2650 BOOL end = FALSE;
2651
2652 /* Multiple requestedExecutionLevel elements are not supported. */
2653 if (assembly->run_level != ACTCTX_RUN_LEVEL_UNSPECIFIED) set_error( xmlbuf );
2654
2655 while (next_xml_attr(xmlbuf, &attr, &end))
2656 {
2657 if (xml_attr_cmp(&attr, L"level"))
2658 {
2659 if (xmlstr_cmpi(&attr.value, L"asInvoker"))
2660 assembly->run_level = ACTCTX_RUN_LEVEL_AS_INVOKER;
2661 else if (xmlstr_cmpi(&attr.value, L"highestAvailable"))
2662 assembly->run_level = ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE;
2663 else if (xmlstr_cmpi(&attr.value, L"requireAdministrator"))
2664 assembly->run_level = ACTCTX_RUN_LEVEL_REQUIRE_ADMIN;
2665 else
2666 FIXME("unknown execution level: %s\n", debugstr_xmlstr(&attr.value));
2667 }
2668 else if (xml_attr_cmp(&attr, L"uiAccess"))
2669 {
2670 if (xmlstr_cmpi(&attr.value, L"false"))
2672 else if (xmlstr_cmpi(&attr.value, L"true"))
2674 else
2675 FIXME("unknown uiAccess value: %s\n", debugstr_xmlstr(&attr.value));
2676 }
2677 else if (!is_xmlns_attr( &attr ))
2678 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2679 }
2680
2681 if (end) return;
2682
2683 while (next_xml_elem(xmlbuf, &elem, parent))
2684 {
2685 WARN("unknown element %s\n", debugstr_xml_elem(&elem));
2686 parse_unknown_elem(xmlbuf, &elem);
2687 }
2688}
2689
2691 struct actctx_loader *acl, const struct xml_elem *parent )
2692{
2693 struct xml_elem elem;
2694
2695 while (next_xml_elem(xmlbuf, &elem, parent))
2696 {
2697 if (xml_elem_cmp(&elem, L"requestedExecutionLevel", asmv1W))
2698 {
2700 }
2701 else
2702 {
2703 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2704 parse_unknown_elem(xmlbuf, &elem);
2705 }
2706 }
2707}
2708
2709static void parse_security_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
2710 struct actctx_loader *acl, const struct xml_elem *parent )
2711{
2712 struct xml_elem elem;
2713
2714 while (next_xml_elem(xmlbuf, &elem, parent))
2715 {
2716 if (xml_elem_cmp(&elem, L"requestedPrivileges", asmv1W))
2717 {
2719 }
2720 else
2721 {
2722 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2723 parse_unknown_elem(xmlbuf, &elem);
2724 }
2725 }
2726}
2727
2728static void parse_trust_info_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
2729 struct actctx_loader *acl, const struct xml_elem *parent )
2730{
2731 struct xml_elem elem;
2732
2733 while (next_xml_elem(xmlbuf, &elem, parent))
2734 {
2735 if (xml_elem_cmp(&elem, L"security", asmv1W))
2736 {
2737 parse_security_elem(xmlbuf, assembly, acl, &elem);
2738 }
2739 else
2740 {
2741 WARN("unknown elem %s\n", debugstr_xml_elem(&elem));
2742 parse_unknown_elem(xmlbuf, &elem);
2743 }
2744 }
2745}
2746
2747static void parse_assembly_elem( xmlbuf_t *xmlbuf, struct assembly* assembly,
2748 struct actctx_loader* acl, const struct xml_elem *parent,
2749 struct assembly_identity* expected_ai)
2750{
2751 struct xml_elem elem;
2752 struct xml_attr attr;
2753 BOOL end = FALSE, version = FALSE;
2754
2755 TRACE("(%p)\n", xmlbuf);
2756
2757 while (next_xml_attr(xmlbuf, &attr, &end))
2758 {
2759 if (xml_attr_cmp(&attr, L"manifestVersion"))
2760 {
2761 if (!xmlstr_cmp(&attr.value, L"1.0"))
2762 {
2763 FIXME("wrong version %s\n", debugstr_xmlstr(&attr.value));
2764 break;
2765 }
2766 version = TRUE;
2767 }
2768 else if (!is_xmlns_attr( &attr ))
2769 {
2770 WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
2771 }
2772 }
2773
2774 if (!version)
2775 {
2776 set_error( xmlbuf );
2777 return;
2778 }
2779
2780 if (end)
2781 return;
2782
2783 while (next_xml_elem(xmlbuf, &elem, parent))
2784 {
2785 if (assembly->type == APPLICATION_MANIFEST && xml_elem_cmp(&elem, L"noInherit", asmv1W))
2786 {
2787 parse_noinherit_elem(xmlbuf, &elem);
2789 }
2790 else if (xml_elem_cmp(&elem, L"noInheritable", asmv1W))
2791 {
2793 }
2794 else if (xml_elem_cmp(&elem, L"description", asmv1W))
2795 {
2796 parse_description_elem(xmlbuf, &elem);
2797 }
2798 else if (xml_elem_cmp(&elem, L"comInterfaceExternalProxyStub", asmv1W))
2799 {
2801 }
2802 else if (xml_elem_cmp(&elem, L"dependency", asmv1W))
2803 {
2804 parse_dependency_elem(xmlbuf, acl, &elem);
2805 }
2806 else if (xml_elem_cmp(&elem, L"file", asmv1W))
2807 {
2808 parse_file_elem(xmlbuf, assembly, acl, &elem);
2809 }
2810 else if (xml_elem_cmp(&elem, L"clrClass", asmv1W))
2811 {
2812 parse_clr_class_elem(xmlbuf, assembly, acl, &elem);
2813 }
2814 else if (xml_elem_cmp(&elem, L"clrSurrogate", asmv1W))
2815 {
2816 parse_clr_surrogate_elem(xmlbuf, assembly, acl, &elem);
2817 }
2818 else if (xml_elem_cmp(&elem, L"trustInfo", asmv1W))
2819 {
2820 parse_trust_info_elem(xmlbuf, assembly, acl, &elem);
2821 }
2822 else if (xml_elem_cmp(&elem, L"assemblyIdentity", asmv1W))
2823 {
2825
2826 if (!xmlbuf->error && expected_ai)
2827 {
2828 /* FIXME: more tests */
2830 memcmp(&assembly->id.version, &expected_ai->version, sizeof(assembly->id.version)))
2831 {
2832 FIXME("wrong version for assembly manifest: %u.%u.%u.%u / %u.%u.%u.%u\n",
2833 expected_ai->version.major, expected_ai->version.minor,
2834 expected_ai->version.build, expected_ai->version.revision,
2835 assembly->id.version.major, assembly->id.version.minor,
2836 assembly->id.version.build, assembly->id.version.revision);
2837 set_error( xmlbuf );
2838 }
2839 else if (assembly->type == ASSEMBLY_SHARED_MANIFEST &&
2840 (assembly->id.version.major != expected_ai->version.major ||
2841 assembly->id.version.minor != expected_ai->version.minor ||
2842 assembly->id.version.build < expected_ai->version.build ||
2843 (assembly->id.version.build == expected_ai->version.build &&
2844 assembly->id.version.revision < expected_ai->version.revision)))
2845 {
2846 FIXME("wrong version for shared assembly manifest\n");
2847 set_error( xmlbuf );
2848 }
2849 }
2850 }
2851 else if (xml_elem_cmp(&elem, L"compatibility", compatibilityNSW))
2852 {
2853 parse_compatibility_elem(xmlbuf, assembly, acl, &elem);
2854 }
2855 else if (xml_elem_cmp(&elem, L"application", asmv1W))
2856 {
2857 parse_application_elem(xmlbuf, assembly, acl, &elem);
2858 }
2859 else
2860 {
2861 WARN("unknown element %s\n", debugstr_xml_elem(&elem));
2862 parse_unknown_elem(xmlbuf, &elem);
2863 }
2864 }
2865
2868 {
2869 set_error( xmlbuf );
2870 }
2871}
2872
2874 struct assembly_identity* ai, xmlbuf_t *xmlbuf )
2875{
2876 struct xml_elem elem;
2877 struct xml_elem parent = {0};
2878
2879 xmlbuf->error = FALSE;
2880 xmlbuf->ns_pos = 0;
2881
2882 if (!next_xml_elem(xmlbuf, &elem, &parent)) return STATUS_SXS_CANT_GEN_ACTCTX;
2883
2884 if (xmlstr_cmp(&elem.name, L"?xml") &&
2885 (!parse_xml_header(xmlbuf) || !next_xml_elem(xmlbuf, &elem, &parent)))
2887
2888 if (!xml_elem_cmp(&elem, L"assembly", asmv1W))
2889 {
2890 FIXME("root element is %s, not <assembly>\n", debugstr_xml_elem(&elem));
2892 }
2893
2894 parse_assembly_elem(xmlbuf, assembly, acl, &elem, ai);
2895 if (xmlbuf->error)
2896 {
2897 FIXME("failed to parse manifest %s\n", debugstr_w(assembly->manifest.info) );
2899 }
2900
2901 if (next_xml_elem(xmlbuf, &elem, &parent))
2902 {
2903 FIXME("unexpected element %s\n", debugstr_xml_elem(&elem));
2905 }
2906
2907 if (xmlbuf->ptr != xmlbuf->end)
2908 {
2909 FIXME("parse error\n");
2911 }
2912 return STATUS_SUCCESS;
2913}
2914
2917 const void *buffer, SIZE_T size )
2918{
2919 xmlbuf_t xmlbuf;
2921 struct assembly *assembly;
2922 int unicode_tests;
2923
2924 TRACE( "parsing manifest loaded from %s base dir %s\n", debugstr_w(filename), debugstr_w(directory) );
2925
2928
2930 return STATUS_NO_MEMORY;
2931
2932 if (!filename)
2933 {
2934 UNICODE_STRING module_path;
2935 if ((status = get_module_filename( module, &module_path, 0 ))) return status;
2936 assembly->manifest.info = module_path.Buffer;
2937 }
2938 else if(!(assembly->manifest.info = strdupW( filename + 4 /* skip \??\ prefix */ ))) return STATUS_NO_MEMORY;
2939
2940 assembly->manifest.type = assembly->manifest.info ? ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE
2941 : ACTIVATION_CONTEXT_PATH_TYPE_NONE;
2942
2944 if (RtlIsTextUnicode( buffer, size, &unicode_tests ))
2945 {
2946 xmlbuf.ptr = buffer;
2947 xmlbuf.end = xmlbuf.ptr + size / sizeof(WCHAR);
2948 status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf );
2949 }
2950 else if (unicode_tests & IS_TEXT_UNICODE_REVERSE_SIGNATURE)
2951 {
2952 const WCHAR *buf = buffer;
2953 WCHAR *new_buff;
2954 unsigned int i;
2955
2956 if (!(new_buff = RtlAllocateHeap( GetProcessHeap(), 0, size )))
2957 return STATUS_NO_MEMORY;
2958 for (i = 0; i < size / sizeof(WCHAR); i++)
2959 new_buff[i] = RtlUshortByteSwap( buf[i] );
2960 xmlbuf.ptr = new_buff;
2961 xmlbuf.end = xmlbuf.ptr + size / sizeof(WCHAR);
2962 status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf );
2963 RtlFreeHeap( GetProcessHeap(), 0, new_buff );
2964 }
2965 else
2966 {
2967 DWORD len;
2968 WCHAR *new_buff;
2969
2970 /* let's assume utf-8 for now */
2972 if (!NT_SUCCESS(status))
2973 {
2974 DPRINT1("RtlMultiByteToUnicodeSize failed with %lx\n", status);
2976 }
2977
2978 if (!(new_buff = RtlAllocateHeap( GetProcessHeap(), 0, len ))) return STATUS_NO_MEMORY;
2979 status = RtlUTF8ToUnicodeN( new_buff, len, &len, buffer, size );
2980 if (!NT_SUCCESS(status))
2981 {
2982 DPRINT1("RtlMultiByteToUnicodeN failed with %lx\n", status);
2984 }
2985
2986 xmlbuf.ptr = new_buff;
2987 xmlbuf.end = xmlbuf.ptr + len / sizeof(WCHAR);
2988 status = parse_manifest_buffer( acl, assembly, ai, &xmlbuf );
2989 RtlFreeHeap( GetProcessHeap(), 0, new_buff );
2990 }
2991 return status;
2992}
2993
2995{
2998
2999 attr.Length = sizeof(attr);
3000 attr.RootDirectory = 0;
3001 attr.Attributes = OBJ_CASE_INSENSITIVE;
3002 attr.ObjectName = name;
3003 attr.SecurityDescriptor = NULL;
3004 attr.SecurityQualityOfService = NULL;
3007}
3008
3010{
3011 static LDR_RESOURCE_INFO manifest_res_info = { RT_MANIFEST };
3012 const IMAGE_RESOURCE_DIRECTORY_ENTRY *entry_base, *entry;
3015
3016 status = LdrFindResourceDirectory_U( hModule, &manifest_res_info, 1, &resdir );
3017 if (status != STATUS_SUCCESS) return status;
3018
3020 entry_base = (const IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resdir + 1);
3021 entry = entry_base + resdir->NumberOfNamedEntries;
3022 *resname = (const WCHAR *)(ULONG_PTR)entry->Id;
3023
3024 return STATUS_SUCCESS;
3025}
3026
3029 HANDLE hModule, LPCWSTR resname, ULONG lang )
3030{
3035 void *ptr;
3036
3037 //DPRINT( "looking for res %s in module %p %s\n", resname,
3038 // hModule, filename );
3039 DPRINT("get_manifest_in_module %p\n", hModule);
3040
3041#if 0
3042 if (TRACE_ON(actctx))
3043 {
3044 if (!filename && !get_module_filename( hModule, &nameW, 0 ))
3045 {
3046 TRACE( "looking for res %s in module %p %s\n", debugstr_w(resname),
3047 hModule, debugstr_w(nameW.Buffer) );
3049 }
3050 else TRACE( "looking for res %s in module %p %s\n", debugstr_w(resname),
3052 }
3053#endif
3054
3055 if (!resname)
3056 {
3058 if (status != STATUS_SUCCESS) return status;
3059 }
3060
3061 info.Type = RT_MANIFEST;
3062 info.Language = lang;
3063 if (!((ULONG_PTR)resname >> 16))
3064 {
3065 info.Name = (ULONG_PTR)resname;
3067 }
3068 else if (resname[0] == '#')
3069 {
3070 ULONG value;
3071 RtlInitUnicodeString(&nameW, resname + 1);
3074 info.Name = value;
3076 }
3077 else
3078 {
3079 RtlCreateUnicodeString(&nameW, resname);
3081 info.Name = (ULONG_PTR)nameW.Buffer;
3084 }
3086
3087 if (status == STATUS_SUCCESS)
3088 status = parse_manifest(acl, ai, filename, hModule, directory, shared, ptr, entry->Size);
3089
3090 return status;
3091}
3092
3093#ifdef __REACTOS__
3095 LPCWSTR name, void *root,
3096 int want_dir );
3097
3099 void *root, int want_dir );
3100
3101
3102static IMAGE_RESOURCE_DIRECTORY *find_first_id_entry( IMAGE_RESOURCE_DIRECTORY *dir,
3103 void *root, int want_dir )
3104{
3106 int pos;
3107
3108 for (pos = dir->NumberOfNamedEntries; pos < dir->NumberOfNamedEntries + dir->NumberOfIdEntries; pos++)
3109 {
3110 if (!entry[pos].DataIsDirectory == !want_dir)
3111 return (IMAGE_RESOURCE_DIRECTORY *)((char *)root + entry[pos].OffsetToDirectory);
3112 }
3113 return NULL;
3114}
3115
3116
3117static NTSTATUS search_manifest_in_module( struct actctx_loader* acl, struct assembly_identity* ai,
3120{
3121 ULONG size;
3122 PVOID root, ptr;
3123 IMAGE_RESOURCE_DIRECTORY *resdirptr;
3126
3129 if (size < sizeof(*resdirptr)) return STATUS_RESOURCE_DATA_NOT_FOUND;
3130 resdirptr = root;
3131
3132 if (!(ptr = find_entry_by_name(resdirptr, (LPCWSTR)RT_MANIFEST, root, 1)))
3134
3135 resdirptr = ptr;
3136 if (!(ptr = find_first_id_entry(resdirptr, root, 1)))
3138
3139 resdirptr = ptr;
3140 if (!(ptr = find_first_entry(resdirptr, root, 0)))
3142
3143 entry = ptr;
3145
3146 if (status == STATUS_SUCCESS)
3147 status = parse_manifest(acl, ai, filename, hModule, directory, shared, ptr, entry->Size);
3148
3149 return status;
3150}
3151#endif // __REACTOS__
3152
3155 HANDLE file, LPCWSTR resname, ULONG lang )
3156{
3162 SIZE_T count;
3163 void *base;
3164 WCHAR resnameBuf[20];
3165 LPCWSTR resptr = resname;
3166
3167 if ((!((ULONG_PTR)resname >> 16)))
3168 {
3169 _swprintf(resnameBuf, L"#%u", PtrToUlong(resname));
3170 resptr = resnameBuf;
3171 }
3172
3173 DPRINT( "looking for res %S in %S\n", resptr, filename ? filename : L"<NULL>");
3174
3175 attr.Length = sizeof(attr);
3176 attr.RootDirectory = 0;
3177 attr.ObjectName = NULL;
3178 attr.Attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF;
3179 attr.SecurityDescriptor = NULL;
3180 attr.SecurityQualityOfService = NULL;
3181
3182 size.QuadPart = 0;
3185 if (status != STATUS_SUCCESS) return status;
3186
3187 offset.QuadPart = 0;
3188 count = 0;
3189 base = NULL;
3192 NtClose( mapping );
3193 if (status != STATUS_SUCCESS) return status;
3194
3195 if (RtlImageNtHeader(base)) /* we got a PE file */
3196 {
3197 HANDLE module = (HMODULE)((ULONG_PTR)base | 1); /* make it a LOAD_LIBRARY_AS_DATAFILE handle */
3198 if (resname)
3199 status = get_manifest_in_module( acl, ai, filename, directory, shared, module, resname, lang );
3200 else
3201 status = search_manifest_in_module(acl, ai, filename, directory, shared, module, lang);
3202 }
3204
3206 return status;
3207}
3208
3211{
3219 SIZE_T count;
3220 void *base;
3221
3222 TRACE( "loading manifest file %s\n", debugstr_w(filename) );
3223
3224 attr.Length = sizeof(attr);
3225 attr.RootDirectory = 0;
3226 attr.ObjectName = NULL;
3227 attr.Attributes = OBJ_CASE_INSENSITIVE | OBJ_OPENIF;
3228 attr.SecurityDescriptor = NULL;
3229 attr.SecurityQualityOfService = NULL;
3230
3231 size.QuadPart = 0;
3234 if (status != STATUS_SUCCESS) return status;
3235
3236 offset.QuadPart = 0;
3237 count = 0;
3238 base = NULL;
3241 NtClose( mapping );
3242 if (status != STATUS_SUCCESS) return status;
3243
3245 if (status == STATUS_SUCCESS)
3246 status = parse_manifest(acl, ai, filename, NULL, directory, shared, base, info.EndOfFile.QuadPart);
3247
3249 return status;
3250}
3251
3252/* try to load the .manifest file associated to the file */
3255{
3256 WCHAR *buffer;
3259 HANDLE file;
3261
3262 if (!((ULONG_PTR)resname >> 16)) resid = LOWORD(resname);
3263
3264 TRACE( "looking for manifest associated with %s id %u\n", debugstr_w(filename), resid );
3265
3266 if (module) /* use the module filename */
3267 {
3269
3270 if (!(status = get_module_filename( module, &name, sizeof(L".manifest") + 10*sizeof(WCHAR) )))
3271 {
3272 if (resid != 1) swprintf( name.Buffer + wcslen(name.Buffer), 10, L".%u", resid );
3273 wcscat( name.Buffer, L".manifest" );
3274 if (!RtlDosPathNameToNtPathName_U( name.Buffer, &nameW, NULL, NULL ))
3277 }
3278 if (status) return status;
3279 }
3280 else
3281 {
3283 (wcslen(filename) + 10) * sizeof(WCHAR) + sizeof(L".manifest") )))
3284 return STATUS_NO_MEMORY;
3286 if (resid != 1) swprintf( buffer + wcslen(buffer), 10, L".%u", resid );
3287 wcscat( buffer, L".manifest" );
3289 }
3290
3291 if (!open_nt_file( &file, &nameW ))
3292 {
3294 NtClose( file );
3295 }
3298 return status;
3299}
3300
3302{
3303 static const WCHAR lookup_fmtW[] = L"%s_%s_%s_%u.%u.*.*_%s_*.manifest";
3304 static const WCHAR wine_trailerW[] = {'d','e','a','d','b','e','e','f','.','m','a','n','i','f','e','s','t'};
3305
3306 WCHAR *lookup, *ret = NULL;
3307 UNICODE_STRING lookup_us;
3309 const WCHAR *lang = ai->language;
3310 unsigned int data_pos = 0, data_len, len;
3311 char buffer[8192];
3312
3313 if (!lang || !wcsicmp( lang, L"neutral" )) lang = L"*";
3314
3315 len = wcslen(ai->arch) + wcslen(ai->name) + wcslen(ai->public_key) + wcslen(lang) + 20 + ARRAY_SIZE(lookup_fmtW);
3316 if (!(lookup = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
3317 swprintf( lookup, len, lookup_fmtW, ai->arch, ai->name, ai->public_key,
3318 ai->version.major, ai->version.minor, lang );
3319 RtlInitUnicodeString( &lookup_us, lookup );
3320
3321#ifdef __arm64ec__
3322 if (!wcsncmp( lookup, L"amd64_", 6 )) memcpy( lookup, L"a??", 3 * sizeof(WCHAR) );
3323#endif
3324
3325 if (!NtQueryDirectoryFile( dir, 0, NULL, NULL, &io, buffer, sizeof(buffer),
3326 FileBothDirectoryInformation, FALSE, &lookup_us, TRUE ))
3327 {
3328 ULONG min_build = ai->version.build, min_revision = ai->version.revision;
3329 FILE_BOTH_DIR_INFORMATION *dir_info;
3330 WCHAR *tmp;
3332
3333 data_len = io.Information;
3334
3335 for (;;)
3336 {
3337 if (data_pos >= data_len)
3338 {
3339 if (NtQueryDirectoryFile( dir, 0, NULL, NULL, &io, buffer, sizeof(buffer),
3341 break;
3342 data_len = io.Information;
3343 data_pos = 0;
3344 }
3345 dir_info = (FILE_BOTH_DIR_INFORMATION*)(buffer + data_pos);
3346
3347 if (dir_info->NextEntryOffset) data_pos += dir_info->NextEntryOffset;
3348 else data_pos = data_len;
3349
3350 tmp = (WCHAR *)dir_info->FileName + (wcschr(lookup, '*') - lookup);
3351 build = wcstoul( tmp, NULL, 10 );
3352 if (build < min_build) continue;
3353 tmp = wcschr(tmp, '.') + 1;
3354 revision = wcstoul( tmp, NULL, 10 );
3355 if (build == min_build && revision < min_revision) continue;
3356 tmp = wcschr(tmp, '_') + 1;
3357 tmp = wcschr(tmp, '_') + 1;
3358 if (dir_info->FileNameLength - (tmp - dir_info->FileName) * sizeof(WCHAR) == sizeof(wine_trailerW) &&
3359 !wcsnicmp( tmp, wine_trailerW, ARRAY_SIZE( wine_trailerW )))
3360 {
3361 /* prefer a non-Wine manifest if we already have one */
3362 /* we'll still load the builtin dll if specified through DllOverrides */
3363 if (ret) continue;
3364 }
3365 else
3366 {
3367 min_build = build;
3368 min_revision = revision;
3369 }
3370 ai->version.build = build;
3371 ai->version.revision = revision;
3373 if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, dir_info->FileNameLength + sizeof(WCHAR) )))
3374 {
3375 memcpy( ret, dir_info->FileName, dir_info->FileNameLength );
3376 ret[dir_info->FileNameLength/sizeof(WCHAR)] = 0;
3377 }
3378 }
3379 }
3380 else WARN("no matching file for %s\n", debugstr_w(lookup));
3382 return ret;
3383}
3384
3386{
3387 struct assembly_identity sxs_ai;
3388 UNICODE_STRING path_us;
3391 WCHAR *path, *file = NULL;
3392 HANDLE handle;
3393
3394 if (!ai->arch || !ai->name || !ai->public_key) return STATUS_NO_SUCH_FILE;
3395
3396 if (!(path = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(L"\\winsxs\\manifests") +
3397 wcslen(windows_dir) * sizeof(WCHAR) )))
3398 return STATUS_NO_MEMORY;
3399
3401 wcscat( path, L"\\winsxs\\manifests" );
3402
3403 if (!RtlDosPathNameToNtPathName_U( path, &path_us, NULL, NULL ))
3404 {
3406 return STATUS_NO_SUCH_FILE;
3407 }
3409
3410 attr.Length = sizeof(attr);
3411 attr.RootDirectory = 0;
3412 attr.Attributes = OBJ_CASE_INSENSITIVE;
3413 attr.ObjectName = &path_us;
3414 attr.SecurityDescriptor = NULL;
3415 attr.SecurityQualityOfService = NULL;
3416
3419 {
3420 sxs_ai = *ai;
3421 file = lookup_manifest_file( handle, &sxs_ai );
3422 NtClose( handle );
3423 }
3424 if (!file)
3425 {
3426 RtlFreeUnicodeString( &path_us );
3427 return STATUS_NO_SUCH_FILE;
3428 }
3429
3430 /* append file name to directory path */
3431 if (!(path = RtlReAllocateHeap( GetProcessHeap(), 0, path_us.Buffer,
3432 path_us.Length + (wcslen(file) + 2) * sizeof(WCHAR) )))
3433 {
3435 RtlFreeUnicodeString( &path_us );
3436 return STATUS_NO_MEMORY;
3437 }
3438
3439 path[path_us.Length/sizeof(WCHAR)] = '\\';
3440 wcscpy( path + path_us.Length/sizeof(WCHAR) + 1, file );
3441 RtlInitUnicodeString( &path_us, path );
3442 *wcsrchr(file, '.') = 0; /* remove .manifest extension */
3443
3444 if (!open_nt_file( &handle, &path_us ))
3445 {
3446 io.Status = get_manifest_in_manifest_file(acl, &sxs_ai, path_us.Buffer, file, TRUE, handle);
3447 NtClose( handle );
3448 }
3449 else io.Status = STATUS_NO_SUCH_FILE;
3450
3452 RtlFreeUnicodeString( &path_us );
3453 return io.Status;
3454}
3455
3457 struct assembly_identity* ai)
3458{
3459 unsigned int i;
3460 WCHAR *buffer, *p, *directory;
3463 HANDLE file;
3464 DWORD len;
3465
3466 TRACE( "looking for name=%s version=%s arch=%s\n",
3468
3469 if ((status = lookup_winsxs(acl, ai)) != STATUS_NO_SUCH_FILE) return status;
3470
3471 /* FIXME: add support for language specific lookup */
3472
3473 len = max(RtlGetFullPathName_U(acl->actctx->assemblies->manifest.info, 0, NULL, NULL) / sizeof(WCHAR),
3474 wcslen(acl->actctx->appdir.info));
3475
3476 nameW.Buffer = NULL;
3478 (len + 2 * wcslen(ai->name) + 2) * sizeof(WCHAR) + sizeof(L".manifest") )))
3479 return STATUS_NO_MEMORY;
3480
3481 if (!(directory = build_assembly_dir( ai )))
3482 {
3484 return STATUS_NO_MEMORY;
3485 }
3486
3487 /* Lookup in <dir>\name.dll
3488 * <dir>\name.manifest
3489 * <dir>\name\name.dll
3490 * <dir>\name\name.manifest
3491 *
3492 * First 'appdir' is used as <dir>, if that failed
3493 * it tries application manifest file path.
3494 */
3495 wcscpy( buffer, acl->actctx->appdir.info );
3496 p = buffer + wcslen(buffer);
3497 for (i = 0; i < 4; i++)
3498 {
3499 if (i == 2)
3500 {
3501 struct assembly *assembly = acl->actctx->assemblies;
3502 if (!RtlGetFullPathName_U(assembly->manifest.info, len * sizeof(WCHAR), buffer, &p)) break;
3503 }
3504 else *p++ = '\\';
3505
3506 wcscpy( p, ai->name );
3507 p += wcslen(p);
3508
3509 wcscpy( p, L".dll" );
3511 {
3512 status = open_nt_file( &file, &nameW );
3513 if (!status)
3514 {
3515 status = get_manifest_in_pe_file( acl, ai, nameW.Buffer, directory, FALSE, file, NULL, 0 );
3516 NtClose( file );
3517 if (status == STATUS_SUCCESS)
3518 break;
3519 }
3521 }
3522
3523 wcscpy( p, L".manifest" );
3525 {
3526 status = open_nt_file( &file, &nameW );
3527 if (!status)
3528 {
3530 NtClose( file );
3531 break;
3532 }
3534 }
3536 }
3540 return status;
3541}
3542
3544{
3546 unsigned int i;
3547
3548 for (i = 0; i < acl->num_dependencies; i++)
3549 {
3550 if (lookup_assembly(acl, &acl->dependencies[i]) != STATUS_SUCCESS)
3551 {
3552 if (!acl->dependencies[i].optional && !acl->dependencies[i].delayed)
3553 {
3554 FIXME( "Could not find dependent assembly %s (%s)\n",
3555 debugstr_w(acl->dependencies[i].name),
3556 debugstr_version(&acl->dependencies[i].version) );
3558 break;
3559 }
3560 }
3561 }
3562 /* FIXME should now iterate through all refs */
3563 return status;
3564}
3565
3567{
3568 ACTIVATION_CONTEXT_STACK *actctx_stack = NtCurrentTeb()->ActivationContextStackPointer;
3569
3570 if (actctx_stack->ActiveFrame)
3571 return actctx_stack->ActiveFrame->ActivationContext;
3572
3573 return NULL;
3574}
3575
3576/* find the appropriate activation context for RtlQueryInformationActivationContext */
3578{
3580
3582 {
3583 if (*handle) return STATUS_INVALID_PARAMETER;
3584
3586 }
3588 {
3589 ULONG_PTR magic;
3591
3592 if (!*handle) return STATUS_INVALID_PARAMETER;
3593
3594 LdrLockLoaderLock( 0, NULL, &magic );
3595 if (!LdrFindEntryForAddress( *handle, &pldr ))
3596 {
3599 else
3601 }
3603 LdrUnlockLoaderLock( 0, magic );
3604 }
3605 else if (!*handle && (class != ActivationContextBasicInformation))
3607
3608 return status;
3609}
3610
3612{
3613 unsigned int i, j, total_len = 0, dll_count = 0;
3614 struct strsection_header *header;
3615 ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *data;
3616 ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT *path;
3617 struct string_index *index;
3619
3620 DPRINT("actctx %p, num_assemblies %d\n", actctx, actctx->num_assemblies);
3621
3622 /* compute section length */
3623 for (i = 0; i < actctx->num_assemblies; i++)
3624 {
3625 struct assembly *assembly = &actctx->assemblies[i];
3626 for (j = 0; j < assembly->num_dlls; j++)
3627 {
3628 struct dll_redirect *dll = &assembly->dlls[j];
3629
3630 /* each entry needs index, data and string data */
3631 total_len += sizeof(*index);
3632 total_len += aligned_string_len((wcslen(dll->name)+1)*sizeof(WCHAR));
3633 total_len += sizeof(*data);
3634 if (dll->load_from)
3635 {
3636 total_len += sizeof(*path);
3637 total_len += aligned_string_len( wcslen(dll->load_from) * sizeof(WCHAR) );
3638 }
3639
3640 DPRINT("assembly %d (%p), dll %d: dll name %S\n", i, assembly, j, dll->name);
3641 }
3642
3644 }
3645
3646 total_len += sizeof(*header);
3647
3648 header = RtlAllocateHeap(GetProcessHeap(), 0, total_len);
3649 if (!header) return STATUS_NO_MEMORY;
3650
3651 memset(header, 0, sizeof(*header));
3652 header->magic = STRSECTION_MAGIC;
3653 header->size = sizeof(*header);
3654 header->count = dll_count;
3655 header->index_offset = sizeof(*header);
3656 index = (struct string_index*)((BYTE*)header + header->index_offset);
3657 name_offset = header->index_offset + header->count*sizeof(*index);
3658
3659 for (i = 0; i < actctx->num_assemblies; i++)
3660 {
3661 struct assembly *assembly = &actctx->assemblies[i];
3662
3663 DPRINT("assembly->num_dlls %d\n", assembly->num_dlls);
3664
3665 for (j = 0; j < assembly->num_dlls; j++)
3666 {
3667 struct dll_redirect *dll = &assembly->dlls[j];
3669 WCHAR *ptrW;
3670
3671 DPRINT("%d: dll name %S\n", j, dll->name);
3672 /* setup new index entry */
3673 str.Buffer = dll->name;
3674 str.Length = wcslen(dll->name)*sizeof(WCHAR);
3675 str.MaximumLength = str.Length + sizeof(WCHAR);
3676 /* hash original class name */
3678
3679 index->name_offset = name_offset;
3680 index->name_len = str.Length;
3681 index->data_offset = index->name_offset + aligned_string_len(str.MaximumLength);
3682 index->data_len = sizeof(*data);
3683 index->rosterindex = i + 1;
3684
3685 /* dll name */
3686 ptrW = (WCHAR*)((BYTE*)header + index->name_offset);
3687 memcpy(ptrW, dll->name, index->name_len);
3688 ptrW[index->name_len/sizeof(WCHAR)] = 0;
3689 name_offset += aligned_string_len(str.MaximumLength);
3690
3691 /* setup data */
3692 data = (ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *)((BYTE *)header + index->data_offset);
3693 if (dll->load_from)
3694 {
3695 ULONG len = wcslen(dll->load_from) * sizeof(WCHAR);
3696 data->Size = sizeof(*data) + sizeof(*path);
3697 data->Flags = 0;
3698 data->TotalPathLength = aligned_string_len( len );
3699 data->PathSegmentCount = 1;
3700 data->PathSegmentOffset = index->data_offset + sizeof(*data);
3701 path = (ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT *)(data + 1);
3702 path->Offset = index->data_offset + data->Size;
3703 path->Length = len;
3704 ptrW = (WCHAR *)((BYTE *)header + path->Offset);
3705 memcpy( ptrW, dll->load_from, len );
3706 if (wcschr( dll->load_from, '%' ))
3708 }
3709 else
3710 {
3711 data->Size = sizeof(*data);
3713 data->TotalPathLength = 0;
3714 data->PathSegmentCount = 0;
3715 data->PathSegmentOffset = 0;
3716 }
3717 name_offset += data->Size + data->TotalPathLength;
3718
3719 index++;
3720 }
3721 }
3722
3723 *section = header;
3724
3725 return STATUS_SUCCESS;
3726}
3727
3729{
3730 struct string_index *iter, *index = NULL;
3732 ULONG hash = 0, i;
3733
3734 DPRINT("section %p, name %wZ\n", section, name);
3736 iter = (struct string_index*)((BYTE*)section + section->index_offset);
3737
3738 for (i = 0; i < section->count; i++)
3739 {
3740 DPRINT("iter->hash 0x%x ?= 0x%x\n", iter->hash, hash);
3741 DPRINT("iter->name %S\n", (WCHAR*)((BYTE*)section + iter->name_offset));
3742 if (iter->hash == hash)
3743 {
3744 str.Buffer = (WCHAR *)((BYTE *)section + iter->name_offset);
3745 str.Length = iter->name_len;
3747 {
3748 index = iter;
3749 break;
3750 }
3751 else
3752 WARN("hash collision 0x%08lx, %s, %s\n", hash, debugstr_us(name), debugstr_us(&str));
3753 }
3754 iter++;
3755 }
3756
3757 return index;
3758}
3759
3760static struct guid_index *find_guid_index(const struct guidsection_header *section, const GUID *guid)
3761{
3762 struct guid_index *iter, *index = NULL;
3763 ULONG i;
3764
3765 iter = (struct guid_index*)((BYTE*)section + section->index_offset);
3766
3767 for (i = 0; i < section->count; i++)
3768 {
3769 if (!memcmp(guid, &iter->guid, sizeof(*guid)))
3770 {
3771 index = iter;
3772 break;
3773 }
3774 iter++;
3775 }
3776
3777 return index;
3778}
3779
3780static inline ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *get_dllredirect_data(ACTIVATION_CONTEXT *ctxt, struct string_index *index)
3781{
3782 return (ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *)((BYTE *)ctxt->dllredirect_section + index->data_offset);
3783}
3784
3787{
3788 ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION *dll;
3789 struct string_index *index;
3790
3791 DPRINT("sections: 0x%08X\n", actctx->sections);
3792 if (!(actctx->sections & DLLREDIRECT_SECTION)) return STATUS_SXS_KEY_NOT_FOUND;
3793
3794 DPRINT("actctx->dllredirect_section: %p\n", actctx->dllredirect_section);
3795 if (!actctx->dllredirect_section)
3796 {
3797 struct strsection_header *section;
3798
3800 if (status) return status;
3801
3802 if (InterlockedCompareExchangePointer((void**)&actctx->dllredirect_section, section, NULL))
3804 }
3805
3806 index = find_string_index(actctx->dllredirect_section, name);
3807 DPRINT("index: %d\n", index);
3808 if (!index) return STATUS_SXS_KEY_NOT_FOUND;
3809
3810 if (data)
3811 {
3813
3814 data->ulDataFormatVersion = 1;
3815 data->lpData = dll;
3816 data->ulLength = dll->Size;
3817 data->lpSectionGlobalData = NULL;
3818 data->ulSectionGlobalDataLength = 0;
3819 data->lpSectionBase = actctx->dllredirect_section;
3820 data->ulSectionTotalLength = RtlSizeHeap( GetProcessHeap(), 0, actctx->dllredirect_section );
3821 data->hActCtx = NULL;
3822
3823 if (data->cbSize >= FIELD_OFFSET(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) + sizeof(ULONG))
3824 data->ulAssemblyRosterIndex = index->rosterindex;
3825 }
3826
3827 return STATUS_SUCCESS;
3828}
3829
3831{
3832 return (struct string_index*)((BYTE*)actctx->wndclass_section + actctx->wndclass_section->index_offset);
3833}
3834
3836{
3837 return (struct wndclass_redirect_data*)((BYTE*)ctxt->wndclass_section + index->data_offset);
3838}
3839
3841{
3842 unsigned int i, j, k, total_len = 0, class_count = 0;
3844 struct strsection_header *header;
3845 struct string_index *index;
3847
3848 /* compute section length */
3849 for (i = 0; i < actctx->num_assemblies; i++)
3850 {
3851 struct assembly *assembly = &actctx->assemblies[i];
3852 for (j = 0; j < assembly->num_dlls; j++)
3853 {
3854 struct dll_redirect *dll = &assembly->dlls[j];
3855 for (k = 0; k < dll->entities.num; k++)
3856 {
3857 struct entity *entity = &dll->entities.base[k];
3858 if (entity->kind == ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION)
3859 {
3860 int class_len = wcslen(entity->u.class.name) + 1;
3861 int len;
3862
3863 /* each class entry needs index, data and string data */
3864 total_len += sizeof(*index);
3865 total_len += sizeof(*data);
3866 /* original name is stored separately */
3867 total_len += aligned_string_len(class_len*sizeof(WCHAR));
3868 /* versioned name and module name are stored one after another */
3869 if (entity->u.class.versioned)
3870 len = get_assembly_version(assembly, NULL) + class_len + 1 /* '!' separator */;
3871 else
3872 len = class_len;
3873 len += wcslen(dll->name) + 1;
3874 total_len += aligned_string_len(len*sizeof(WCHAR));
3875
3876 class_count++;
3877 }
3878 }
3879 }
3880 }
3881
3882 total_len += sizeof(*header);
3883
3884 header = RtlAllocateHeap(GetProcessHeap(), 0, total_len);
3885 if (!header) return STATUS_NO_MEMORY;
3886
3887 memset(header, 0, sizeof(*header));
3888 header->magic = STRSECTION_MAGIC;
3889 header->size = sizeof(*header);
3890 header->count = class_count;
3891 header->index_offset = sizeof(*header);
3892 index = (struct string_index*)((BYTE*)header + header->index_offset);
3893 name_offset = header->index_offset + header->count*sizeof(*index);
3894
3895 for (i = 0; i < actctx->num_assemblies; i++)
3896 {
3897 struct assembly *assembly = &actctx->assemblies[i];
3898 for (j = 0; j < assembly->num_dlls; j++)
3899 {
3900 struct dll_redirect *dll = &assembly->dlls[j];
3901 for (k = 0; k < dll->entities.num; k++)
3902 {
3903 struct entity *entity = &dll->entities.base[k];
3904 if (entity->kind == ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION)
3905 {
3906 ULONG versioned_len, module_len;
3908 WCHAR *ptrW;
3909
3910 /* setup new index entry */
3911 str.Buffer = entity->u.class.name;
3912 str.Length = wcslen(entity->u.class.name)*sizeof(WCHAR);
3913 str.MaximumLength = str.Length + sizeof(WCHAR);
3914 /* hash original class name */
3916
3917 /* include '!' separator too */
3918 if (entity->u.class.versioned)
3919 versioned_len = (get_assembly_version(assembly, NULL) + 1)*sizeof(WCHAR) + str.Length;
3920 else
3921 versioned_len = str.Length;
3922 module_len = wcslen(dll->name)*sizeof(WCHAR);
3923
3924 index->name_offset = name_offset;
3925 index->name_len = str.Length;
3926 index->data_offset = index->name_offset + aligned_string_len(str.MaximumLength);
3927 index->data_len = sizeof(*data) + versioned_len + module_len + 2*sizeof(WCHAR) /* two nulls */;
3928 index->rosterindex = i + 1;
3929
3930 /* setup data */
3931 data = (struct wndclass_redirect_data*)((BYTE*)header + index->data_offset);
3932 data->size = sizeof(*data);
3933 data->res = 0;
3934 data->name_len = versioned_len;
3935 data->name_offset = sizeof(*data);
3936 data->module_len = module_len;
3937 data->module_offset = index->data_offset + data->name_offset + data->name_len + sizeof(WCHAR);
3938
3939 /* original class name */
3940 ptrW = (WCHAR*)((BYTE*)header + index->name_offset);
3941 memcpy(ptrW, entity->u.class.name, index->name_len);
3942 ptrW[index->name_len/sizeof(WCHAR)] = 0;
3943
3944 /* module name */
3945 ptrW = (WCHAR*)((BYTE*)header + data->module_offset);
3946 memcpy(ptrW, dll->name, data->module_len);
3947 ptrW[data->module_len/sizeof(WCHAR)] = 0;
3948
3949 /* versioned name */
3950 ptrW = (WCHAR*)((BYTE*)data + data->name_offset);
3951 if (entity->u.class.versioned)
3952 {
3954 wcscat(ptrW, L"!");
3955 wcscat(ptrW, entity->u.class.name);
3956 }
3957 else
3958 {
3959 memcpy(ptrW, entity->u.class.name, index->name_len);
3960 ptrW[index->name_len/sizeof(WCHAR)] = 0;
3961 }
3962
3963 name_offset += sizeof(*data);
3964 name_offset += aligned_string_len(str.MaximumLength) + aligned_string_len(versioned_len + module_len + 2*sizeof(WCHAR));
3965
3966 index++;
3967 }
3968 }
3969 }
3970 }
3971
3972 *section = header;
3973
3974 return STATUS_SUCCESS;
3975}
3976
3979{
3980 struct string_index *iter, *index = NULL;
3981 struct wndclass_redirect_data *class;
3983 ULONG hash;
3984 int i;
3985
3986 if (!(actctx->sections & WINDOWCLASS_SECTION)) return STATUS_SXS_KEY_NOT_FOUND;
3987
3988 if (!actctx->wndclass_section)
3989 {
3990 struct strsection_header *section;
3991
3993 if (status) return status;
3994
3995 if (InterlockedCompareExchangePointer((void**)&actctx->wndclass_section, section, NULL))
3997 }
3998
3999 hash = 0;
4002
4003 for (i = 0; i < actctx->wndclass_section->count; i++)
4004 {
4005 if (iter->hash == hash)
4006 {
4007 str.Buffer = (WCHAR *)((BYTE *)actctx->wndclass_section + iter->name_offset);
4008 str.Length = iter->name_len;
4010 {
4011 index = iter;
4012 break;
4013 }
4014 else
4015 WARN("hash collision 0x%08lx, %s, %s\n", hash, debugstr_us(name), debugstr_us(&str));
4016 }
4017 iter++;
4018 }
4019
4020 if (!index) return STATUS_SXS_KEY_NOT_FOUND;
4021
4022 if (data)
4023 {
4024 class = get_wndclass_data(actctx, index);
4025
4026 data->ulDataFormatVersion = 1;
4027 data->lpData = class;
4028 /* full length includes string length with nulls */
4029 data->ulLength = class->size + class->name_len + class->module_len + 2*sizeof(WCHAR);
4030 data->lpSectionGlobalData = NULL;
4031 data->ulSectionGlobalDataLength = 0;
4032 data->lpSectionBase = actctx->wndclass_section;
4033 data->ulSectionTotalLength = RtlSizeHeap( GetProcessHeap(), 0, actctx->wndclass_section );
4034 data->hActCtx = NULL;
4035
4036 if (data->cbSize >= FIELD_OFFSET(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) + sizeof(ULONG))
4037 data->ulAssemblyRosterIndex = index->rosterindex;
4038 }
4039
4040 return STATUS_SUCCESS;
4041}
4042
4044{
4045 return (struct string_index *)((BYTE *)actctx->activatable_class_section + actctx->activatable_class_section->index_offset);
4046}
4047
4049{
4050 return (struct activatable_class_data *)((BYTE *)ctxt->activatable_class_section + index->data_offset);
4051}
4052
4054{
4055 unsigned int i, j, k, total_len = 0, class_count = 0, global_offset = 0, global_len = 0;
4057 struct strsection_header *header;
4058 struct string_index *index;
4060
4061 /* compute section length */
4062 for (i = 0; i < actctx->num_assemblies; i++)
4063 {
4064 struct assembly *assembly = &actctx->assemblies[i];
4065 for (j = 0; j < assembly->num_dlls; j++)
4066 {
4067 struct dll_redirect *dll = &assembly->dlls[j];
4068 BOOL has_class = FALSE;
4069
4070 for (k = 0; k < dll->entities.num; k++)
4071 {
4072 struct entity *entity = &dll->entities.base[k];
4073 if (entity->kind == ACTIVATION_CONTEXT_SECTION_WINRT_ACTIVATABLE_CLASSES)
4074 {
4075 int class_len = wcslen(entity->u.activatable_class.name) + 1;
4076
4077 /* each class entry needs index, data and string data */
4078 total_len += sizeof(*index);
4079 total_len += aligned_string_len(class_len * sizeof(WCHAR));
4080 total_len += sizeof(*data);
4081
4082 class_count++;
4083 has_class = TRUE;
4084 }
4085 }
4086
4087 if (has_class)
4088 {
4089 int module_len = wcslen(dll->name) + 1;
4090 global_len += aligned_string_len(module_len * sizeof(WCHAR));
4091 }
4092 }
4093 }
4094
4095 total_len += sizeof(*header) + global_len;
4096
4097 header = RtlAllocateHeap(GetProcessHeap(), 0, total_len);
4098 if (!header) return STATUS_NO_MEMORY;
4099
4100 memset(header, 0, sizeof(*header));
4101 header->magic = STRSECTION_MAGIC;
4102 header->size = sizeof(*header);
4103 header->count = class_count;
4104 header->global_offset = header->size;
4105 header->global_len = global_len;
4106 header->index_offset = header->global_offset + header->global_len;
4107 index = (struct string_index *)((BYTE *)header + header->index_offset);
4108 name_offset = header->index_offset + header->count * sizeof(*index);
4109
4110 global_offset = header->size;
4111 for (i = 0; i < actctx->num_assemblies; i++)
4112 {
4113 struct assembly *assembly = &actctx->assemblies[i];
4114 for (j = 0; j < assembly->num_dlls; j++)
4115 {
4116 struct dll_redirect *dll = &assembly->dlls[j];
4117 int module_len = wcslen(dll->name) * sizeof(WCHAR);
4118 BOOL has_class = FALSE;
4119
4120 for (k = 0; k < dll->entities.num; k++)
4121 {
4122 struct entity *entity = &dll->entities.base[k];
4123
4124 if (entity->kind == ACTIVATION_CONTEXT_SECTION_WINRT_ACTIVATABLE_CLASSES)
4125 {
4127 WCHAR *ptrW;
4128
4129 /* setup new index entry */
4130 str.Buffer = entity->u.activatable_class.name;
4131 str.Length = wcslen(entity->u.activatable_class.name) * sizeof(WCHAR);
4132 str.MaximumLength = str.Length + sizeof(WCHAR);
4133 /* hash class name */
4135
4136 index->name_offset = name_offset;
4137 index->name_len = str.Length;
4138 index->data_offset = index->name_offset + aligned_string_len(str.MaximumLength);
4139 index->data_len = sizeof(*data);
4140 index->rosterindex = i + 1;
4141
4142 /* class name */
4143 ptrW = (WCHAR *)((BYTE *)header + index->name_offset);
4144 memcpy(ptrW, entity->u.activatable_class.name, index->name_len);
4145 ptrW[index->name_len / sizeof(WCHAR)] = 0;
4146
4147 /* class data */
4148 data = (struct activatable_class_data *)((BYTE *)header + index->data_offset);
4149 data->size = sizeof(*data);
4150 data->threading_model = entity->u.activatable_class.threading_model;
4151 data->module_len = module_len;
4152 data->module_offset = global_offset;
4153
4154 name_offset += aligned_string_len(str.MaximumLength);
4155 name_offset += sizeof(*data);
4156
4157 index++;
4158 has_class = TRUE;
4159 }
4160 }
4161
4162 if (has_class)
4163 {
4164 WCHAR *ptrW = (WCHAR *)((BYTE *)header + global_offset);
4165 memcpy(ptrW, dll->name, module_len);
4166 ptrW[module_len / sizeof(WCHAR)] = 0;
4167 global_offset += aligned_string_len(module_len + sizeof(WCHAR));
4168 }
4169 }
4170 }
4171
4172 *section = header;
4173
4174 return STATUS_SUCCESS;
4175}
4176
4179{
4180 struct string_index *iter, *index = NULL;
4181 struct activatable_class_data *class;
4183 ULONG hash;
4184 int i;
4185
4187
4188 if (!actctx->activatable_class_section)
4189 {
4190 struct strsection_header *section;
4191
4193 if (status) return status;
4194
4195 if (InterlockedCompareExchangePointer((void**)&actctx->activatable_class_section, section, NULL))
4197 }
4198
4199 hash = 0;
4202
4203 for (i = 0; i < actctx->activatable_class_section->count; i++)
4204 {
4205 if (iter->hash == hash)
4206 {
4207 str.Buffer = (WCHAR *)((BYTE *)actctx->activatable_class_section + iter->name_offset);
4208 str.Length = iter->name_len;
4210 {
4211 index = iter;
4212 break;
4213 }
4214 else
4215 WARN("hash collision 0x%08lx, %s, %s\n", hash, debugstr_us(name), debugstr_us(&str));
4216 }
4217 iter++;
4218 }
4219
4220 if (!index) return STATUS_SXS_KEY_NOT_FOUND;
4221
4222 if (data)
4223 {
4225
4226 data->ulDataFormatVersion = 1;
4227 data->lpData = class;
4228 /* full length includes string length with nulls */
4229 data->ulLength = class->size + class->module_len + sizeof(WCHAR);
4230 data->lpSectionGlobalData = (BYTE *)actctx->activatable_class_section + actctx->activatable_class_section->global_offset;
4231 data->ulSectionGlobalDataLength = actctx->activatable_class_section->global_len;
4232 data->lpSectionBase = actctx->activatable_class_section;
4233 data->ulSectionTotalLength = RtlSizeHeap( GetProcessHeap(), 0, actctx->activatable_class_section );
4234 data->hActCtx = NULL;
4235
4236 if (data->cbSize >= FIELD_OFFSET(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) + sizeof(ULONG))
4237 data->ulAssemblyRosterIndex = index->rosterindex;
4238 }
4239
4240 return STATUS_SUCCESS;
4241}
4242
4244{
4245 unsigned int i, j, k, total_len = 0, tlib_count = 0, names_len = 0;
4246 struct guidsection_header *header;
4247 ULONG module_offset, data_offset;
4248 struct tlibredirect_data *data;
4249 struct guid_index *index;
4250
4251 /* compute section length */
4252 for (i = 0; i < actctx->num_assemblies; i++)
4253 {
4254 struct assembly *assembly = &actctx->assemblies[i];
4255 for (j = 0; j < assembly->num_dlls; j++)
4256 {
4257 struct dll_redirect *dll = &assembly->dlls[j];
4258 for (k = 0; k < dll->entities.num; k++)
4259 {
4260 struct entity *entity = &dll->entities.base[k];
4261 if (entity->kind == ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION)
4262 {
4263 /* each entry needs index, data and string data for module name and help string */
4264 total_len += sizeof(*index);
4265 total_len += sizeof(*data);
4266 /* help string is stored separately */
4267 if (*entity->u.typelib.helpdir)
4268 total_len += aligned_string_len((wcslen(entity->u.typelib.helpdir)+1)*sizeof(WCHAR));
4269
4270 /* module names are packed one after another */
4271 names_len += (wcslen(dll->name)+1)*sizeof(WCHAR);
4272
4273 tlib_count++;
4274 }
4275 }
4276 }
4277 }
4278
4279 total_len += aligned_string_len(names_len);
4280 total_len += sizeof(*header);
4281
4282 header = RtlAllocateHeap(GetProcessHeap(), 0, total_len);
4283 if (!header) return STATUS_NO_MEMORY;
4284
4285 memset(header, 0, sizeof(*header));
4286 header->magic = GUIDSECTION_MAGIC;
4287 header->size = sizeof(*header);
4288 header->count = tlib_count;
4289 header->index_offset = sizeof(*header) + aligned_string_len(names_len);
4290 index = (struct guid_index*)((BYTE*)header + header->index_offset);
4291 module_offset = sizeof(*header);
4292 data_offset = header->index_offset + tlib_count*sizeof(*index);
4293
4294 for (i = 0; i < actctx->num_assemblies; i++)
4295 {
4296 struct assembly *assembly = &actctx->assemblies[i];
4297 for (j = 0; j < assembly->num_dlls; j++)
4298 {
4299 struct dll_redirect *dll = &assembly->dlls[j];
4300 for (k = 0; k < dll->entities.num; k++)
4301 {
4302 struct entity *entity = &dll->entities.base[k];
4303 if (entity->kind == ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION)
4304 {
4305 ULONG module_len, help_len;
4307 WCHAR *ptrW;
4309
4310 if (*entity->u.typelib.helpdir)
4311 help_len = wcslen(entity->u.typelib.helpdir)*sizeof(WCHAR);
4312 else
4313 help_len = 0;
4314
4315 module_len = wcslen(dll->name)*sizeof(WCHAR);
4316
4317 /* setup new index entry */
4319 Status = RtlGUIDFromString(&str, &index->guid);
4320 if (!NT_SUCCESS(Status))
4321 {
4323 return Status;
4324 }
4325 index->data_offset = data_offset;
4326 index->data_len = sizeof(*data) + aligned_string_len(help_len);
4327 index->rosterindex = i + 1;
4328
4329 /* setup data */
4330 data = (struct tlibredirect_data*)((BYTE*)header + index->data_offset);
4331 data->size = sizeof(*data);
4332 data->res = 0;
4333 data->name_len = module_len;
4334 data->name_offset = module_offset;
4335 /* FIXME: resourceid handling is really weird, and it doesn't seem to be useful */
4336 data->langid = 0;
4337 data->flags = entity->u.typelib.flags;
4338 data->help_len = help_len;
4339 data->help_offset = sizeof(*data);
4340 data->major_version = entity->u.typelib.major;
4341 data->minor_version = entity->u.typelib.minor;
4342
4343 /* module name */
4344 ptrW = (WCHAR*)((BYTE*)header + data->name_offset);
4345 memcpy(ptrW, dll->name, data->name_len);
4346 ptrW[data->name_len/sizeof(WCHAR)] = 0;
4347
4348 /* help string */
4349 if (data->help_len)
4350 {
4351 ptrW = (WCHAR*)((BYTE*)data + data->help_offset);
4352 memcpy(ptrW, entity->u.typelib.helpdir, data->help_len);
4353 ptrW[data->help_len/sizeof(WCHAR)] = 0;
4354 }
4355
4356 data_offset += sizeof(*data);
4357 if (help_len)
4358 data_offset += aligned_string_len(help_len + sizeof(WCHAR));
4359
4360 module_offset += module_len + sizeof(WCHAR);
4361
4362 index++;
4363 }
4364 }
4365 }
4366 }
4367
4368 *section = header;
4369
4370 return STATUS_SUCCESS;
4371}
4372
4374{
4375 return (struct tlibredirect_data*)((BYTE*)actctx->tlib_section + index->data_offset);
4376}
4377
4378static NTSTATUS find_tlib_redirection(ACTIVATION_CONTEXT* actctx, const GUID *guid, ACTCTX_SECTION_KEYED_DATA* data)
4379{
4380 struct guid_index *index = NULL;
4381 struct tlibredirect_data *tlib;
4382
4383 if (!(actctx->sections & TLIBREDIRECT_SECTION)) return STATUS_SXS_KEY_NOT_FOUND;
4384
4385 if (!actctx->tlib_section)
4386 {
4388
4390 if (status) return status;
4391
4392 if (InterlockedCompareExchangePointer((void**)&actctx->tlib_section, section, NULL))
4394 }
4395
4396 index = find_guid_index(actctx->tlib_section, guid);
4397 if (!index) return STATUS_SXS_KEY_NOT_FOUND;
4398
4399 tlib = get_tlib_data(actctx, index);
4400
4401 data->ulDataFormatVersion = 1;
4402 data->lpData = tlib;
4403 /* full length includes string length with nulls */
4404 data->ulLength = tlib->size + tlib->help_len + sizeof(WCHAR);
4405 data->lpSectionGlobalData = (BYTE*)actctx->tlib_section + actctx->tlib_section->names_offset;
4406 data->ulSectionGlobalDataLength = actctx->tlib_section->names_len;
4407 data->lpSectionBase = actctx->tlib_section;
4408 data->ulSectionTotalLength = RtlSizeHeap( GetProcessHeap(), 0, actctx->tlib_section );
4409 data->hActCtx = NULL;
4410
4411 if (data->cbSize >= FIELD_OFFSET(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) + sizeof(ULONG))
4412 data->ulAssemblyRosterIndex = index->rosterindex;
4413
4414 return STATUS_SUCCESS;
4415}
4416
4417static void generate_uuid(ULONG *seed, GUID *guid)
4418{
4419 ULONG *ptr = (ULONG*)guid;
4420 int i;
4421
4422 /* GUID is 16 bytes long */
4423 for (i = 0; i < sizeof(GUID)/sizeof(ULONG); i++, ptr++)
4424 *ptr = RtlUniform(seed);
4425
4426 guid->Data3 &= 0x0fff;
4427 guid->Data3 |= (4 << 12);
4428 guid->Data4[0] &= 0x3f;
4429 guid->Data4[0] |= 0x80;
4430}
4431
4432static void get_comserver_datalen(const struct entity_array *entities, const struct dll_redirect *dll,
4433 unsigned int *count, unsigned int *len, unsigned int *module_len)
4434{
4435 unsigned int i;
4436
4437 for (i = 0; i < entities->num; i++)
4438 {
4439 struct entity *entity = &entities->base[i];
4440 if (entity->kind == ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)
4441 {
4442 /* each entry needs two index entries, extra one goes for alias GUID */
4443 *len += 2*sizeof(struct guid_index);
4444 /* To save some memory we don't allocated two data structures,
4445 instead alias index and normal index point to the same data structure. */
4446 *len += sizeof(struct comclassredirect_data);
4447
4448 /* for clrClass store some more */
4449 if (entity->u.comclass.name)
4450 {
4451 unsigned int str_len;
4452
4453 /* all string data is stored together in aligned block */
4454 str_len = wcslen(entity->u.comclass.name)+1;
4455 if (entity->u.comclass.progid)
4456 str_len += wcslen(entity->u.comclass.progid)+1;
4457 if (entity->u.comclass.version)
4458 str_len += wcslen(entity->u.comclass.version)+1;
4459
4460 *len += sizeof(struct clrclass_data);
4461 *len += aligned_string_len(str_len*sizeof(WCHAR));
4462
4463 /* module name is forced to mscoree.dll, and stored two times with different case */
4464 *module_len += sizeof(L"MSCOREE.DLL") + sizeof(L"mscoree.dll");
4465 }
4466 else
4467 {
4468 /* progid string is stored separately */
4469 if (entity->u.comclass.progid)
4470 *len += aligned_string_len((wcslen(entity->u.comclass.progid)+1)*sizeof(WCHAR));
4471
4472 *module_len += (wcslen(dll->name)+1)*sizeof(WCHAR);
4473 }
4474
4475 *count += 1;
4476 }
4477 }
4478}
4479
4480static NTSTATUS add_comserver_record(const struct guidsection_header *section, const struct entity_array *entities,
4481 const struct dll_redirect *dll, struct guid_index **index, ULONG *data_offset, ULONG *module_offset,
4482 ULONG *seed, ULONG rosterindex)
4483{
4484 unsigned int i;
4486
4487 for (i = 0; i < entities->num; i++)
4488 {
4489 struct entity *entity = &entities->base[i];
4490 if (entity->kind == ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)
4491 {
4492 ULONG module_len, progid_len, str_len = 0, miscmask;
4494 struct guid_index *alias_index;
4495 struct clrclass_data *clrdata;
4497 WCHAR *ptrW;
4498
4499 if (entity->u.comclass.progid)
4500 progid_len = wcslen(entity->u.comclass.progid)*sizeof(WCHAR);
4501 else
4502 progid_len = 0;
4503
4504 module_len = dll ? wcslen(dll->name)*sizeof(WCHAR) : wcslen(L"MSCOREE.DLL")*sizeof(WCHAR);
4505
4506 /* setup new index entry */
4508 Status = RtlGUIDFromString(&str, &(*index)->guid);
4509 if (!NT_SUCCESS(Status))
4510 return Status;
4511
4512 (*index)->data_offset = *data_offset;
4513 (*index)->data_len = sizeof(*data); /* additional length added later */
4514 (*index)->rosterindex = rosterindex;
4515
4516 /* Setup new index entry for alias guid. Alias index records are placed after
4517 normal records, so normal guids are hit first on search. Note that class count
4518 is doubled. */
4519 alias_index = (*index) + section->count/2;
4520 generate_uuid(seed, &alias_index->guid);
4521 alias_index->data_offset = (*index)->data_offset;
4522 alias_index->data_len = 0;
4523 alias_index->rosterindex = (*index)->rosterindex;
4524
4525 /* setup data */
4526 data = (struct comclassredirect_data*)((BYTE*)section + (*index)->data_offset);
4527 data->size = sizeof(*data);
4528 data->model = entity->u.comclass.model;
4529 data->clsid = (*index)->guid;
4530 data->alias = alias_index->guid;
4531 data->clsid2 = data->clsid;
4532 if (entity->u.comclass.tlbid)
4533 {
4535 Status = RtlGUIDFromString(&str, &data->tlbid);
4536 if (!NT_SUCCESS(Status))
4537 return Status;
4538 }
4539 else
4540 memset(&data->tlbid, 0, sizeof(data->tlbid));
4541 data->name_len = module_len;
4542 data->name_offset = *module_offset;
4543 data->progid_len = progid_len;
4544 data->progid_offset = data->progid_len ? data->size : 0; /* in case of clrClass additional offset is added later */
4545 data->clrdata_len = 0; /* will be set later */
4546 data->clrdata_offset = entity->u.comclass.name ? sizeof(*data) : 0;
4547 data->miscstatus = entity->u.comclass.miscstatus;
4548 data->miscstatuscontent = entity->u.comclass.miscstatuscontent;
4549 data->miscstatusthumbnail = entity->u.comclass.miscstatusthumbnail;
4550 data->miscstatusicon = entity->u.comclass.miscstatusicon;
4551 data->miscstatusdocprint = entity->u.comclass.miscstatusdocprint;
4552
4553 /* mask describes which misc* data is available */
4554 miscmask = 0;
4555 if (data->miscstatus)
4557 if (data->miscstatuscontent)
4559 if (data->miscstatusthumbnail)
4561 if (data->miscstatusicon)
4563 if (data->miscstatusdocprint)
4565 data->flags = miscmask << 8;
4566
4567 if (data->clrdata_offset)
4568 {
4569 clrdata = (struct clrclass_data*)((BYTE*)data + data->clrdata_offset);
4570
4571 clrdata->size = sizeof(*clrdata);
4572 clrdata->res[0] = 0;
4573 clrdata->res[1] = 2; /* FIXME: unknown field */
4574 clrdata->module_len = wcslen(L"MSCOREE.DLL")*sizeof(WCHAR);
4575 clrdata->module_offset = *module_offset + data->name_len + sizeof(WCHAR);
4576 clrdata->name_len = wcslen(entity->u.comclass.name)*sizeof(WCHAR);
4577 clrdata->name_offset = clrdata->size;
4578 clrdata->version_len = entity->u.comclass.version ? wcslen(entity->u.comclass.version)*sizeof(WCHAR) : 0;
4579 clrdata->version_offset = clrdata->version_len ? clrdata->name_offset + clrdata->name_len + sizeof(WCHAR) : 0;
4580 clrdata->res2[0] = 0;
4581 clrdata->res2[1] = 0;
4582
4583 data->clrdata_len = clrdata->size + clrdata->name_len + sizeof(WCHAR);
4584
4585 /* module name */
4586 ptrW = (WCHAR*)((BYTE*)section + clrdata->module_offset);
4587 memcpy(ptrW, L"mscoree.dll", clrdata->module_len);
4588 ptrW[clrdata->module_len/sizeof(WCHAR)] = 0;
4589
4590 ptrW = (WCHAR*)((BYTE*)section + data->name_offset);
4591 memcpy(ptrW, L"MSCOREE.DLL", data->name_len);
4592 ptrW[data->name_len/sizeof(WCHAR)] = 0;
4593
4594 /* class name */
4595 ptrW = (WCHAR*)((BYTE*)clrdata + clrdata->name_offset);
4596 memcpy(ptrW, entity->u.comclass.name, clrdata->name_len);
4597 ptrW[clrdata->name_len/sizeof(WCHAR)] = 0;
4598
4599 /* runtime version, optional */
4600 if (clrdata->version_len)
4601 {
4602 data->clrdata_len += clrdata->version_len + sizeof(WCHAR);
4603
4604 ptrW = (WCHAR*)((BYTE*)clrdata + clrdata->version_offset);
4605 memcpy(ptrW, entity->u.comclass.version, clrdata->version_len);
4606 ptrW[clrdata->version_len/sizeof(WCHAR)] = 0;
4607 }
4608
4609 if (data->progid_len)
4610 data->progid_offset += data->clrdata_len;
4611 (*index)->data_len += sizeof(*clrdata);
4612 }
4613 else
4614 {
4615 clrdata = NULL;
4616
4617 /* module name */
4618 ptrW = (WCHAR*)((BYTE*)section + data->name_offset);
4619 memcpy(ptrW, dll->name, data->name_len);
4620 ptrW[data->name_len/sizeof(WCHAR)] = 0;
4621 }
4622
4623 /* progid string */
4624 if (data->progid_len)
4625 {
4626 ptrW = (WCHAR*)((BYTE*)data + data->progid_offset);
4627 memcpy(ptrW, entity->u.comclass.progid, data->progid_len);
4628 ptrW[data->progid_len/sizeof(WCHAR)] = 0;
4629 }
4630
4631 /* string block length */
4632 str_len = 0;
4633 if (clrdata)
4634 {
4635 str_len += clrdata->name_len + sizeof(WCHAR);
4636 if (clrdata->version_len)
4637 str_len += clrdata->version_len + sizeof(WCHAR);
4638 }
4639 if (progid_len)
4640 str_len += progid_len + sizeof(WCHAR);
4641
4642 (*index)->data_len += aligned_string_len(str_len);
4643 alias_index->data_len = (*index)->data_len;
4644
4645 /* move to next data record */
4646 (*data_offset) += sizeof(*data) + aligned_string_len(str_len);
4647 (*module_offset) += module_len + sizeof(WCHAR);
4648
4649 if (clrdata)
4650 {
4651 (*data_offset) += sizeof(*clrdata);
4652 (*module_offset) += clrdata->module_len + sizeof(WCHAR);
4653 }
4654 (*index) += 1;
4655 }
4656 }
4657
4658 return STATUS_SUCCESS;
4659}
4660
4662{
4663 unsigned int i, j, total_len = 0, class_count = 0, names_len = 0;
4664 struct guidsection_header *header;
4665 ULONG module_offset, data_offset;
4666 struct guid_index *index;
4667 ULONG seed;
4669
4670 /* compute section length */
4671 for (i = 0; i < actctx->num_assemblies; i++)
4672 {
4673 struct assembly *assembly = &actctx->assemblies[i];
4674 get_comserver_datalen(&assembly->entities, NULL, &class_count, &total_len, &names_len);
4675 for (j = 0; j < assembly->num_dlls; j++)
4676 {
4677 struct dll_redirect *dll = &assembly->dlls[j];
4678 get_comserver_datalen(&dll->entities, dll, &class_count, &total_len, &names_len);
4679 }
4680 }
4681
4682 total_len += aligned_string_len(names_len);
4683 total_len += sizeof(*header);
4684
4685 header = RtlAllocateHeap(GetProcessHeap(), 0, total_len);
4686 if (!header) return STATUS_NO_MEMORY;
4687
4688 memset(header, 0, sizeof(*header));
4689 header->magic = GUIDSECTION_MAGIC;
4690 header->size = sizeof(*header);
4691 header->count = 2*class_count;
4692 header->index_offset = sizeof(*header) + aligned_string_len(names_len);
4693 index = (struct guid_index*)((BYTE*)header + header->index_offset);
4694 module_offset = sizeof(*header);
4695 data_offset = header->index_offset + 2*class_count*sizeof(*index);
4696
4697 seed = NtGetTickCount();
4698 for (i = 0; i < actctx->num_assemblies; i++)
4699 {
4700 struct assembly *assembly = &actctx->assemblies[i];
4701 Status = add_comserver_record(header, &assembly->entities, NULL, &index, &data_offset, &module_offset, &seed, i+1);
4702 if (!NT_SUCCESS(Status))
4703 {
4705 return Status;
4706 }
4707 for (j = 0; j < assembly->num_dlls; j++)
4708 {
4709 struct dll_redirect *dll = &assembly->dlls[j];
4710 Status = add_comserver_record(header, &dll->entities, dll, &index, &data_offset, &module_offset, &seed, i+1);
4711 if (!NT_SUCCESS(Status))
4712 {
4714 return Status;
4715 }
4716 }
4717 }
4718
4719 *section = header;
4720
4721 return STATUS_SUCCESS;
4722}
4723
4725{
4726 return (struct comclassredirect_data*)((BYTE*)actctx->comserver_section + index->data_offset);
4727}
4728
4729static NTSTATUS find_comserver_redirection(ACTIVATION_CONTEXT* actctx, const GUID *guid, ACTCTX_SECTION_KEYED_DATA* data)
4730{
4731 struct comclassredirect_data *comclass;
4732 struct guid_index *index = NULL;
4733
4734 if (!(actctx->sections & SERVERREDIRECT_SECTION)) return STATUS_SXS_KEY_NOT_FOUND;
4735
4736 if (!actctx->comserver_section)
4737 {
4739
4741 if (status) return status;
4742
4743 if (InterlockedCompareExchangePointer((void**)&actctx->comserver_section, section, NULL))
4745 }
4746
4747 index = find_guid_index(actctx->comserver_section, guid);
4748 if (!index) return STATUS_SXS_KEY_NOT_FOUND;
4749
4750 comclass = get_comclass_data(actctx, index);
4751
4752 data->ulDataFormatVersion = 1;
4753 data->lpData = comclass;
4754 /* full length includes string length with nulls */
4755 data->ulLength = comclass->size + comclass->clrdata_len;
4756 if (comclass->progid_len) data->ulLength += comclass->progid_len + sizeof(WCHAR);
4757 data->lpSectionGlobalData = (BYTE*)actctx->comserver_section + actctx->comserver_section->names_offset;
4758 data->ulSectionGlobalDataLength = actctx->comserver_section->names_len;
4759 data->lpSectionBase = actctx->comserver_section;
4760 data->ulSectionTotalLength = RtlSizeHeap( GetProcessHeap(), 0, actctx->comserver_section );
4761 data->hActCtx = NULL;
4762
4763 if (data->cbSize >= FIELD_OFFSET(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) + sizeof(ULONG))
4764 data->ulAssemblyRosterIndex = index->rosterindex;
4765
4766 return STATUS_SUCCESS;
4767}
4768
4769static void get_ifaceps_datalen(const struct entity_array *entities, unsigned int *count, unsigned int *len)
4770{
4771 unsigned int i;
4772
4773 for (i = 0; i < entities->num; i++)
4774 {
4775 struct entity *entity = &entities->base[i];
4776 if (entity->kind == ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION)
4777 {
4778 *len += sizeof(struct guid_index) + sizeof(struct ifacepsredirect_data);
4779 if (entity->u.ifaceps.name)
4780 *len += aligned_string_len((wcslen(entity->u.ifaceps.name)+1)*sizeof(WCHAR));
4781 *count += 1;
4782 }
4783 }
4784}
4785
4788{
4789 unsigned int i;
4790
4791 for (i = 0; i < entities->num; i++)
4792 {
4793 struct entity *entity = &entities->base[i];
4794 if (entity->kind == ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION)
4795 {
4796 struct ifacepsredirect_data *data = (struct ifacepsredirect_data*)((BYTE*)section + *data_offset);
4800
4801 if (entity->u.ifaceps.name)
4802 name_len = wcslen(entity->u.ifaceps.name)*sizeof(WCHAR);
4803 else
4804 name_len = 0;
4805
4806 /* setup index */
4808 Status = RtlGUIDFromString(&str, &(*index)->guid);
4809 if (!NT_SUCCESS(Status))
4810 return Status;
4811 (*index)->data_offset = *data_offset;
4812 (*index)->data_len = sizeof(*data) + name_len ? aligned_string_len(name_len + sizeof(WCHAR)) : 0;
4813 (*index)->rosterindex = rosterindex;
4814
4815 /* setup data record */
4816 data->size = sizeof(*data);
4817 data->mask = entity->u.ifaceps.mask;
4818
4819 /* proxyStubClsid32 value is only stored for external PS,
4820 if set it's used as iid, otherwise 'iid' attribute value is used */
4821 if (entity->u.ifaceps.ps32)
4822 {
4824 Status = RtlGUIDFromString(&str, &data->iid);
4825 if (!NT_SUCCESS(Status))
4826 return Status;
4827 }
4828 else
4829 data->iid = (*index)->guid;
4830
4831 data->nummethods = entity->u.ifaceps.nummethods;
4832
4833 if (entity->u.ifaceps.tlib)
4834 {
4836 Status = RtlGUIDFromString(&str, &data->tlbid);
4837 if (!NT_SUCCESS(Status))
4838 return Status;
4839 }
4840 else
4841 memset(&data->tlbid, 0, sizeof(data->tlbid));
4842
4843 if (entity->u.ifaceps.base)
4844 {
4846 Status = RtlGUIDFromString(&str, &data->base);
4847 if (!NT_SUCCESS(Status))
4848 return Status;
4849 }
4850 else
4851 memset(&data->base, 0, sizeof(data->base));
4852
4853 data->name_len = name_len;
4854 data->name_offset = data->name_len ? sizeof(*data) : 0;
4855
4856 /* name string */
4857 if (data->name_len)
4858 {
4859 WCHAR *ptrW = (WCHAR*)((BYTE*)data + data->name_offset);
4860 memcpy(ptrW, entity->u.ifaceps.name, data->name_len);
4861 ptrW[data->name_len/sizeof(WCHAR)] = 0;
4862 }
4863
4864 /* move to next record */
4865 (*index) += 1;
4866 *data_offset += sizeof(*data);
4867 if (data->name_len)
4868 *data_offset += aligned_string_len(data->name_len + sizeof(WCHAR));
4869 }
4870 }
4871
4872 return STATUS_SUCCESS;
4873}
4874
4876{
4877 unsigned int i, j, total_len = 0, count = 0;
4878 struct guidsection_header *header;
4879 struct guid_index *index;
4881
4882 /* compute section length */
4883 for (i = 0; i < actctx->num_assemblies; i++)
4884 {
4885 struct assembly *assembly = &actctx->assemblies[i];
4886
4887 get_ifaceps_datalen(&assembly->entities, &count, &total_len);
4888 for (j = 0; j < assembly->num_dlls; j++)
4889 {
4890 struct dll_redirect *dll = &assembly->dlls[j];
4891 get_ifaceps_datalen(&dll->entities, &count, &total_len);
4892 }
4893 }
4894
4895 total_len += sizeof(*header);
4896
4897 header = RtlAllocateHeap(GetProcessHeap(), 0, total_len);
4898 if (!header) return STATUS_NO_MEMORY;
4899
4900 memset(header, 0, sizeof(*header));
4901 header->magic = GUIDSECTION_MAGIC;
4902 header->size = sizeof(*header);
4903 header->count = count;
4904 header->index_offset = sizeof(*header);
4905 index = (struct guid_index*)((BYTE*)header + header->index_offset);
4906 data_offset = header->index_offset + count*sizeof(*index);
4907
4908 for (i = 0; i < actctx->num_assemblies; i++)
4909 {
4910 struct assembly *assembly = &actctx->assemblies[i];
4912
4913 Status = add_ifaceps_record(header, &assembly->entities, &index, &data_offset, i + 1);
4914 if (!NT_SUCCESS(Status))
4915 {
4917 return Status;
4918 }
4919
4920 for (j = 0; j < assembly->num_dlls; j++)
4921 {
4922 struct dll_redirect *dll = &assembly->dlls[j];
4923 Status = add_ifaceps_record(header, &dll->entities, &index, &data_offset, i + 1);
4924 if (!NT_SUCCESS(Status))
4925 {
4927 return Status;
4928 }
4929 }
4930 }
4931
4932 *section = header;
4933
4934 return STATUS_SUCCESS;
4935}
4936
4938{
4939 return (struct ifacepsredirect_data*)((BYTE*)actctx->ifaceps_section + index->data_offset);
4940}
4941
4943{
4944 struct ifacepsredirect_data *iface;
4945 struct guid_index *index = NULL;
4946
4947 if (!(actctx->sections & IFACEREDIRECT_SECTION)) return STATUS_SXS_KEY_NOT_FOUND;
4948
4949 if (!actctx->ifaceps_section)
4950 {
4952
4954 if (status) return status;
4955
4956 if (InterlockedCompareExchangePointer((void**)&actctx->ifaceps_section, section, NULL))
4958 }
4959
4960 index = find_guid_index(actctx->ifaceps_section, guid);
4961 if (!index) return STATUS_SXS_KEY_NOT_FOUND;
4962
4963 iface = get_ifaceps_data(actctx, index);
4964
4965 data->ulDataFormatVersion = 1;
4966 data->lpData = iface;
4967 data->ulLength = iface->size + (iface->name_len ? iface->name_len + sizeof(WCHAR) : 0);
4968 data->lpSectionGlobalData = NULL;
4969 data->ulSectionGlobalDataLength = 0;
4970 data->lpSectionBase = actctx->ifaceps_section;
4971 data->ulSectionTotalLength = RtlSizeHeap( GetProcessHeap(), 0, actctx->ifaceps_section );
4972 data->hActCtx = NULL;
4973
4974 if (data->cbSize >= FIELD_OFFSET(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) + sizeof(ULONG))
4975 data->ulAssemblyRosterIndex = index->rosterindex;
4976
4977 return STATUS_SUCCESS;
4978}
4979
4981{
4982 unsigned int i, j, total_len = 0, count = 0;
4983 struct guidsection_header *header;
4984 struct clrsurrogate_data *data;
4985 struct guid_index *index;
4987
4988 /* compute section length */
4989 for (i = 0; i < actctx->num_assemblies; i++)
4990 {
4991 struct assembly *assembly = &actctx->assemblies[i];
4992 for (j = 0; j < assembly->entities.num; j++)
4993 {
4994 struct entity *entity = &assembly->entities.base[j];
4995 if (entity->kind == ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES)
4996 {
4997 ULONG len;
4998
4999 total_len += sizeof(*index) + sizeof(*data);
5000 len = wcslen(entity->u.clrsurrogate.name) + 1;
5001 if (entity->u.clrsurrogate.version)
5002 len += wcslen(entity->u.clrsurrogate.version) + 1;
5003 total_len += aligned_string_len(len*sizeof(WCHAR));
5004
5005 count++;
5006 }
5007 }
5008 }
5009
5010 total_len += sizeof(*header);
5011
5012 header = RtlAllocateHeap(GetProcessHeap(), 0, total_len);
5013 if (!header) return STATUS_NO_MEMORY;
5014
5015 memset(header, 0, sizeof(*header));
5016 header->magic = GUIDSECTION_MAGIC;
5017 header->size = sizeof(*header);
5018 header->count = count;
5019 header->index_offset = sizeof(*header);
5020 index = (struct guid_index*)((BYTE*)header + header->index_offset);
5021 data_offset = header->index_offset + count*sizeof(*index);
5022
5023 for (i = 0; i < actctx->num_assemblies; i++)
5024 {
5025 struct assembly *assembly = &actctx->assemblies[i];
5026 for (j = 0; j < assembly->entities.num; j++)
5027 {
5028 struct entity *entity = &assembly->entities.base[j];
5029 if (entity->kind == ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES)
5030 {
5031 ULONG version_len, name_len;
5033 WCHAR *ptrW;
5035
5036 if (entity->u.clrsurrogate.version)
5037 version_len = wcslen(entity->u.clrsurrogate.version)*sizeof(WCHAR);
5038 else
5039 version_len = 0;
5040 name_len = wcslen(entity->u.clrsurrogate.name)*sizeof(WCHAR);
5041
5042 /* setup new index entry */
5044 Status = RtlGUIDFromString(&str, &index->guid);
5045 if (!NT_SUCCESS(Status))
5046 {
5048 return Status;
5049 }
5050
5051 index->data_offset = data_offset;
5052 index->data_len = sizeof(*data) + aligned_string_len(name_len + sizeof(WCHAR) + (version_len ? version_len + sizeof(WCHAR) : 0));
5053 index->rosterindex = i + 1;
5054
5055 /* setup data */
5056 data = (struct clrsurrogate_data*)((BYTE*)header + index->data_offset);
5057 data->size = sizeof(*data);
5058 data->res = 0;
5059 data->clsid = index->guid;
5060 data->version_offset = version_len ? data->size : 0;
5061 data->version_len = version_len;
5062 data->name_offset = data->size + version_len;
5063 if (version_len)
5064 data->name_offset += sizeof(WCHAR);
5065 data->name_len = name_len;
5066
5067 /* surrogate name */
5068 ptrW = (WCHAR*)((BYTE*)data + data->name_offset);
5069 memcpy(ptrW, entity->u.clrsurrogate.name, data->name_len);
5070 ptrW[data->name_len/sizeof(WCHAR)] = 0;
5071
5072 /* runtime version */
5073 if (data->version_len)
5074 {
5075 ptrW = (WCHAR*)((BYTE*)data + data->version_offset);
5076 memcpy(ptrW, entity->u.clrsurrogate.version, data->version_len);
5077 ptrW[data->version_len/sizeof(WCHAR)] = 0;
5078 }
5079
5080 data_offset += index->data_len;
5081 index++;
5082 }
5083 }
5084 }
5085
5086 *section = header;
5087
5088 return STATUS_SUCCESS;
5089}
5090
5092{
5093 return (struct clrsurrogate_data*)((BYTE*)actctx->clrsurrogate_section + index->data_offset);
5094}
5095
5096static NTSTATUS find_clr_surrogate(ACTIVATION_CONTEXT* actctx, const GUID *guid, ACTCTX_SECTION_KEYED_DATA* data)
5097{
5098 struct clrsurrogate_data *surrogate;
5099 struct guid_index *index = NULL;
5100
5101 if (!(actctx->sections & CLRSURROGATES_SECTION)) return STATUS_SXS_KEY_NOT_FOUND;
5102
5103 if (!actctx->clrsurrogate_section)
5104 {
5106
5108 if (status) return status;
5109
5110 if (InterlockedCompareExchangePointer((void**)&actctx->clrsurrogate_section, section, NULL))
5112 }
5113
5114 index = find_guid_index(actctx->clrsurrogate_section, guid);
5115 if (!index) return STATUS_SXS_KEY_NOT_FOUND;
5116
5117 surrogate = get_surrogate_data(actctx, index);
5118
5119 data->ulDataFormatVersion = 1;
5120 data->lpData = surrogate;
5121 /* full length includes string length with nulls */
5122 data->ulLength = surrogate->size + surrogate->name_len + sizeof(WCHAR);
5123 if (surrogate->version_len)
5124 data->ulLength += surrogate->version_len + sizeof(WCHAR);
5125
5126 data->lpSectionGlobalData = NULL;
5127 data->ulSectionGlobalDataLength = 0;
5128 data->lpSectionBase = actctx->clrsurrogate_section;
5129 data->ulSectionTotalLength = RtlSizeHeap( GetProcessHeap(), 0, actctx->clrsurrogate_section );
5130 data->hActCtx = NULL;
5131
5132 if (data->cbSize >= FIELD_OFFSET(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) + sizeof(ULONG))
5133 data->ulAssemblyRosterIndex = index->rosterindex;
5134
5135 return STATUS_SUCCESS;
5136}
5137
5138static void get_progid_datalen(struct entity_array *entities, unsigned int *count, unsigned int *total_len)
5139{
5140 unsigned int i, j, single_len;
5141
5142 single_len = sizeof(struct progidredirect_data) + sizeof(struct string_index) + sizeof(GUID);
5143 for (i = 0; i < entities->num; i++)
5144 {
5145 struct entity *entity = &entities->base[i];
5146 if (entity->kind == ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)
5147 {
5148 if (entity->u.comclass.progid)
5149 {
5150 *total_len += single_len + aligned_string_len((wcslen(entity->u.comclass.progid)+1)*sizeof(WCHAR));
5151 *count += 1;
5152 }
5153
5154 for (j = 0; j < entity->u.comclass.progids.num; j++)
5155 *total_len += aligned_string_len((wcslen(entity->u.comclass.progids.progids[j])+1)*sizeof(WCHAR));
5156
5157 *total_len += single_len*entity->u.comclass.progids.num;
5158 *count += entity->u.comclass.progids.num;
5159 }
5160 }
5161}
5162
5164 struct string_index **index, ULONG *data_offset, ULONG *global_offset, ULONG rosterindex)
5165{
5166 struct progidredirect_data *data;
5168 GUID *guid_ptr;
5169 WCHAR *ptrW;
5170
5171 /* setup new index entry */
5172
5173 /* hash progid name */
5176
5177 (*index)->name_offset = *data_offset;
5178 (*index)->name_len = str.Length;
5179 (*index)->data_offset = (*index)->name_offset + aligned_string_len(str.MaximumLength);
5180 (*index)->data_len = sizeof(*data);
5181 (*index)->rosterindex = rosterindex;
5182
5183 *data_offset += aligned_string_len(str.MaximumLength);
5184
5185 /* setup data structure */
5186 data = (struct progidredirect_data*)((BYTE*)section + *data_offset);
5187 data->size = sizeof(*data);
5188 data->reserved = 0;
5189 data->clsid_offset = *global_offset;
5190
5191 /* write progid string */
5192 ptrW = (WCHAR*)((BYTE*)section + (*index)->name_offset);
5193 memcpy(ptrW, progid, (*index)->name_len);
5194 ptrW[(*index)->name_len/sizeof(WCHAR)] = 0;
5195
5196 /* write guid to global area */
5197 guid_ptr = (GUID*)((BYTE*)section + data->clsid_offset);
5198 *guid_ptr = *alias;
5199
5200 /* to next entry */
5201 *global_offset += sizeof(GUID);
5202 *data_offset += data->size;
5203 (*index) += 1;
5204}
5205
5207 struct string_index **index, ULONG *data_offset, ULONG *global_offset, ULONG rosterindex)
5208{
5209 unsigned int i, j;
5211
5212 for (i = 0; i < entities->num; i++)
5213 {
5214 struct entity *entity = &entities->base[i];
5215 if (entity->kind == ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION)
5216 {
5217 const struct progids *progids = &entity->u.comclass.progids;
5218 struct comclassredirect_data *comclass;
5219 struct guid_index *guid_index;
5221 GUID clsid;
5222
5225 if (!NT_SUCCESS(Status))
5226 return Status;
5227
5228 guid_index = find_guid_index(actctx->comserver_section, &clsid);
5229 comclass = get_comclass_data(actctx, guid_index);
5230
5231 if (entity->u.comclass.progid)
5232 write_progid_record(section, entity->u.comclass.progid, &comclass->alias,
5233 index, data_offset, global_offset, rosterindex);
5234
5235 for (j = 0; j < progids->num; j++)
5237 index, data_offset, global_offset, rosterindex);
5238 }
5239 }
5240 return Status;
5241}
5242
5244{
5245 unsigned int i, j, total_len = 0, count = 0;
5246 struct strsection_header *header;
5247 ULONG data_offset, global_offset;
5248 struct string_index *index;
5250
5251 /* compute section length */
5252 for (i = 0; i < actctx->num_assemblies; i++)
5253 {
5254 struct assembly *assembly = &actctx->assemblies[i];
5255
5256 get_progid_datalen(&assembly->entities, &count, &total_len);
5257 for (j = 0; j < assembly->num_dlls; j++)
5258 {
5259 struct dll_redirect *dll = &assembly->dlls[j];
5260 get_progid_datalen(&dll->entities, &count, &total_len);
5261 }
5262 }
5263
5264 total_len += sizeof(*header);
5265
5266 header = RtlAllocateHeap(GetProcessHeap(), 0, total_len);
5267 if (!header) return STATUS_NO_MEMORY;
5268
5269 memset(header, 0, sizeof(*header));
5270 header->magic = STRSECTION_MAGIC;
5271 header->size = sizeof(*header);
5272 header->count = count;
5273 header->global_offset = header->size;
5274 header->global_len = count*sizeof(GUID);
5275 header->index_offset = header->size + header->global_len;
5276
5277 index = (struct string_index*)((BYTE*)header + header->index_offset);
5278 data_offset = header->index_offset + count*sizeof(*index);
5279 global_offset = header->global_offset;
5280
5281 for (i = 0; i < actctx->num_assemblies; i++)
5282 {
5283 struct assembly *assembly = &actctx->assemblies[i];
5284
5285 Status = add_progid_record(actctx, header, &assembly->entities, &index, &data_offset, &global_offset, i + 1);
5286 if (!NT_SUCCESS(Status))
5287 {
5289 return Status;
5290 }
5291
5292 for (j = 0; j < assembly->num_dlls; j++)
5293 {
5294 struct dll_redirect *dll = &assembly->dlls[j];
5295 Status = add_progid_record(actctx, header, &dll->entities, &index, &data_offset, &global_offset, i + 1);
5296 if (!NT_SUCCESS(Status))
5297 {
5299 return Status;
5300 }
5301 }
5302 }
5303
5304 *section = header;
5305
5306 return STATUS_SUCCESS;
5307}
5308
5310{
5311 return (struct progidredirect_data*)((BYTE*)actctx->progid_section + index->data_offset);
5312}
5313
5316{
5318 struct string_index *index;
5319
5320 if (!(actctx->sections & PROGIDREDIRECT_SECTION)) return STATUS_SXS_KEY_NOT_FOUND;
5321
5322 if (!actctx->comserver_section)
5323 {
5325
5327 if (status) return status;
5328
5329 if (InterlockedCompareExchangePointer((void**)&actctx->comserver_section, section, NULL))
5331 }
5332
5333 if (!actctx->progid_section)
5334 {
5335 struct strsection_header *section;
5336
5338 if (status) return status;
5339
5340 if (InterlockedCompareExchangePointer((void**)&actctx->progid_section, section, NULL))
5342 }
5343
5344 index = find_string_index(actctx->progid_section, name);
5345 if (!index) return STATUS_SXS_KEY_NOT_FOUND;
5346
5347 if (data)
5348 {
5350
5351 data->ulDataFormatVersion = 1;
5352 data->lpData = progid;
5353 data->ulLength = progid->size;
5354 data->lpSectionGlobalData = (BYTE*)actctx->progid_section + actctx->progid_section->global_offset;
5355 data->ulSectionGlobalDataLength = actctx->progid_section->global_len;
5356 data->lpSectionBase = actctx->progid_section;
5357 data->ulSectionTotalLength = RtlSizeHeap( GetProcessHeap(), 0, actctx->progid_section );
5358 data->hActCtx = NULL;
5359
5360 if (data->cbSize >= FIELD_OFFSET(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) + sizeof(ULONG))
5361 data->ulAssemblyRosterIndex = index->rosterindex;
5362 }
5363
5364 return STATUS_SUCCESS;
5365}
5366
5368 const UNICODE_STRING *section_name,
5370{
5372
5373 switch (section_kind)
5374 {
5375#ifdef __REACTOS__
5376 case ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION:
5377 DPRINT1("Unsupported yet section_kind %x\n", section_kind);
5379#endif // __REACTOS__
5380 case ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION:
5381 status = find_dll_redirection(actctx, section_name, data);
5382 break;
5383 case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION:
5384 status = find_window_class(actctx, section_name, data);
5385 break;
5386 case ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION:
5387 status = find_progid_redirection(actctx, section_name, data);
5388 break;
5389 case ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE:
5390 FIXME("Unsupported yet section_kind %lx\n", section_kind);
5392 case ACTIVATION_CONTEXT_SECTION_WINRT_ACTIVATABLE_CLASSES:
5393 status = find_activatable_class(actctx, section_name, data);
5394 break;
5395 default:
5396 WARN("Unknown section_kind %lx\n", section_kind);
5398 }
5399
5400 if (status != STATUS_SUCCESS) return status;
5401
5402 if (data && (flags & FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX))
5403 {
5405 data->hActCtx = actctx;
5406 }
5407 return STATUS_SUCCESS;
5408}
5409
5412{
5414
5415 switch (section_kind)
5416 {
5417 case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION:
5419 break;
5420 case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION:
5422 break;
5423 case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION:
5425 break;
5426 case ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES:
5428 break;
5429 default:
5430 WARN("Unknown section_kind %lx\n", section_kind);
5432 }
5433
5434 if (status != STATUS_SUCCESS) return status;
5435
5436 if (flags & FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX)
5437 {
5439 data->hActCtx = actctx;
5440 }
5441 return STATUS_SUCCESS;
5442}
5443
5445{
5446 unsigned int i, j;
5447
5448 for (i = 0; i < actctx->num_assemblies; i++)
5449 {
5450 struct assembly *assembly = &actctx->assemblies[i];
5451 for (j = 0; j < assembly->entities.num; j++)
5452 {
5453 struct entity *entity = &assembly->entities.base[j];
5454 if (entity->kind == ACTIVATION_CONTEXT_SECTION_APPLICATION_SETTINGS &&
5455 !wcscmp( entity->u.settings.name, settings ) &&
5456 !wcscmp( entity->u.settings.ns, ns ))
5457 return entity->u.settings.value;
5458 }
5459 }
5460 return NULL;
5461}
5462
5463/* initialize the activation context for the current process */
5464void actctx_init(void)
5465{
5466 ACTCTXW ctx;
5467 HANDLE handle;
5468
5469 ctx.cbSize = sizeof(ctx);
5470 ctx.lpSource = NULL;
5471 ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID | ACTCTX_FLAG_HMODULE_VALID;
5472 ctx.hModule = NtCurrentTeb()->ProcessEnvironmentBlock->ImageBaseAddress;
5474
5476 {
5478 }
5479
5480#ifdef __REACTOS__
5481 NtCurrentTeb()->ProcessEnvironmentBlock->ActivationContextData = process_actctx->ActivationContextData;
5482#else
5483 NtCurrentTeb()->Peb->ActivationContextData = process_actctx;
5484#endif // __REACTOS__
5485}
5486
5487
5488/***********************************************************************
5489 * RtlCreateActivationContext (NTDLL.@)
5490 *
5491 * Create an activation context.
5492 */
5494NTAPI
5496 IN PACTIVATION_CONTEXT_DATA ActivationContextData,
5497 IN ULONG ExtraBytes,
5498 IN PVOID NotificationRoutine,
5501{
5502 const ACTCTXW *pActCtx = (PVOID)ActivationContextData;
5503 const WCHAR *directory = NULL;
5506 ULONG lang = 0;
5508 HANDLE file = 0;
5509 struct actctx_loader acl;
5510
5511 TRACE("%p %08lx\n", pActCtx, pActCtx ? pActCtx->dwFlags : 0);
5512
5513#define CHECK_LIMIT( field ) (pActCtx->cbSize >= RTL_SIZEOF_THROUGH_FIELD( ACTCTXW, field ))
5514 if (!pActCtx || (pActCtx->dwFlags & ~ACTCTX_FLAGS_ALL) ||
5515 !CHECK_LIMIT( lpSource ) ||
5516 ((pActCtx->dwFlags & ACTCTX_FLAG_PROCESSOR_ARCHITECTURE_VALID) && !CHECK_LIMIT( wProcessorArchitecture )) ||
5517 ((pActCtx->dwFlags & ACTCTX_FLAG_LANGID_VALID) && !CHECK_LIMIT( wLangId )) ||
5518 ((pActCtx->dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID) && !CHECK_LIMIT( lpAssemblyDirectory )) ||
5519 ((pActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) && !CHECK_LIMIT( lpResourceName )) ||
5520 ((pActCtx->dwFlags & ACTCTX_FLAG_APPLICATION_NAME_VALID) && !CHECK_LIMIT( lpApplicationName )) ||
5521 ((pActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID) && !CHECK_LIMIT( hModule )))
5523#undef CHECK_LIMIT
5524
5525 if ((pActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) && !pActCtx->lpResourceName)
5527
5529 return STATUS_NO_MEMORY;
5530
5531 actctx->magic = ACTCTX_MAGIC;
5532 actctx->ref_count = 1;
5533 actctx->config.type = ACTIVATION_CONTEXT_PATH_TYPE_NONE;
5534 actctx->config.info = NULL;
5535 actctx->appdir.type = ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE;
5536 if (pActCtx->dwFlags & ACTCTX_FLAG_APPLICATION_NAME_VALID)
5537 {
5538 if (!(actctx->appdir.info = strdupW( pActCtx->lpApplicationName ))) goto error;
5539 }
5540 else
5541 {
5543 WCHAR *p;
5545
5546 if (pActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID) module = pActCtx->hModule;
5547 else module = NtCurrentTeb()->ProcessEnvironmentBlock->ImageBaseAddress;
5548
5550 if (!NT_SUCCESS(status)) goto error;
5551 if ((p = wcsrchr( dir.Buffer, '\\' ))) p[1] = 0;
5552 actctx->appdir.info = dir.Buffer;
5553 }
5554
5555 nameW.Buffer = NULL;
5556
5557 /* open file only if it's going to be used */
5558 if (pActCtx->lpSource && !((pActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID) &&
5559 (pActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID)))
5560 {
5561 WCHAR *source = NULL;
5562 BOOLEAN ret;
5563
5564 if (pActCtx->dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID &&
5565 RtlDetermineDosPathNameType_U(pActCtx->lpSource) == RELATIVE_PATH)
5566 {
5567 DWORD dir_len, source_len;
5568
5569 dir_len = wcslen(pActCtx->lpAssemblyDirectory);
5570 source_len = wcslen(pActCtx->lpSource);
5571 if (!(source = RtlAllocateHeap( GetProcessHeap(), 0, (dir_len+source_len+2)*sizeof(WCHAR))))
5572 {
5574 goto error;
5575 }
5576
5577 memcpy(source, pActCtx->lpAssemblyDirectory, dir_len*sizeof(WCHAR));
5578 source[dir_len] = '\\';
5579 memcpy(source+dir_len+1, pActCtx->lpSource, (source_len+1)*sizeof(WCHAR));
5580 }
5581
5582 ret = RtlDosPathNameToNtPathName_U(source ? source : pActCtx->lpSource, &nameW, NULL, NULL);
5584 if (!ret)
5585 {
5587 goto error;
5588 }
5589 status = open_nt_file( &file, &nameW );
5590 if (!NT_SUCCESS(status))
5591 {
5593 goto error;
5594 }
5595 }
5596
5597 acl.actctx = actctx;
5598 acl.dependencies = NULL;
5599 acl.num_dependencies = 0;
5600 acl.allocated_dependencies = 0;
5601
5602 if (pActCtx->dwFlags & ACTCTX_FLAG_LANGID_VALID) lang = pActCtx->wLangId;
5603 if (pActCtx->dwFlags & ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID) directory = pActCtx->lpAssemblyDirectory;
5604
5605 if (pActCtx->dwFlags & ACTCTX_FLAG_RESOURCE_NAME_VALID)
5606 {
5607 /* if we have a resource it's a PE file */
5608 if (pActCtx->dwFlags & ACTCTX_FLAG_HMODULE_VALID)
5609 {
5610 status = get_manifest_in_module( &acl, NULL, NULL, directory, FALSE, pActCtx->hModule,
5611 pActCtx->lpResourceName, lang );
5613 /* FIXME: what to do if pActCtx->lpSource is set */
5615 pActCtx->hModule, pActCtx->lpResourceName );
5616 }
5617 else if (pActCtx->lpSource && pActCtx->lpResourceName)
5618 {
5620 file, pActCtx->lpResourceName, lang );
5623 NULL, pActCtx->lpResourceName );
5624 }
5626 }
5627 else
5628 {
5630 }
5631
5632 if (file) NtClose( file );
5634
5636 free_depend_manifests( &acl );
5637
5638 if (NT_SUCCESS(status))
5639 *ActCtx = actctx;
5640 else actctx_release( actctx );
5641 return status;
5642
5643error:
5644 if (file) NtClose( file );
5646 return status;
5647}
5648
5649
5650/***********************************************************************
5651 * RtlAddRefActivationContext (NTDLL.@)
5652 */
5654{
5656
5658}
5659
5660
5661/******************************************************************
5662 * RtlReleaseActivationContext (NTDLL.@)
5663 */
5665{
5667
5669}
5670
5671/******************************************************************
5672 * RtlZombifyActivationContext (NTDLL.@)
5673 *
5674 * FIXME: function prototype might be wrong
5675 */
5677{
5678 FIXME("%p: stub\n", handle);
5679
5681 return STATUS_SUCCESS;
5682
5684}
5685
5686/******************************************************************
5687 * RtlActivateActivationContext (NTDLL.@)
5688 */
5690{
5692}
5693
5694/******************************************************************
5695 * RtlActivateActivationContextEx (NTDLL.@)
5696 */
5698{
5701
5702 frame = RtlAllocateHeap( GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(*frame) );
5703 frame->Previous = actctx_stack->ActiveFrame;
5704 frame->ActivationContext = handle;
5705 frame->Flags = 0;
5706
5707 DPRINT("ActiveSP %p: ACTIVATE (ActiveFrame %p -> NewFrame %p, Context %p)\n",
5709 frame, handle);
5710
5711 actctx_stack->ActiveFrame = frame;
5713
5714 *cookie = (ULONG_PTR)frame;
5715 TRACE( "%p cookie=%Ix\n", handle, *cookie );
5716 return STATUS_SUCCESS;
5717}
5718
5719/***********************************************************************
5720 * RtlDeactivateActivationContext (NTDLL.@)
5721 */
5723{
5724 ACTIVATION_CONTEXT_STACK *actctx_stack = NtCurrentTeb()->ActivationContextStackPointer;
5726
5727 TRACE( "%lx cookie=%Ix\n", flags, cookie );
5728
5729 /* find the right frame */
5730 top = actctx_stack->ActiveFrame;
5731 for (frame = top; frame; frame = frame->Previous)
5732 if ((ULONG_PTR)frame == cookie) break;
5733
5734 if (!frame)
5736
5739
5740 DPRINT("ActiveSP %p: DEACTIVATE (ActiveFrame %p -> PreviousFrame %p)\n",
5741 NtCurrentTeb()->ActivationContextStackPointer,
5742 NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame,
5743 frame->Previous);
5744
5745 /* pop everything up to and including frame */
5746 actctx_stack->ActiveFrame = frame->Previous;
5747
5748 while (top != actctx_stack->ActiveFrame)
5749 {
5750 frame = top->Previous;
5751 RtlReleaseActivationContext( top->ActivationContext );
5753 top = frame;
5754 }
5755
5756 return STATUS_SUCCESS;
5757}
5758
5759/******************************************************************
5760 * RtlFreeThreadActivationContextStack (NTDLL.@)
5761 */
5763{
5764 RtlFreeActivationContextStack( NtCurrentTeb()->ActivationContextStackPointer );
5765#ifdef __REACTOS__
5766 NtCurrentTeb()->ActivationContextStackPointer = NULL;
5767#endif
5768}
5769
5770
5771/******************************************************************
5772 * RtlFreeActivationContextStack (NTDLL.@)
5773 */
5775{
5777
5778#ifdef __REACTOS__
5779 /* Nothing to do if there is no stack */
5780 if (!actctx_stack) return;
5781#endif // __REACTOS_
5782
5783 frame = actctx_stack->ActiveFrame;
5784 while (frame)
5785 {
5788 RtlFreeHeap( GetProcessHeap(), 0, frame );
5789 frame = prev;
5790 }
5791 actctx_stack->ActiveFrame = NULL;
5792
5793#ifdef __REACTOS__
5794 /* TODO: Empty the Frame List Cache */
5795 ASSERT(IsListEmpty(&actctx_stack->FrameListCache));
5796
5797 /* Free activation stack memory */
5798 RtlFreeHeap(GetProcessHeap(), 0, actctx_stack);
5799#endif // __REACTOS__
5800}
5801
5802
5803/******************************************************************
5804 * RtlGetActiveActivationContext (NTDLL.@)
5805 */
5807{
5809 return STATUS_SUCCESS;
5810}
5811
5812
5813/******************************************************************
5814 * RtlIsActivationContextActive (NTDLL.@)
5815 */
5817{
5818 ACTIVATION_CONTEXT_STACK *actctx_stack = NtCurrentTeb()->ActivationContextStackPointer;
5820
5821 for (frame = actctx_stack->ActiveFrame; frame; frame = frame->Previous)
5822 if (frame->ActivationContext == handle) return TRUE;
5823 return FALSE;
5824}
5825
5826
5827/***********************************************************************
5828 * RtlQueryInformationActivationContext (NTDLL.@)
5829 *
5830 * Get information about an activation context.
5831 * FIXME: function signature/prototype may be wrong
5832 */
5834 ULONG class, PVOID buffer,
5835 SIZE_T bufsize, SIZE_T *retlen )
5836{
5839
5840 TRACE("%08lx %p %p %lu %p %Id %p\n", flags, handle,
5841 subinst, class, buffer, bufsize, retlen);
5842
5843 if (retlen) *retlen = 0;
5844 if ((status = find_query_actctx( &handle, flags, class ))) return status;
5845
5846 switch (class)
5847 {
5848 case ActivationContextBasicInformation:
5849 {
5850 ACTIVATION_CONTEXT_BASIC_INFORMATION *info = buffer;
5851
5852 if (retlen) *retlen = sizeof(*info);
5853 if (!info || bufsize < sizeof(*info)) return STATUS_BUFFER_TOO_SMALL;
5854
5855 info->hActCtx = handle;
5856 info->dwFlags = 0; /* FIXME */
5858 }
5859 break;
5860
5861 case ActivationContextDetailedInformation:
5862 {
5863 ACTIVATION_CONTEXT_DETAILED_INFORMATION *acdi = buffer;
5864 struct assembly *assembly = NULL;
5865 SIZE_T len, manifest_len = 0, config_len = 0, appdir_len = 0;
5866 LPWSTR ptr;
5867
5869
5870 if (actctx->num_assemblies) assembly = actctx->assemblies;
5871
5872 if (assembly && assembly->manifest.info)
5873 manifest_len = wcslen(assembly->manifest.info) + 1;
5874 if (actctx->config.info) config_len = wcslen(actctx->config.info) + 1;
5875 if (actctx->appdir.info) appdir_len = wcslen(actctx->appdir.info) + 1;
5876 len = sizeof(*acdi) + (manifest_len + config_len + appdir_len) * sizeof(WCHAR);
5877
5878 if (retlen) *retlen = len;
5879 if (!buffer || bufsize < len) return STATUS_BUFFER_TOO_SMALL;
5880
5881 acdi->dwFlags = 0;
5882 acdi->ulFormatVersion = assembly ? 1 : 0; /* FIXME */
5883 acdi->ulAssemblyCount = actctx->num_assemblies;
5884 acdi->ulRootManifestPathType = assembly ? assembly->manifest.type : 0 /* FIXME */;
5885 acdi->ulRootManifestPathChars = assembly && assembly->manifest.info ? manifest_len - 1 : 0;
5886 acdi->ulRootConfigurationPathType = actctx->config.type;
5887 acdi->ulRootConfigurationPathChars = actctx->config.info ? config_len - 1 : 0;
5888 acdi->ulAppDirPathType = actctx->appdir.type;
5889 acdi->ulAppDirPathChars = actctx->appdir.info ? appdir_len - 1 : 0;
5890 ptr = (LPWSTR)(acdi + 1);
5891 if (manifest_len)
5892 {
5893 acdi->lpRootManifestPath = ptr;
5894 memcpy(ptr, assembly->manifest.info, manifest_len * sizeof(WCHAR));
5895 ptr += manifest_len;
5896 }
5897 else acdi->lpRootManifestPath = NULL;
5898 if (config_len)
5899 {
5900 acdi->lpRootConfigurationPath = ptr;
5901 memcpy(ptr, actctx->config.info, config_len * sizeof(WCHAR));
5902 ptr += config_len;
5903 }
5904 else acdi->lpRootConfigurationPath = NULL;
5905 if (appdir_len)
5906 {
5907 acdi->lpAppDirPath = ptr;
5908 memcpy(ptr, actctx->appdir.info, appdir_len * sizeof(WCHAR));
5909 }
5910 else acdi->lpAppDirPath = NULL;
5911 }
5912 break;
5913
5914 case AssemblyDetailedInformationInActivationContext:
5915 {
5916 ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *afdi = buffer;
5917 struct assembly *assembly;
5918 WCHAR *assembly_id;
5919 DWORD index;
5920 SIZE_T len, id_len = 0, ad_len = 0, path_len = 0;
5921 LPWSTR ptr;
5922
5924 if (!subinst) return STATUS_INVALID_PARAMETER;
5925
5926 index = *(DWORD*)subinst;
5927 if (!index || index > actctx->num_assemblies) return STATUS_INVALID_PARAMETER;
5928
5929 assembly = &actctx->assemblies[index - 1];
5930
5931 if (!(assembly_id = build_assembly_id( &assembly->id ))) return STATUS_NO_MEMORY;
5932 id_len = wcslen(assembly_id) + 1;
5933 if (assembly->directory) ad_len = wcslen(assembly->directory) + 1;
5934
5935 if (assembly->manifest.info &&
5937 path_len = wcslen(assembly->manifest.info) + 1;
5938
5939 len = sizeof(*afdi) + (id_len + ad_len + path_len) * sizeof(WCHAR);
5940
5941 if (retlen) *retlen = len;
5942 if (!buffer || bufsize < len)
5943 {
5944 RtlFreeHeap( GetProcessHeap(), 0, assembly_id );
5946 }
5947
5948 afdi->ulFlags = 0; /* FIXME */
5949 afdi->ulEncodedAssemblyIdentityLength = (id_len - 1) * sizeof(WCHAR);
5950 afdi->ulManifestPathType = assembly->manifest.type;
5951 afdi->ulManifestPathLength = assembly->manifest.info ? (path_len - 1) * sizeof(WCHAR) : 0;
5952 /* FIXME afdi->liManifestLastWriteTime = 0; */
5953 afdi->ulPolicyPathType = ACTIVATION_CONTEXT_PATH_TYPE_NONE; /* FIXME */
5954 afdi->ulPolicyPathLength = 0;
5955 /* FIXME afdi->liPolicyLastWriteTime = 0; */
5956 afdi->ulMetadataSatelliteRosterIndex = 0; /* FIXME */
5957 afdi->ulManifestVersionMajor = 1;
5958 afdi->ulManifestVersionMinor = 0;
5959 afdi->ulPolicyVersionMajor = 0; /* FIXME */
5960 afdi->ulPolicyVersionMinor = 0; /* FIXME */
5961 afdi->ulAssemblyDirectoryNameLength = ad_len ? (ad_len - 1) * sizeof(WCHAR) : 0;
5962 ptr = (LPWSTR)(afdi + 1);
5963 afdi->lpAssemblyEncodedAssemblyIdentity = ptr;
5964 memcpy( ptr, assembly_id, id_len * sizeof(WCHAR) );
5965 ptr += id_len;
5966 if (path_len)
5967 {
5968 afdi->lpAssemblyManifestPath = ptr;
5969 memcpy(ptr, assembly->manifest.info, path_len * sizeof(WCHAR));
5970 ptr += path_len;
5971 } else afdi->lpAssemblyManifestPath = NULL;
5972 afdi->lpAssemblyPolicyPath = NULL; /* FIXME */
5973 if (ad_len)
5974 {
5975 afdi->lpAssemblyDirectoryName = ptr;
5976 memcpy(ptr, assembly->directory, ad_len * sizeof(WCHAR));
5977 }
5978 else afdi->lpAssemblyDirectoryName = NULL;
5979 RtlFreeHeap( GetProcessHeap(), 0, assembly_id );
5980 }
5981 break;
5982
5983 case FileInformationInAssemblyOfAssemblyInActivationContext:
5984 {
5985 const ACTIVATION_CONTEXT_QUERY_INDEX *acqi = subinst;
5986 ASSEMBLY_FILE_DETAILED_INFORMATION *afdi = buffer;
5987 struct assembly *assembly;
5988 struct dll_redirect *dll;
5989 SIZE_T len, dll_len = 0;
5990 LPWSTR ptr;
5991
5993 if (!acqi) return STATUS_INVALID_PARAMETER;
5994
5995 if (acqi->ulAssemblyIndex >= actctx->num_assemblies)
5997 assembly = &actctx->assemblies[acqi->ulAssemblyIndex];
5998
5999 if (acqi->ulFileIndexInAssembly >= assembly->num_dlls)
6001 dll = &assembly->dlls[acqi->ulFileIndexInAssembly];
6002
6003 if (dll->name) dll_len = wcslen(dll->name) + 1;
6004 len = sizeof(*afdi) + dll_len * sizeof(WCHAR);
6005
6006 if (!buffer || bufsize < len)
6007 {
6008 if (retlen) *retlen = len;
6010 }
6011 if (retlen) *retlen = 0; /* yes that's what native does !! */
6012 afdi->ulFlags = ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION;
6013 afdi->ulFilenameLength = dll_len ? (dll_len - 1) * sizeof(WCHAR) : 0;
6014 afdi->ulPathLength = 0; /* FIXME */
6015 ptr = (LPWSTR)(afdi + 1);
6016 if (dll_len)
6017 {
6018 afdi->lpFileName = ptr;
6019 memcpy( ptr, dll->name, dll_len * sizeof(WCHAR) );
6020 } else afdi->lpFileName = NULL;
6021 afdi->lpFilePath = NULL; /* FIXME */
6022 }
6023 break;
6024
6025 case CompatibilityInformationInActivationContext:
6026 {
6027 struct acci
6028 {
6029 DWORD ElementCount;
6030 COMPATIBILITY_CONTEXT_ELEMENT Elements[1];
6031 } *acci = buffer;
6032 struct assembly *assembly = NULL;
6034 SIZE_T len;
6035
6037
6038 if (actctx->num_assemblies) assembly = actctx->assemblies;
6039
6040 if (assembly)
6042 len = offsetof( struct acci, Elements[num_compat_contexts] );
6043
6044 if (retlen) *retlen = len;
6045 if (!buffer || bufsize < len) return STATUS_BUFFER_TOO_SMALL;
6046
6047 acci->ElementCount = num_compat_contexts;
6048 for (n = 0; n < num_compat_contexts; ++n)
6049 {
6050 acci->Elements[n] = assembly->compat_contexts[n];
6051 }
6052 }
6053 break;
6054
6055 case RunlevelInformationInActivationContext:
6056 {
6057 ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION *acrli = buffer;
6058 struct assembly *assembly;
6059 SIZE_T len;
6060
6062
6063 len = sizeof(*acrli);
6064 if (retlen) *retlen = len;
6065 if (!buffer || bufsize < len)
6067
6068 assembly = actctx->assemblies;
6069
6070 acrli->ulFlags = 0;
6071 acrli->RunLevel = assembly ? assembly->run_level : ACTCTX_RUN_LEVEL_UNSPECIFIED;
6072 acrli->UiAccess = assembly ? assembly->ui_access : 0;
6073 }
6074 break;
6075
6076 default:
6077 FIXME( "class %lu not implemented\n", class );
6079 }
6080 return STATUS_SUCCESS;
6081}
6082
6083#ifdef __REACTOS__
6085NTAPI
6086RtlQueryInformationActiveActivationContext(ULONG ulInfoClass,
6087 PVOID pvBuffer,
6088 SIZE_T cbBuffer OPTIONAL,
6089 SIZE_T *pcbWrittenOrRequired OPTIONAL)
6090{
6092 NULL,
6093 NULL,
6094 ulInfoClass,
6095 pvBuffer,
6096 cbBuffer,
6097 pcbWrittenOrRequired);
6098}
6099
6100#define FIND_ACTCTX_RETURN_FLAGS 0x00000002
6101#define FIND_ACTCTX_RETURN_ASSEMBLY_METADATA 0x00000004
6102#define FIND_ACTCTX_VALID_MASK (FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX | FIND_ACTCTX_RETURN_FLAGS | FIND_ACTCTX_RETURN_ASSEMBLY_METADATA)
6103
6105NTAPI
6106RtlpFindActivationContextSection_CheckParameters( ULONG flags, const GUID *guid, ULONG section_kind,
6107 const UNICODE_STRING *section_name, PACTCTX_SECTION_KEYED_DATA data )
6108{
6109 /* Check general parameter combinations */
6110 if (!section_name || !section_name->Buffer ||
6111 (flags & ~FIND_ACTCTX_VALID_MASK) ||
6112 ((flags & FIND_ACTCTX_VALID_MASK) && !data) ||
6113 (data && data->cbSize < offsetof(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex)))
6114 {
6115 DPRINT1("invalid parameter\n");
6117 }
6118
6119 /* TODO */
6120 if (flags & FIND_ACTCTX_RETURN_FLAGS ||
6121 flags & FIND_ACTCTX_RETURN_ASSEMBLY_METADATA)
6122 {
6123 DPRINT1("unknown flags %08x\n", flags);
6125 }
6126
6127 return STATUS_SUCCESS;
6128}
6129#endif // __REACTOS__
6130
6131/***********************************************************************
6132 * RtlFindActivationContextSectionString (NTDLL.@)
6133 *
6134 * Find information about a string in an activation context.
6135 * FIXME: function signature/prototype may be wrong
6136 */
6138 const UNICODE_STRING *section_name, PVOID ptr )
6139{
6143
6144 TRACE("%08lx %s %lu %s %p\n", flags, debugstr_guid(guid), section_kind,
6145 debugstr_us(section_name), data);
6146
6147#ifdef __REACTOS__
6148 status = RtlpFindActivationContextSection_CheckParameters(flags, guid, section_kind, section_name, data);
6149 if (!NT_SUCCESS(status))
6150 {
6151 DPRINT1("RtlFindActivationContextSectionString() failed with status %x\n", status);
6152 return status;
6153 }
6154
6156
6157 /* if there is no data, but params are valid,
6158 we return that sxs key is not found to be at least somehow compatible */
6159 if (!data)
6160 {
6161 DPRINT("RtlFindActivationContextSectionString() failed with status %x\n", status);
6162 return status;
6163 }
6164#else
6165 if (guid)
6166 {
6167 FIXME("expected guid == NULL\n");
6169 }
6170 if (flags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX)
6171 {
6172 FIXME("unknown flags %08lx\n", flags);
6174 }
6175 if ((data && data->cbSize < offsetof(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex)) ||
6176 !section_name || !section_name->Buffer)
6177 {
6178 WARN("invalid parameter\n");
6180 }
6181#endif // __REACTOS__
6182
6184 if (actctx) status = find_string( actctx, section_kind, section_name, flags, data );
6185
6186 DPRINT("status %x\n", status);
6187 if (status != STATUS_SUCCESS)
6188 status = find_string( process_actctx, section_kind, section_name, flags, data );
6189
6190 if (status != STATUS_SUCCESS)
6191 status = find_string( implicit_actctx, section_kind, section_name, flags, data );
6192
6193 DPRINT("RtlFindActivationContextSectionString() returns status %x\n", status);
6194 return status;
6195}
6196
6197/***********************************************************************
6198 * RtlFindActivationContextSectionGuid (NTDLL.@)
6199 *
6200 * Find information about a GUID in an activation context.
6201 * FIXME: function signature/prototype may be wrong
6202 */
6204 const GUID *guid, void *ptr )
6205{
6206 ACTCTX_SECTION_KEYED_DATA *data = ptr;
6209
6210 TRACE("%08lx %s %lu %s %p\n", flags, debugstr_guid(extguid), section_kind, debugstr_guid(guid), data);
6211
6212 if (extguid)
6213 {
6214 FIXME("expected extguid == NULL\n");
6216 }
6217
6218 if (flags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX)
6219 {
6220 FIXME("unknown flags %08lx\n", flags);
6222 }
6223
6224 if (!data || data->cbSize < FIELD_OFFSET(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) || !guid)
6226
6228 if (actctx) status = find_guid( actctx, section_kind, guid, flags, data );
6229
6230 if (status != STATUS_SUCCESS)
6231 status = find_guid( process_actctx, section_kind, guid, flags, data );
6232
6233 if (status != STATUS_SUCCESS)
6234 status = find_guid( implicit_actctx, section_kind, guid, flags, data );
6235
6236 return status;
6237}
6238
6239
6240/***********************************************************************
6241 * RtlQueryActivationContextApplicationSettings (NTDLL.@)
6242 */
6244 const WCHAR *settings, WCHAR *buffer,
6245 SIZE_T size, SIZE_T *written )
6246{
6248 const WCHAR *res;
6249
6250 if (flags)
6251 {
6252 WARN( "unknown flags %08lx\n", flags );
6254 }
6255
6256 if (ns)
6257 {
6265 }
6267
6270
6272
6273 if (written) *written = wcslen(res) + 1;
6274 if (size < wcslen(res)) return STATUS_BUFFER_TOO_SMALL;
6275 wcscpy( buffer, res );
6276 return STATUS_SUCCESS;
6277}
6278
6279#ifdef __REACTOS__
6280/* Stubs */
6281
6283NTAPI
6284RtlAllocateActivationContextStack(IN PACTIVATION_CONTEXT_STACK *Stack)
6285{
6286 PACTIVATION_CONTEXT_STACK ContextStack;
6287
6288 /* Check if it's already allocated */
6289 if (*Stack) return STATUS_SUCCESS;
6290
6291 /* Allocate space for the context stack */
6293 if (!ContextStack)
6294 {
6295 return STATUS_NO_MEMORY;
6296 }
6297
6298 /* Initialize the context stack */
6299 ContextStack->Flags = 0;
6300 ContextStack->ActiveFrame = NULL;
6301 InitializeListHead(&ContextStack->FrameListCache);
6302 ContextStack->NextCookieSequenceNumber = 1;
6303 ContextStack->StackId = 1; //TODO: Timer-based
6304
6305 *Stack = ContextStack;
6306
6307 return STATUS_SUCCESS;
6308}
6309
6312RtlActivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame,
6314{
6317
6318 /* Get the current active frame */
6319 ActiveFrame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame;
6320
6321 DPRINT("ActiveSP %p: ACTIVATE (ActiveFrame %p -> NewFrame %p, Context %p)\n",
6322 NtCurrentTeb()->ActivationContextStackPointer, ActiveFrame,
6323 &Frame->Frame, Context);
6324
6325 /* Ensure it's in the right format and at least fits basic info */
6327 ASSERT(Frame->Size >= sizeof(RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_BASIC));
6328
6329 /* Set debug info if size allows*/
6330 if (Frame->Size >= sizeof(RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED))
6331 {
6332 Frame->Extra1 = (PVOID)(~(ULONG_PTR)ActiveFrame);
6333 Frame->Extra2 = (PVOID)(~(ULONG_PTR)Context);
6334 //Frame->Extra3 = ...;
6335 }
6336
6337 if (ActiveFrame)
6338 {
6339 /*ASSERT((ActiveFrame->Flags &
6340 (RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_ACTIVATED |
6341 RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_DEACTIVATED |
6342 RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_NOT_REALLY_ACTIVATED)) == RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_ACTIVATED);*/
6343
6345 {
6346 // TODO: Perform some additional checks if it was not heap allocated
6347 }
6348 }
6349
6350 /* Save pointer to the new activation frame */
6351 NewFrame = &Frame->Frame;
6352
6353 /* Actually activate it */
6354 Frame->Frame.Previous = ActiveFrame;
6355 Frame->Frame.ActivationContext = Context;
6357
6358 /* Check if we can activate this context */
6359 if ((ActiveFrame && (ActiveFrame->ActivationContext != Context)) ||
6360 Context)
6361 {
6362 /* Set new active frame */
6363 DPRINT("Setting new active frame %p instead of old %p\n", NewFrame, ActiveFrame);
6364 NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = NewFrame;
6365 return NewFrame;
6366 }
6367
6368 /* We can get here only one way: it was already activated */
6369 DPRINT("Trying to activate already activated activation context\n");
6370
6371 /* Activate only if we are allowing multiple activation */
6372#if 0
6373 if (!RtlpNotAllowingMultipleActivation)
6374 {
6376 NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = NewFrame;
6377 }
6378#else
6379 // Activate it anyway
6380 NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = NewFrame;
6381#endif
6382
6383 /* Return pointer to the activation frame */
6384 return NewFrame;
6385}
6386
6389RtlDeactivateActivationContextUnsafeFast(IN PRTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame)
6390{
6391 PRTL_ACTIVATION_CONTEXT_STACK_FRAME ActiveFrame, NewFrame;
6392
6393 ActiveFrame = NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame;
6394
6395 /* Ensure it's in the right format and at least fits basic info */
6397 ASSERT(Frame->Size >= sizeof(RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_BASIC));
6398
6399 /* Make sure it is not deactivated and it is activated */
6403
6404 /* Check debug info if it is present */
6405 if (Frame->Size >= sizeof(RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED))
6406 {
6407 ASSERT(Frame->Extra1 == (PVOID)(~(ULONG_PTR)Frame->Frame.Previous));
6408 ASSERT(Frame->Extra2 == (PVOID)(~(ULONG_PTR)Frame->Frame.ActivationContext));
6409 //Frame->Extra3 = ...;
6410 }
6411
6412 if (ActiveFrame)
6413 {
6414 // TODO: Perform some additional checks here
6415 }
6416
6417 /* Special handling for not-really-activated */
6419 {
6420 DPRINT1("Deactivating not really activated activation context\n");
6422 return &Frame->Frame;
6423 }
6424
6425 /* find the right frame */
6426 NewFrame = &Frame->Frame;
6427 if (ActiveFrame != NewFrame)
6428 {
6429 DPRINT1("Deactivating wrong active frame: %p != %p\n", ActiveFrame, NewFrame);
6430 }
6431
6432 DPRINT("ActiveSP %p: DEACTIVATE (ActiveFrame %p -> PreviousFrame %p)\n",
6433 NtCurrentTeb()->ActivationContextStackPointer, NewFrame, NewFrame->Previous);
6434
6435 /* Pop everything up to and including frame */
6436 NtCurrentTeb()->ActivationContextStackPointer->ActiveFrame = NewFrame->Previous;
6437
6439 return NewFrame->Previous;
6440}
6441
6443NTAPI
6444RtlpInitializeActCtx(PVOID* pOldShimData)
6445{
6446 ACTCTXW ctx;
6447 HANDLE handle;
6448 WCHAR buffer[1024];
6450
6451 /* Initialize trace flags to WARN and ERR */
6452 __wine_dbch_actctx.flags = 0x03;
6453
6454 actctx_init();
6455
6456 /* ReactOS specific:
6457 Now that we have found the process_actctx we can initialize the process compat subsystem */
6459
6460 ctx.cbSize = sizeof(ctx);
6461 ctx.dwFlags = 0;
6462 ctx.hModule = NULL;
6463 ctx.lpResourceName = NULL;
6464 ctx.lpSource = buffer;
6466 RtlStringCchCatW(buffer, RTL_NUMBER_OF(buffer), L"\\winsxs\\manifests\\systemcompatible.manifest");
6467
6469 if (NT_SUCCESS(Status))
6470 {
6472 }
6473 else
6474 {
6475 DPRINT1("Failed to create the implicit act ctx. Status: 0x%x!!!\n", Status);
6476 }
6477
6478 return Status;
6479}
6480
6481#endif // __REACTOS__
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3485
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3078
NTSTATUS NTAPI NtMapViewOfSection(IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3259
static UCHAR NotificationContext
struct mke2fs_defaults settings[]
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
@ optional
Definition: SystemMenu.c:34
unsigned char BOOLEAN
Definition: actypes.h:127
comclass_threadingmodel
Definition: apartment.c:42
unsigned int dir
Definition: maze.c:112
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
const WCHAR * alias
Definition: main.c:67
LONG NTSTATUS
Definition: precomp.h:26
static const WCHAR nameW[]
Definition: main.c:49
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define index(s, c)
Definition: various.h:29
#define DPRINT1
Definition: precomp.h:8
#define ARRAY_SIZE(A)
Definition: main.h:20
#define FIXME(fmt,...)
Definition: precomp.h:53
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
struct _root root
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
IMAGE_RESOURCE_DIRECTORY * find_entry_by_name(IMAGE_RESOURCE_DIRECTORY *dir, LPCWSTR name, void *root, int want_dir)
Definition: res.c:177
IMAGE_RESOURCE_DIRECTORY * find_first_entry(IMAGE_RESOURCE_DIRECTORY *dir, void *root, int want_dir)
Definition: res.c:75
#define DECLSPEC_HIDDEN
Definition: precomp.h:8
static const WCHAR quote[]
Definition: reg.c:40
content
Definition: atl_ax.c:994
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
const char * wine_dbg_sprintf(const char *format,...)
Definition: compat.c:296
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
#define wcsnicmp
Definition: compat.h:14
#define wcsrchr
Definition: compat.h:16
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define __TRY
Definition: compat.h:80
#define GetCurrentProcess()
Definition: compat.h:759
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define GENERIC_READ
Definition: compat.h:135
#define TRACE_ON(x)
Definition: compat.h:75
#define RtlImageNtHeader
Definition: compat.h:806
#define __ENDTRY
Definition: compat.h:82
#define FILE_SHARE_READ
Definition: compat.h:136
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
#define wcsicmp
Definition: compat.h:15
static const WCHAR version[]
Definition: asmname.c:66
const WCHAR windows_dir[]
Definition: file.c:67
GUID guid
Definition: version.c:147
WORD WORD WORD * revision
Definition: metahost.c:91
WORD WORD * build
Definition: metahost.c:91
unsigned char ch[4][2]
Definition: console.c:118
_ACRTIMP __msvcrt_ulong __cdecl wcstoul(const wchar_t *, wchar_t **, int)
Definition: wcs.c:2912
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1972
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
_ACRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:518
int WINAPIV _swprintf(wchar_t *str, const wchar_t *format,...)
Definition: wcs.c:1687
comclass_miscfields
Definition: compobj.c:73
#define swprintf
Definition: precomp.h:40
static const ULONG lookup[16]
Definition: vga.c:48
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
r parent
Definition: btrfs.c:3010
#define ULONG_PTR
Definition: config.h:101
#define PtrToUlong(u)
Definition: config.h:107
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define progid(str)
Definition: exdisp.idl:31
static unsigned char buff[32768]
Definition: fatten.c:17
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileBothDirectoryInformation
Definition: from_kernel.h:64
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: from_kernel.h:30
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble n
Definition: glext.h:7729
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLintptr offset
Definition: glext.h:5920
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
GLuint GLuint num
Definition: glext.h:9618
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
const char * filename
Definition: ioapi.h:137
NTSTATUS NTAPI NtQueryDirectoryFile(IN HANDLE FileHandle, IN HANDLE EventHandle OPTIONAL, IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass, IN BOOLEAN ReturnSingleEntry, IN PUNICODE_STRING FileName OPTIONAL, IN BOOLEAN RestartScan)
Definition: iofunc.c:1994
#define NtCurrentTeb
uint32_t entry
Definition: isohybrid.c:63
LONG dll_count
Definition: itss.c:49
#define c
Definition: ke_i.h:80
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_wn
Definition: kernel32.h:33
#define actctx
Definition: kernel32.h:8
#define debugstr_w
Definition: kernel32.h:32
VOID NTAPI LdrpInitializeProcessCompat(PVOID pProcessActctx, PVOID *pOldShimData)
Definition: ldrinit.c:1593
NTSTATUS NTAPI RtlpInitializeActCtx(PVOID *pOldShimData)
NTSTATUS NTAPI LdrUnlockLoaderLock(_In_ ULONG Flags, _In_opt_ ULONG_PTR Cookie)
Definition: ldrapi.c:101
NTSTATUS NTAPI LdrLockLoaderLock(_In_ ULONG Flags, _Out_opt_ PULONG Disposition, _Out_opt_ PULONG_PTR Cookie)
Definition: ldrapi.c:174
NTSTATUS NTAPI LdrFindEntryForAddress(_In_ PVOID Address, _Out_ PLDR_DATA_TABLE_ENTRY *Module)
Definition: ldrapi.c:425
NTSTATUS NTAPI LdrAccessResource(_In_ PVOID BaseAddress, _In_ PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry, _Out_opt_ PVOID *Resource, _Out_opt_ PULONG Size)
NTSTATUS NTAPI LdrFindResource_U(_In_ PVOID BaseAddress, _In_ PLDR_RESOURCE_INFO ResourceInfo, _In_ ULONG Level, _Out_ PIMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry)
NTSTATUS NTAPI LdrFindResourceDirectory_U(_In_ PVOID BaseAddress, _In_ PLDR_RESOURCE_INFO ResourceInfo, _In_ ULONG Level, _Out_ PIMAGE_RESOURCE_DIRECTORY *ResourceDirectory)
_In_ PCWSTR _Out_ PVOID * ActCtx
Definition: ldrtypes.h:264
USHORT LANGID
Definition: mui.h:9
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ASSERT(a)
Definition: mode.c:44
static PVOID ptr
Definition: dispmode.c:27
static DWORD path_len
Definition: batch.c:31
static SIZE_T *static const GUID PACTCTX_SECTION_KEYED_DATA
Definition: actctx.c:34
@ MiscStatusContent
Definition: actctx.c:1581
@ MiscStatusThumbnail
Definition: actctx.c:1582
@ MiscStatus
Definition: actctx.c:1579
@ MiscStatusDocPrint
Definition: actctx.c:1583
@ MiscStatusIcon
Definition: actctx.c:1580
ifaceps_mask
Definition: actctx.c:1779
@ BaseIface
Definition: actctx.c:1781
@ NumMethods
Definition: actctx.c:1780
static LPWSTR
Definition: actctx.c:32
static SIZE_T *static const GUID ULONG
Definition: actctx.c:34
#define GUIDSECTION_MAGIC
@ ThreadingModel_No
Definition: actctx.c:1573
@ ThreadingModel_Both
Definition: actctx.c:1574
@ ThreadingModel_Neutral
Definition: actctx.c:1575
@ ThreadingModel_Free
Definition: actctx.c:1572
@ ThreadingModel_Apartment
Definition: actctx.c:1571
static size_t elem
Definition: string.c:71
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:100
#define HASH_STRING_ALGORITHM_X65599
Definition: rtlstr.c:33
WCHAR strW[12]
Definition: clipboard.c:2025
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
const CLSID * clsid
Definition: msctf.cpp:50
unsigned int UINT
Definition: ndis.h:50
#define SEC_COMMIT
Definition: mmtypes.h:100
NTSYSAPI ULONG NTAPI RtlUniform(_In_ PULONG Seed)
NTSYSAPI NTSTATUS NTAPI RtlFindActivationContextSectionGuid(ULONG flags, const GUID *extguid, ULONG section_kind, const GUID *guid, void *ptr)
Definition: actctx.c:6203
NTSYSAPI NTSTATUS NTAPI RtlHashUnicodeString(_In_ CONST UNICODE_STRING *String, _In_ BOOLEAN CaseInSensitive, _In_ ULONG HashAlgorithm, _Out_ PULONG HashValue)
NTSYSAPI BOOLEAN NTAPI RtlIsTextUnicode(_In_ CONST VOID *Buffer, _In_ INT Size, _Inout_opt_ INT *Flags)
NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path)
_Must_inspect_result_ NTSYSAPI LONG NTAPI RtlCompareUnicodeStrings(_In_reads_(String1Length) PCWCH String1, _In_ SIZE_T String1Length, _In_reads_(String2Length) PCWCH String2, _In_ SIZE_T String2Length, _In_ BOOLEAN CaseInSensitive)
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSYSAPI ULONG NTAPI RtlGetFullPathName_U(_In_ PCWSTR FileName, _In_ ULONG Size, _Out_z_bytecap_(Size) PWSTR Buffer, _Out_opt_ PWSTR *ShortName)
Definition: path.c:1987
NTSYSAPI SIZE_T NTAPI RtlSizeHeap(_In_ PVOID HeapHandle, _In_ ULONG Flags, _In_ PVOID MemoryPointer)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_NOT_REALLY_ACTIVATED
Definition: rtltypes.h:94
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_ACTIVATED
Definition: rtltypes.h:95
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_IS_ADDRESS
Definition: rtltypes.h:118
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_IS_HMODULE
Definition: rtltypes.h:117
#define RTL_DEACTIVATE_ACTIVATION_CONTEXT_FLAG_FORCE_EARLY_DEACTIVATION
Definition: rtltypes.h:111
#define RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_FORMAT_WHISTLER
Definition: rtltypes.h:101
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_DEACTIVATED
Definition: rtltypes.h:96
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_NO_ADDREF
Definition: rtltypes.h:119
#define RTL_ACTIVATION_CONTEXT_STACK_FRAME_FLAG_HEAP_ALLOCATED
Definition: rtltypes.h:93
#define RTL_QUERY_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT
Definition: rtltypes.h:116
HMODULE hModule
Definition: netsh.c:17
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3953
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define SECTION_QUERY
Definition: nt_native.h:1290
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define HEAP_GENERATE_EXCEPTIONS
Definition: nt_native.h:1697
#define FASTCALL
Definition: nt_native.h:50
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToInteger(PUNICODE_STRING String, ULONG Base, PULONG Value)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
@ ViewShare
Definition: nt_native.h:1281
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define STANDARD_RIGHTS_REQUIRED
Definition: nt_native.h:63
#define STATUS_SXS_CANT_GEN_ACTCTX
Definition: ntstatus.h:1771
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:453
#define STATUS_SXS_ASSEMBLY_NOT_FOUND
Definition: ntstatus.h:1773
#define STATUS_DLL_NOT_FOUND
Definition: ntstatus.h:639
#define STATUS_SXS_EARLY_DEACTIVATION
Definition: ntstatus.h:1783
#define STATUS_RESOURCE_NAME_NOT_FOUND
Definition: ntstatus.h:469
#define STATUS_SXS_INVALID_DEACTIVATION
Definition: ntstatus.h:1784
#define STATUS_RESOURCE_TYPE_NOT_FOUND
Definition: ntstatus.h:468
#define STATUS_SXS_SECTION_NOT_FOUND
Definition: ntstatus.h:1770
#define STATUS_RESOURCE_DATA_NOT_FOUND
Definition: ntstatus.h:467
#define STATUS_SXS_KEY_NOT_FOUND
Definition: ntstatus.h:1777
NTSTRSAFEAPI RtlStringCchCopyW(_Out_writes_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:127
NTSTRSAFEAPI RtlStringCchCatW(_Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:601
#define LOWORD(l)
Definition: pedump.c:82
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define IMAGE_DIRECTORY_ENTRY_RESOURCE
Definition: pedump.c:261
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define RtlUTF8ToUnicodeN
Definition: reactos.cpp:12
const WCHAR * str
#define NtGetTickCount
Definition: rtlp.h:163
#define offsetof(TYPE, MEMBER)
wcscat
wcscpy
#define SharedUserData
XML_HIDDEN void xmlParserErrors const char const xmlChar const xmlChar * str2
Definition: parser.h:35
XML_HIDDEN void xmlParserErrors const char const xmlChar * str1
Definition: parser.h:35
#define memset(x, y, z)
Definition: compat.h:39
static void read_xml_elem(xmlbuf_t *xmlbuf, struct xml_elem *elem)
Definition: actctx.c:1305
#define ACTCTX_FAKE_HANDLE
Definition: actctx.c:64
static void write_progid_record(struct strsection_header *section, const WCHAR *progid, const GUID *alias, struct string_index **index, ULONG *data_offset, ULONG *global_offset, ULONG rosterindex)
Definition: actctx.c:5163
static struct comclassredirect_data * get_comclass_data(ACTIVATION_CONTEXT *actctx, struct guid_index *index)
Definition: actctx.c:4724
static void parse_noinheritable_elem(xmlbuf_t *xmlbuf, const struct xml_elem *parent)
Definition: actctx.c:2295
static NTSTATUS open_nt_file(HANDLE *handle, UNICODE_STRING *name)
Definition: actctx.c:2994
assembly_type
Definition: actctx.c:545
@ APPLICATION_MANIFEST
Definition: actctx.c:546
@ ASSEMBLY_SHARED_MANIFEST
Definition: actctx.c:548
@ ASSEMBLY_MANIFEST
Definition: actctx.c:547
static const xmlstr_t empty_xmlstr
Definition: actctx.c:638
static BOOL isxmlspace(WCHAR ch)
Definition: actctx.c:760
static BOOL next_xml_attr(xmlbuf_t *xmlbuf, struct xml_attr *attr, BOOL *end)
Definition: actctx.c:1236
static void push_xmlns(xmlbuf_t *xmlbuf, const struct xml_attr *attr)
Definition: actctx.c:1201
static NTSTATUS add_comserver_record(const struct guidsection_header *section, const struct entity_array *entities, const struct dll_redirect *dll, struct guid_index **index, ULONG *data_offset, ULONG *module_offset, ULONG *seed, ULONG rosterindex)
Definition: actctx.c:4480
static ACTIVATION_CONTEXT * implicit_actctx
Definition: actctx.c:698
static WCHAR * build_assembly_dir(struct assembly_identity *ai)
Definition: actctx.c:1058
static NTSTATUS get_manifest_in_module(struct actctx_loader *acl, struct assembly_identity *ai, LPCWSTR filename, LPCWSTR directory, BOOL shared, HANDLE hModule, LPCWSTR resname, ULONG lang)
Definition: actctx.c:3027
enum tagLIBFLAGS LIBFLAGS
static void parse_expect_end_elem(xmlbuf_t *xmlbuf, const struct xml_elem *parent)
Definition: actctx.c:1468
static NTSTATUS get_manifest_in_associated_manifest(struct actctx_loader *acl, struct assembly_identity *ai, LPCWSTR filename, LPCWSTR directory, HMODULE module, LPCWSTR resname)
Definition: actctx.c:3253
static BOOL xml_name_cmp(const struct xml_elem *elem1, const struct xml_elem *elem2)
Definition: actctx.c:736
static NTSTATUS add_ifaceps_record(struct guidsection_header *section, struct entity_array *entities, struct guid_index **index, ULONG *data_offset, ULONG rosterindex)
Definition: actctx.c:4786
static WCHAR * lookup_manifest_file(HANDLE dir, struct assembly_identity *ai)
Definition: actctx.c:3301
static const WCHAR asmv2W[]
Definition: actctx.c:653
static void parse_binding_redirect_elem(xmlbuf_t *xmlbuf, const struct xml_elem *parent)
Definition: actctx.c:1995
static DWORD parse_com_class_misc(const xmlstr_t *value)
Definition: actctx.c:1578
static int aligned_string_len(int len)
Definition: actctx.c:1937
static const WCHAR current_archW[]
Definition: actctx.c:649
static struct wndclass_redirect_data * get_wndclass_data(ACTIVATION_CONTEXT *ctxt, struct string_index *index)
Definition: actctx.c:3835
static const WCHAR windowsSettings2011NSW[]
Definition: actctx.c:658
static NTSTATUS build_dllredirect_section(ACTIVATION_CONTEXT *actctx, struct strsection_header **section)
Definition: actctx.c:3611
static const WCHAR asmv3W[]
Definition: actctx.c:654
static struct tlibredirect_data * get_tlib_data(ACTIVATION_CONTEXT *actctx, struct guid_index *index)
Definition: actctx.c:4373
static void parse_noinherit_elem(xmlbuf_t *xmlbuf, const struct xml_elem *parent)
Definition: actctx.c:2287
static BOOL parse_text_content(xmlbuf_t *xmlbuf, xmlstr_t *content)
Definition: actctx.c:1410
static void parse_activatable_class_elem(xmlbuf_t *xmlbuf, struct dll_redirect *dll, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2303
static OLEMISC get_olemisc_value(const WCHAR *str, int len)
Definition: actctx.c:1551
struct _ACTIVATION_CONTEXT ACTIVATION_CONTEXT
static NTSTATUS find_first_manifest_resource_in_module(HANDLE hModule, const WCHAR **resname)
Definition: actctx.c:3009
static ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION * get_dllredirect_data(ACTIVATION_CONTEXT *ctxt, struct string_index *index)
Definition: actctx.c:3780
static NTSTATUS find_cominterface_redirection(ACTIVATION_CONTEXT *actctx, const GUID *guid, ACTCTX_SECTION_KEYED_DATA *data)
Definition: actctx.c:4942
static NTSTATUS lookup_winsxs(struct actctx_loader *acl, struct assembly_identity *ai)
Definition: actctx.c:3385
static struct progidredirect_data * get_progid_data(ACTIVATION_CONTEXT *actctx, const struct string_index *index)
Definition: actctx.c:5309
static struct activatable_class_data * get_activatable_class_data(ACTIVATION_CONTEXT *ctxt, struct string_index *index)
Definition: actctx.c:4048
static void get_ifaceps_datalen(const struct entity_array *entities, unsigned int *count, unsigned int *len)
Definition: actctx.c:4769
static NTSTATUS get_manifest_in_pe_file(struct actctx_loader *acl, struct assembly_identity *ai, LPCWSTR filename, LPCWSTR directory, BOOL shared, HANDLE file, LPCWSTR resname, ULONG lang)
Definition: actctx.c:3153
static struct entity * add_entity(struct entity_array *array, DWORD kind)
Definition: actctx.c:895
static NTSTATUS build_activatable_class_section(ACTIVATION_CONTEXT *actctx, struct strsection_header **section)
Definition: actctx.c:4053
static void parse_com_class_elem(xmlbuf_t *xmlbuf, struct dll_redirect *dll, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:1638
static void parse_assembly_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent, struct assembly_identity *expected_ai)
Definition: actctx.c:2747
static struct string_index * find_string_index(const struct strsection_header *section, const UNICODE_STRING *name)
Definition: actctx.c:3728
static void free_depend_manifests(struct actctx_loader *acl)
Definition: actctx.c:1050
static WCHAR * xmlstrdupW(const xmlstr_t *str)
Definition: actctx.c:709
tagLIBFLAGS
Definition: actctx.c:72
@ LIBFLAG_FRESTRICTED
Definition: actctx.c:73
@ LIBFLAG_FHASDISKIMAGE
Definition: actctx.c:76
@ LIBFLAG_FCONTROL
Definition: actctx.c:74
@ LIBFLAG_FHIDDEN
Definition: actctx.c:75
static BOOL is_xmlns_attr(const struct xml_attr *attr)
Definition: actctx.c:1193
static ACTIVATION_CONTEXT system_actctx
Definition: actctx.c:696
static HANDLE get_current_actctx_no_addref(void)
Definition: actctx.c:3566
static WCHAR * strdupW(const WCHAR *str)
Definition: actctx.c:700
static ACTIVATION_CONTEXT * process_actctx
Definition: actctx.c:697
static NTSTATUS parse_depend_manifests(struct actctx_loader *acl)
Definition: actctx.c:3543
static void parse_typelib_elem(xmlbuf_t *xmlbuf, struct dll_redirect *dll, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:1896
static WCHAR * build_assembly_id(const struct assembly_identity *ai)
Definition: actctx.c:1100
static void parse_requested_execution_level_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2645
static void parse_compatibility_application_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2506
static NTSTATUS get_module_filename(HMODULE module, UNICODE_STRING *str, unsigned int extra_len)
Definition: actctx.c:787
void WINAPI RtlFreeActivationContextStack(ACTIVATION_CONTEXT_STACK *actctx_stack)
Definition: actctx.c:5774
static void actctx_addref(ACTIVATION_CONTEXT *actctx)
Definition: actctx.c:1142
static NTSTATUS find_comserver_redirection(ACTIVATION_CONTEXT *actctx, const GUID *guid, ACTCTX_SECTION_KEYED_DATA *data)
Definition: actctx.c:4729
static void parse_add_interface_class(xmlbuf_t *xmlbuf, struct entity_array *entities, struct actctx_loader *acl, WCHAR *clsid)
Definition: actctx.c:1743
static const WCHAR winrtv1W[]
Definition: actctx.c:655
static NTSTATUS build_ifaceps_section(ACTIVATION_CONTEXT *actctx, struct guidsection_header **section)
Definition: actctx.c:4875
static const WCHAR asmv1W[]
Definition: actctx.c:652
static NTSTATUS get_manifest_in_manifest_file(struct actctx_loader *acl, struct assembly_identity *ai, LPCWSTR filename, LPCWSTR directory, BOOL shared, HANDLE file)
Definition: actctx.c:3209
static NTSTATUS build_comserver_section(ACTIVATION_CONTEXT *actctx, struct guidsection_header **section)
Definition: actctx.c:4661
static void parse_com_class_progid(xmlbuf_t *xmlbuf, struct entity *entity, const struct xml_elem *parent)
Definition: actctx.c:1625
static void parse_maxversiontested_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2473
static void parse_file_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2351
#define STRSECTION_MAGIC
Definition: actctx.c:61
static NTSTATUS build_wndclass_section(ACTIVATION_CONTEXT *actctx, struct strsection_header **section)
Definition: actctx.c:3840
#define ACTCTX_FLAGS_ALL
Definition: actctx.c:50
static xmlstr_t find_xmlns(xmlbuf_t *xmlbuf, const xmlstr_t *name)
Definition: actctx.c:1222
static void parse_description_elem(xmlbuf_t *xmlbuf, const struct xml_elem *parent)
Definition: actctx.c:2019
static void append_string(WCHAR *buffer, const WCHAR *prefix, const WCHAR *str)
Definition: actctx.c:1086
void WINAPI RtlFreeThreadActivationContextStack(void)
Definition: actctx.c:5762
static void parse_settings_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, struct xml_elem *parent)
Definition: actctx.c:2550
static BOOL next_xml_elem(xmlbuf_t *xmlbuf, struct xml_elem *elem, const struct xml_elem *parent)
Definition: actctx.c:1325
static struct ifacepsredirect_data * get_ifaceps_data(ACTIVATION_CONTEXT *actctx, struct guid_index *index)
Definition: actctx.c:4937
static NTSTATUS find_string(ACTIVATION_CONTEXT *actctx, ULONG section_kind, const UNICODE_STRING *section_name, DWORD flags, PACTCTX_SECTION_KEYED_DATA data)
Definition: actctx.c:5367
static BOOL xmlstr_cmpi(const xmlstr_t *xmlstr, const WCHAR *str)
Definition: actctx.c:726
static const char * debugstr_xmlstr(const xmlstr_t *str)
Definition: actctx.c:765
static void parse_expect_no_attr(xmlbuf_t *xmlbuf, BOOL *end)
Definition: actctx.c:1458
static const struct olemisc_entry olemisc_values[]
Definition: actctx.c:670
context_sections
Definition: actctx.c:569
@ SERVERREDIRECT_SECTION
Definition: actctx.c:573
@ IFACEREDIRECT_SECTION
Definition: actctx.c:574
@ ACTIVATABLE_CLASS_SECTION
Definition: actctx.c:577
@ CLRSURROGATES_SECTION
Definition: actctx.c:575
@ PROGIDREDIRECT_SECTION
Definition: actctx.c:576
@ TLIBREDIRECT_SECTION
Definition: actctx.c:572
@ WINDOWCLASS_SECTION
Definition: actctx.c:570
@ DLLREDIRECT_SECTION
Definition: actctx.c:571
NTSTATUS WINAPI RtlQueryActivationContextApplicationSettings(DWORD flags, HANDLE handle, const WCHAR *ns, const WCHAR *settings, WCHAR *buffer, SIZE_T size, SIZE_T *written)
Definition: actctx.c:6243
static void parse_supportedos_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2432
static void parse_application_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2617
static NTSTATUS parse_manifest(struct actctx_loader *acl, struct assembly_identity *ai, LPCWSTR filename, HANDLE module, LPCWSTR directory, BOOL shared, const void *buffer, SIZE_T size)
Definition: actctx.c:2915
static BOOL parse_nummethods(const xmlstr_t *str, struct entity *entity)
Definition: actctx.c:1723
static void free_entity_array(struct entity_array *array)
Definition: actctx.c:923
static BOOL add_dependent_assembly_id(struct actctx_loader *acl, struct assembly_identity *ai)
Definition: actctx.c:1001
static BOOL parse_typelib_version(const xmlstr_t *str, struct entity *entity)
Definition: actctx.c:1866
NTSTATUS WINAPI RtlActivateActivationContextEx(ULONG flags, TEB *teb, HANDLE handle, ULONG_PTR *cookie)
Definition: actctx.c:5697
static void parse_com_interface_external_proxy_stub_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2043
static struct string_index * get_wndclass_first_index(ACTIVATION_CONTEXT *actctx)
Definition: actctx.c:3830
static void actctx_release(ACTIVATION_CONTEXT *actctx)
Definition: actctx.c:1147
tagOLEMISC
Definition: actctx.c:81
@ OLEMISC_INSIDEOUT
Definition: actctx.c:89
@ OLEMISC_ACTIVATEWHENVISIBLE
Definition: actctx.c:90
@ OLEMISC_RENDERINGISDEVICEINDEPENDENT
Definition: actctx.c:91
@ OLEMISC_ACTSLIKEBUTTON
Definition: actctx.c:94
@ OLEMISC_WANTSTOMENUMERGE
Definition: actctx.c:102
@ OLEMISC_IGNOREACTIVATEWHENVISIBLE
Definition: actctx.c:101
@ OLEMISC_INSERTNOTREPLACE
Definition: actctx.c:84
@ OLEMISC_IMEMODE
Definition: actctx.c:100
@ OLEMISC_CANLINKBYOLE1
Definition: actctx.c:87
@ OLEMISC_ALIGNABLE
Definition: actctx.c:97
@ OLEMISC_ALWAYSRUN
Definition: actctx.c:93
@ OLEMISC_SETCLIENTSITEFIRST
Definition: actctx.c:99
@ OLEMISC_ISLINKOBJECT
Definition: actctx.c:88
@ OLEMISC_NOUIACTIVATE
Definition: actctx.c:96
@ OLEMISC_SUPPORTSMULTILEVELUNDO
Definition: actctx.c:103
@ OLEMISC_SIMPLEFRAME
Definition: actctx.c:98
@ OLEMISC_ONLYICONIC
Definition: actctx.c:83
@ OLEMISC_ACTSLIKELABEL
Definition: actctx.c:95
@ OLEMISC_INVISIBLEATRUNTIME
Definition: actctx.c:92
@ OLEMISC_RECOMPOSEONRESIZE
Definition: actctx.c:82
@ OLEMISC_STATIC
Definition: actctx.c:85
@ OLEMISC_CANTLINKINSIDE
Definition: actctx.c:86
static void parse_windows_settings_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2586
static BOOL com_class_add_progid(const xmlstr_t *progid, struct entity *entity)
Definition: actctx.c:1600
static NTSTATUS find_query_actctx(HANDLE *handle, DWORD flags, ULONG class)
Definition: actctx.c:3577
#define CHECK_LIMIT(field)
static struct clrsurrogate_data * get_surrogate_data(ACTIVATION_CONTEXT *actctx, const struct guid_index *index)
Definition: actctx.c:5091
static const char * debugstr_xml_elem(const struct xml_elem *elem)
Definition: actctx.c:770
static BOOL set_error(xmlbuf_t *xmlbuf)
Definition: actctx.c:1187
static BOOL is_matching_string(const WCHAR *str1, const WCHAR *str2)
Definition: actctx.c:975
static NTSTATUS add_progid_record(ACTIVATION_CONTEXT *actctx, struct strsection_header *section, const struct entity_array *entities, struct string_index **index, ULONG *data_offset, ULONG *global_offset, ULONG rosterindex)
Definition: actctx.c:5206
static NTSTATUS build_progid_section(ACTIVATION_CONTEXT *actctx, struct strsection_header **section)
Definition: actctx.c:5243
static void parse_cominterface_proxy_stub_elem(xmlbuf_t *xmlbuf, struct dll_redirect *dll, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:1770
static BOOL xml_attr_cmp(const struct xml_attr *attr, const WCHAR *str)
Definition: actctx.c:731
static void parse_dependent_assembly_elem(xmlbuf_t *xmlbuf, struct actctx_loader *acl, const struct xml_elem *parent, BOOL optional)
Definition: actctx.c:2202
static const char * debugstr_version(const struct assembly_version *ver)
Definition: actctx.c:782
static BOOL parse_typelib_flags(const xmlstr_t *value, struct entity *entity)
Definition: actctx.c:1830
static NTSTATUS find_clr_surrogate(ACTIVATION_CONTEXT *actctx, const GUID *guid, ACTCTX_SECTION_KEYED_DATA *data)
Definition: actctx.c:5096
static const WCHAR windowsSettings2017NSW[]
Definition: actctx.c:660
static const WCHAR windowsSettings2016NSW[]
Definition: actctx.c:659
static const WCHAR * find_app_settings(ACTIVATION_CONTEXT *actctx, const WCHAR *settings, const WCHAR *ns)
Definition: actctx.c:5444
static void generate_uuid(ULONG *seed, GUID *guid)
Definition: actctx.c:4417
static void free_assembly_identity(struct assembly_identity *ai)
Definition: actctx.c:886
static NTSTATUS find_activatable_class(ACTIVATION_CONTEXT *actctx, const UNICODE_STRING *name, PACTCTX_SECTION_KEYED_DATA data)
Definition: actctx.c:4177
static const WCHAR windowsSettings2019NSW[]
Definition: actctx.c:661
static BOOL xmlstr_cmp(const xmlstr_t *xmlstr, const WCHAR *str)
Definition: actctx.c:721
static void parse_window_class_elem(xmlbuf_t *xmlbuf, struct dll_redirect *dll, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:1951
static NTSTATUS find_progid_redirection(ACTIVATION_CONTEXT *actctx, const UNICODE_STRING *name, PACTCTX_SECTION_KEYED_DATA data)
Definition: actctx.c:5314
static void get_comserver_datalen(const struct entity_array *entities, const struct dll_redirect *dll, unsigned int *count, unsigned int *len, unsigned int *module_len)
Definition: actctx.c:4432
static struct assembly * add_assembly(ACTIVATION_CONTEXT *actctx, enum assembly_type at)
Definition: actctx.c:810
static PCOMPATIBILITY_CONTEXT_ELEMENT add_compat_context(struct assembly *assembly)
Definition: actctx.c:867
static struct guid_index * find_guid_index(const struct guidsection_header *section, const GUID *guid)
Definition: actctx.c:3760
static NTSTATUS build_tlib_section(ACTIVATION_CONTEXT *actctx, struct guidsection_header **section)
Definition: actctx.c:4243
static NTSTATUS build_clr_surrogate_section(ACTIVATION_CONTEXT *actctx, struct guidsection_header **section)
Definition: actctx.c:4980
static const WCHAR windowsSettings2020NSW[]
Definition: actctx.c:662
#define MAX_NAMESPACES
Definition: actctx.c:107
enum tagOLEMISC OLEMISC
static struct dll_redirect * add_dll_redirect(struct assembly *assembly)
Definition: actctx.c:841
static BOOL parse_version(const xmlstr_t *str, struct assembly_version *version)
Definition: actctx.c:1426
static void parse_assembly_identity_elem(xmlbuf_t *xmlbuf, ACTIVATION_CONTEXT *actctx, struct assembly_identity *ai, const struct xml_elem *parent)
Definition: actctx.c:1492
static void parse_unknown_elem(xmlbuf_t *xmlbuf, const struct xml_elem *parent)
Definition: actctx.c:1479
static void parse_clr_class_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2096
static NTSTATUS find_window_class(ACTIVATION_CONTEXT *actctx, const UNICODE_STRING *name, PACTCTX_SECTION_KEYED_DATA data)
Definition: actctx.c:3977
static void parse_compatibility_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2531
static void parse_clr_surrogate_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2165
static void parse_trust_info_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2728
static NTSTATUS find_guid(ACTIVATION_CONTEXT *actctx, ULONG section_kind, const GUID *guid, DWORD flags, PACTCTX_SECTION_KEYED_DATA data)
Definition: actctx.c:5410
static ACTIVATION_CONTEXT * check_actctx(HANDLE h)
Definition: actctx.c:1125
BOOLEAN WINAPI RtlIsActivationContextActive(HANDLE handle)
Definition: actctx.c:5816
static BOOL xml_elem_cmp(const struct xml_elem *elem, const WCHAR *str, const WCHAR *namespace)
Definition: actctx.c:744
static int get_assembly_version(struct assembly *assembly, WCHAR *ret)
Definition: actctx.c:1942
static const char * debugstr_xml_attr(const struct xml_attr *attr)
Definition: actctx.c:776
static void parse_security_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2709
static void parse_dependency_elem(xmlbuf_t *xmlbuf, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2250
static const WCHAR windowsSettings2005NSW[]
Definition: actctx.c:657
static BOOL is_matching_identity(const struct assembly_identity *id1, const struct assembly_identity *id2)
Definition: actctx.c:981
static struct string_index * get_activatable_class_first_index(ACTIVATION_CONTEXT *actctx)
Definition: actctx.c:4043
void actctx_init(void)
Definition: actctx.c:5464
static NTSTATUS lookup_assembly(struct actctx_loader *acl, struct assembly_identity *ai)
Definition: actctx.c:3456
static const WCHAR compatibilityNSW[]
Definition: actctx.c:656
static void get_progid_datalen(struct entity_array *entities, unsigned int *count, unsigned int *total_len)
Definition: actctx.c:5138
static NTSTATUS find_tlib_redirection(ACTIVATION_CONTEXT *actctx, const GUID *guid, ACTCTX_SECTION_KEYED_DATA *data)
Definition: actctx.c:4378
static NTSTATUS find_dll_redirection(ACTIVATION_CONTEXT *actctx, const UNICODE_STRING *name, PACTCTX_SECTION_KEYED_DATA data)
Definition: actctx.c:3785
#define ACTCTX_MAGIC
Definition: actctx.c:60
static enum comclass_threadingmodel parse_com_class_threadingmodel(xmlstr_t *value)
Definition: actctx.c:1536
static void parse_requested_privileges_elem(xmlbuf_t *xmlbuf, struct assembly *assembly, struct actctx_loader *acl, const struct xml_elem *parent)
Definition: actctx.c:2690
static NTSTATUS parse_manifest_buffer(struct actctx_loader *acl, struct assembly *assembly, struct assembly_identity *ai, xmlbuf_t *xmlbuf)
Definition: actctx.c:2873
static BOOL parse_xml_header(xmlbuf_t *xmlbuf)
Definition: actctx.c:1394
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:73
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_ PVOID Context
Definition: storport.h:2269
LIST_ENTRY FrameListCache
Definition: rtltypes.h:968
struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME * ActiveFrame
Definition: rtltypes.h:967
struct strsection_header * dllredirect_section
Definition: actctx.c:621
struct guidsection_header * ifaceps_section
Definition: actctx.c:626
struct guidsection_header * comserver_section
Definition: actctx.c:625
struct strsection_header * wndclass_section
Definition: actctx.c:620
struct file_info appdir
Definition: actctx.c:614
struct strsection_header * progid_section
Definition: actctx.c:622
unsigned int allocated_assemblies
Definition: actctx.c:617
struct assembly * assemblies
Definition: actctx.c:615
struct guidsection_header * tlib_section
Definition: actctx.c:624
struct strsection_header * activatable_class_section
Definition: actctx.c:623
struct guidsection_header * clrsurrogate_section
Definition: actctx.c:627
unsigned int num_assemblies
Definition: actctx.c:616
Definition: pedump.c:458
Definition: pedump.c:414
Definition: btrfs_drv.h:1876
PACTIVATION_CONTEXT EntryPointActivationContext
Definition: ldrtypes.h:167
UNICODE_STRING FullDllName
Definition: btrfs_drv.h:1882
PVOID DllBase
Definition: btrfs_drv.h:1880
Definition: typedefs.h:120
struct _ACTIVATION_CONTEXT * ActivationContext
Definition: winternl.h:324
struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME * Previous
Definition: winternl.h:323
Definition: compat.h:836
PVOID ActivationContextStackPointer
Definition: compat.h:854
unsigned int allocated_dependencies
Definition: actctx.c:635
struct assembly_identity * dependencies
Definition: actctx.c:633
unsigned int num_dependencies
Definition: actctx.c:634
ACTIVATION_CONTEXT * actctx
Definition: actctx.c:632
DWORD threading_model
Definition: roapi.c:39
Definition: undname.c:54
unsigned num
Definition: undname.c:56
WCHAR * name
Definition: actctx.c:153
WCHAR * public_key
Definition: actctx.c:155
WCHAR * language
Definition: actctx.c:156
WCHAR * arch
Definition: actctx.c:154
WCHAR * type
Definition: actctx.c:157
struct assembly_version version
Definition: actctx.c:158
USHORT major
Definition: actctx.c:145
USHORT revision
Definition: actctx.c:148
USHORT build
Definition: actctx.c:147
USHORT minor
Definition: actctx.c:146
WCHAR * directory
Definition: actctx.c:556
BSTR type
Definition: cache.c:326
BOOL no_inherit
Definition: actctx.c:557
struct dll_redirect * dlls
Definition: actctx.c:558
unsigned int allocated_dlls
Definition: actctx.c:560
struct assembly_identity id
Definition: actctx.c:554
unsigned int num_dlls
Definition: actctx.c:559
BSTR name
Definition: cache.c:327
struct file_info manifest
Definition: actctx.c:555
struct entity_array entities
Definition: actctx.c:561
enum assembly_type type
Definition: actctx.c:553
ULONG num_compat_contexts
Definition: actctx.c:563
ULONG ui_access
Definition: actctx.c:565
COMPATIBILITY_CONTEXT_ELEMENT * compat_contexts
Definition: actctx.c:562
ACTCTX_REQUESTED_RUN_LEVEL run_level
Definition: actctx.c:564
Definition: cookie.c:202
WCHAR * value
Definition: cookie.c:204
WCHAR * name
Definition: cookie.c:203
ULONG version_len
Definition: actctx.c:1862
ULONG name_offset
Definition: actctx.c:1863
ULONG version_offset
Definition: actctx.c:1861
DWORD miscstatuscontent
Definition: combase.c:71
DWORD miscstatusdocprint
Definition: combase.c:74
DWORD miscstatusthumbnail
Definition: combase.c:72
Definition: cookie.c:34
WCHAR * load_from
Definition: actctx.c:539
WCHAR * name
Definition: actctx.c:538
WCHAR * hash
Definition: actctx.c:540
struct entity_array entities
Definition: actctx.c:541
unsigned int allocated
Definition: actctx.c:533
unsigned int num
Definition: actctx.c:532
struct entity * base
Definition: actctx.c:531
Definition: actctx.c:468
ULONG nummethods
Definition: actctx.c:502
BOOL versioned
Definition: actctx.c:507
DWORD miscstatusicon
Definition: actctx.c:491
struct entity::@5284::@5285 typelib
WORD flags
Definition: actctx.c:476
WCHAR * version
Definition: actctx.c:486
DWORD miscstatusthumbnail
Definition: actctx.c:490
WCHAR * base
Definition: actctx.c:497
struct entity::@5284::@5291 activatable_class
DWORD mask
Definition: actctx.c:501
WCHAR * helpdir
Definition: actctx.c:475
DWORD miscstatusdocprint
Definition: actctx.c:492
union entity::@5284 u
struct entity::@5284::@5287 ifaceps
WORD minor
Definition: actctx.c:478
struct entity::@5284::@5286 comclass
WCHAR * iid
Definition: actctx.c:496
WCHAR * value
Definition: actctx.c:518
struct entity::@5284::@5289 clrsurrogate
DWORD threading_model
Definition: actctx.c:524
WCHAR * progid
Definition: actctx.c:484
WCHAR * name
Definition: actctx.c:485
struct entity::@5284::@5288 class
DWORD miscstatuscontent
Definition: actctx.c:489
DWORD miscstatus
Definition: actctx.c:488
WORD major
Definition: actctx.c:477
WCHAR * clsid
Definition: actctx.c:482
WCHAR * tlib
Definition: actctx.c:498
DWORD kind
Definition: actctx.c:469
WCHAR * ns
Definition: actctx.c:519
WCHAR * tlbid
Definition: actctx.c:474
DWORD model
Definition: actctx.c:487
WCHAR * ps32
Definition: actctx.c:500
struct entity::@5284::@5290 settings
ULONG type
Definition: actctx.c:139
WCHAR * info
Definition: actctx.c:140
Definition: fci.c:127
GUID guid
Definition: actctx.c:1224
ULONG rosterindex
Definition: actctx.c:1227
ULONG data_offset
Definition: actctx.c:1225
ULONG data_len
Definition: actctx.c:1226
ULONG index_offset
Definition: actctx.c:1216
DWORD unk[3]
Definition: actctx.c:1214
ULONG names_offset
Definition: actctx.c:1218
Definition: _hash_fun.h:40
Definition: copy.c:22
Definition: name.c:39
Definition: mxnamespace.c:38
Definition: actctx.c:665
const WCHAR * name
Definition: actctx.c:666
OLEMISC value
Definition: actctx.c:667
ULONG clsid_offset
Definition: combase.c:93
unsigned int allocated
Definition: actctx.c:464
WCHAR ** progids
Definition: actctx.c:462
unsigned int num
Definition: actctx.c:463
Definition: parser.c:56
Definition: ps.c:97
ULONG data_offset
Definition: actctx.c:1205
ULONG name_len
Definition: actctx.c:1204
ULONG hash
Definition: actctx.c:1202
ULONG name_offset
Definition: actctx.c:1203
ULONG data_len
Definition: actctx.c:1206
ULONG rosterindex
Definition: actctx.c:1207
ULONG name_offset
Definition: oleaut.c:792
ULONG help_len
Definition: oleaut.c:795
ULONG help_offset
Definition: oleaut.c:796
WORD minor_version
Definition: oleaut.c:798
ULONG name_len
Definition: oleaut.c:791
LANGID langid
Definition: oleaut.c:793
WORD major_version
Definition: oleaut.c:797
xmlstr_t value
Definition: actctx.c:125
xmlstr_t name
Definition: actctx.c:124
int ns_pos
Definition: actctx.c:119
xmlstr_t name
Definition: actctx.c:117
xmlstr_t ns
Definition: actctx.c:118
int ns_pos
Definition: actctx.c:133
struct xml_attr namespaces[MAX_NAMESPACES]
Definition: actctx.c:132
BOOL error
Definition: actctx.c:134
const WCHAR * end
Definition: actctx.c:131
const WCHAR * ptr
Definition: actctx.c:130
const WCHAR * ptr
Definition: actctx.c:111
unsigned int len
Definition: actctx.c:112
#define max(a, b)
Definition: svc.c:63
Character const *const prefix
Definition: tempnam.cpp:195
#define str_len
Definition: treelist.c:89
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
HANDLE HMODULE
Definition: typedefs.h:77
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define HIWORD(l)
Definition: typedefs.h:247
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
Definition: pdh_main.c:96
static const WCHAR lang[]
Definition: wbemdisp.c:287
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
#define WINAPI
Definition: msvc.h:6
NTSYSAPI NTSTATUS WINAPI RtlActivateActivationContext(DWORD, HANDLE, ULONG_PTR *)
NTSYSAPI NTSTATUS WINAPI RtlFindActivationContextSectionString(ULONG, const GUID *, ULONG, const UNICODE_STRING *, PVOID)
Definition: actctx.c:6137
NTSYSAPI NTSTATUS WINAPI RtlZombifyActivationContext(HANDLE)
Definition: actctx.c:5676
NTSYSAPI NTSTATUS WINAPI RtlGUIDFromString(PUNICODE_STRING, GUID *)
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T) __WINE_ALLOC_SIZE(4) __WINE_DEALLOC(RtlFreeHeap
NTSYSAPI void WINAPI RtlAddRefActivationContext(HANDLE)
Definition: actctx.c:5653
NTSYSAPI void WINAPI RtlDeactivateActivationContext(DWORD, ULONG_PTR)
NTSYSAPI void WINAPI RtlReleaseActivationContext(HANDLE)
Definition: actctx.c:5664
@ RELATIVE_PATH
Definition: winternl.h:2518
NTSYSAPI NTSTATUS WINAPI RtlCreateActivationContext(HANDLE *, const void *)
NTSYSAPI NTSTATUS WINAPI RtlGetActiveActivationContext(HANDLE *)
Definition: actctx.c:5806
NTSYSAPI NTSTATUS WINAPI RtlQueryInformationActivationContext(ULONG, HANDLE, PVOID, ULONG, PVOID, SIZE_T, SIZE_T *)
Definition: actctx.c:5833
LPCSTR debugstr_us(const UNICODE_STRING *us)
Definition: wine_debug.c:136
#define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_OMITS_ASSEMBLY_ROOT
Definition: winnt_old.h:1125
#define IS_TEXT_UNICODE_REVERSE_SIGNATURE
Definition: winnt_old.h:953
#define ACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_EXPAND
Definition: winnt_old.h:1126
#define IS_TEXT_UNICODE_SIGNATURE
Definition: winnt_old.h:952
#define CREATEPROCESS_MANIFEST_RESOURCE_ID
Definition: winuser.h:626
#define RT_MANIFEST
Definition: winuser.h:625
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define RtlUshortByteSwap(_x)
Definition: rtlfuncs.h:3214
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
unsigned char BYTE
Definition: xxhash.c:193