Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1437 lines
51 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. sxsquery.c
  5. Abstract:
  6. Side-by-side activation support for Windows/NT
  7. Implementation of query functions over activation contexts
  8. Author:
  9. Michael Grier (MGrier) 1/18/2001
  10. Revision History:
  11. 1/18/2001 - MGrier - initial; split off from sxsactctx.c.
  12. 3/15/2001 - xiaoyuw - add support query for Assembly of Actctx and files of Assembly info
  13. 5/2001 - JayKrell - more query support (from hmodule, from address, noaddref)
  14. --*/
  15. #pragma warning(disable:4214) // bit field types other than int
  16. #pragma warning(disable:4201) // nameless struct/union
  17. #pragma warning(disable:4115) // named type definition in parentheses
  18. #pragma warning(disable:4127) // condition expression is constant
  19. #include <ntos.h>
  20. #include <ntrtl.h>
  21. #include <nturtl.h>
  22. #include <sxstypes.h>
  23. #include "sxsp.h"
  24. #include "ldrp.h"
  25. typedef const void *PCVOID;
  26. VOID
  27. RtlpLocateActivationContextSectionForQuery(
  28. OUT PULONG Disposition,
  29. OUT NTSTATUS* Status,
  30. PVOID Buffer,
  31. SIZE_T InLength,
  32. PSIZE_T OutLength OPTIONAL,
  33. SIZE_T MinimumLength,
  34. IN PCACTIVATION_CONTEXT_DATA ActivationContextData,
  35. IN const GUID * ExtensionGuid OPTIONAL,
  36. IN ULONG Id,
  37. OUT VOID CONST ** SectionData,
  38. OUT ULONG * SectionLength
  39. )
  40. {
  41. #define RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_CONTINUE (1)
  42. #define RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_RETURN (2)
  43. ASSERT(Status != NULL);
  44. ASSERT(Disposition != NULL);
  45. if (ActivationContextData != NULL) {
  46. *Status = RtlpLocateActivationContextSection(ActivationContextData, ExtensionGuid, Id, SectionData, SectionLength);
  47. if (*Status != STATUS_SXS_SECTION_NOT_FOUND) {
  48. if (NT_SUCCESS(*Status))
  49. *Disposition = RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_CONTINUE;
  50. else
  51. *Disposition = RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_RETURN;
  52. return;
  53. }
  54. }
  55. *Disposition = RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_RETURN;
  56. if (MinimumLength > InLength) {
  57. *Status = STATUS_BUFFER_TOO_SMALL;
  58. return;
  59. }
  60. RtlZeroMemory(Buffer, MinimumLength);
  61. if (OutLength != NULL)
  62. *OutLength = MinimumLength;
  63. *Status = STATUS_SUCCESS;
  64. }
  65. NTSTATUS
  66. RtlpCrackActivationContextStringSectionHeader(
  67. IN PCVOID SectionBase,
  68. IN SIZE_T SectionLength,
  69. OUT ULONG *FormatVersion OPTIONAL,
  70. OUT ULONG *DataFormatVersion OPTIONAL,
  71. OUT ULONG *SectionFlags OPTIONAL,
  72. OUT ULONG *ElementCount OPTIONAL,
  73. OUT PCACTIVATION_CONTEXT_STRING_SECTION_ENTRY *Elements OPTIONAL,
  74. OUT ULONG *HashAlgorithm OPTIONAL,
  75. OUT PCVOID *SearchStructure OPTIONAL,
  76. OUT ULONG *UserDataLength OPTIONAL,
  77. OUT PCVOID *UserData OPTIONAL
  78. )
  79. {
  80. NTSTATUS Status = STATUS_INTERNAL_ERROR; // in case someone forgets to set it...
  81. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header = (PCACTIVATION_CONTEXT_STRING_SECTION_HEADER) SectionBase;
  82. if (FormatVersion != NULL)
  83. *FormatVersion = 0;
  84. if (DataFormatVersion != NULL)
  85. *DataFormatVersion = 0;
  86. if (SectionFlags != NULL)
  87. *SectionFlags = 0;
  88. if (ElementCount != NULL)
  89. *ElementCount = 0;
  90. if (Elements != NULL)
  91. *Elements = NULL;
  92. if (HashAlgorithm != NULL)
  93. *HashAlgorithm = 0;
  94. if (SearchStructure != NULL)
  95. *SearchStructure = NULL;
  96. if (UserDataLength != NULL)
  97. *UserDataLength = 0;
  98. if (UserData != NULL)
  99. *UserData = NULL;
  100. if (SectionLength < (RTL_SIZEOF_THROUGH_FIELD(ACTIVATION_CONTEXT_STRING_SECTION_HEADER, HeaderSize))) {
  101. DbgPrintEx(
  102. DPFLTR_SXS_ID,
  103. DPFLTR_ERROR_LEVEL,
  104. "SXS: %s() passed string section at %p only %lu bytes long; that's not even enough for the 4-byte magic and 4-byte header length!\n",
  105. __FUNCTION__,
  106. SectionBase,
  107. SectionLength);
  108. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  109. goto Exit;
  110. }
  111. if (Header->Magic != ACTIVATION_CONTEXT_STRING_SECTION_MAGIC) {
  112. DbgPrintEx(
  113. DPFLTR_SXS_ID,
  114. DPFLTR_ERROR_LEVEL,
  115. "SXS: %s() found assembly information section with wrong magic value\n"
  116. " Expected %lu; got %lu\n",
  117. __FUNCTION__,
  118. ACTIVATION_CONTEXT_STRING_SECTION_MAGIC,
  119. Header->Magic);
  120. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  121. goto Exit;
  122. }
  123. // Pedantic: check to see if the header size claimed includes the header size field so that we can safely use it.
  124. if (!RTL_CONTAINS_FIELD(Header, Header->HeaderSize, HeaderSize)) {
  125. DbgPrintEx(
  126. DPFLTR_SXS_ID,
  127. DPFLTR_ERROR_LEVEL,
  128. "SXS: %s() passed string section at %p claims %lu byte header size; that doesn't even include the HeaderSize member!\n",
  129. __FUNCTION__,
  130. Header,
  131. Header->HeaderSize);
  132. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  133. goto Exit;
  134. }
  135. // Now we're just going to jump forward to the last known member that we expect to see; UserDataSize...
  136. if (!RTL_CONTAINS_FIELD(Header, Header->HeaderSize, UserDataSize)) {
  137. DbgPrintEx(
  138. DPFLTR_SXS_ID,
  139. DPFLTR_ERROR_LEVEL,
  140. "SXS: %s() passed string section at %p with too small of a header\n"
  141. " HeaderSize: %lu\n"
  142. " Required: %lu\n",
  143. __FUNCTION__,
  144. Header,
  145. Header->HeaderSize,
  146. RTL_SIZEOF_THROUGH_FIELD(ACTIVATION_CONTEXT_STRING_SECTION_HEADER, UserDataSize));
  147. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  148. goto Exit;
  149. }
  150. if ((Header->ElementListOffset != 0) &&
  151. (Header->ElementListOffset < Header->HeaderSize)) {
  152. DbgPrintEx(
  153. DPFLTR_SXS_ID,
  154. DPFLTR_ERROR_LEVEL,
  155. "SXS: %s() found assembly information section with element list overlapping section header\n"
  156. " Section header: %p\n"
  157. " Header Size: %lu\n"
  158. " ElementListOffset: %lu\n",
  159. __FUNCTION__,
  160. Header,
  161. Header->HeaderSize,
  162. Header->ElementListOffset);
  163. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  164. goto Exit;
  165. }
  166. if ((Header->SearchStructureOffset != 0) &&
  167. (Header->SearchStructureOffset < Header->HeaderSize)) {
  168. DbgPrintEx(
  169. DPFLTR_SXS_ID,
  170. DPFLTR_ERROR_LEVEL,
  171. "SXS: %s() found assembly information section with search structure overlapping section header\n"
  172. " Section header: %p\n"
  173. " Header Size: %lu\n"
  174. " SearchStructureOffset: %lu\n",
  175. __FUNCTION__,
  176. Header,
  177. Header->HeaderSize,
  178. Header->SearchStructureOffset);
  179. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  180. goto Exit;
  181. }
  182. if ((Header->UserDataOffset != 0) &&
  183. (Header->UserDataOffset < Header->HeaderSize)) {
  184. DbgPrintEx(
  185. DPFLTR_SXS_ID,
  186. DPFLTR_ERROR_LEVEL,
  187. "SXS: %s() found assembly information section with user data overlapping section header\n"
  188. " Section header: %p\n"
  189. " Header Size: %lu\n"
  190. " User Data Offset: %lu\n",
  191. __FUNCTION__,
  192. Header,
  193. Header->HeaderSize,
  194. Header->UserDataOffset);
  195. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  196. goto Exit;
  197. }
  198. if (Header->UserDataSize < sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION)) {
  199. DbgPrintEx(
  200. DPFLTR_SXS_ID,
  201. DPFLTR_ERROR_LEVEL,
  202. "SXS: %s() found assembly information section with user data too small\n"
  203. " Section header: %p\n"
  204. " UserDataSize: %lu; needed: %lu\n",
  205. __FUNCTION__,
  206. Header,
  207. Header->UserDataSize, sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION));
  208. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  209. goto Exit;
  210. }
  211. if ((Header->UserDataOffset + Header->UserDataSize) > SectionLength) {
  212. DbgPrintEx(
  213. DPFLTR_SXS_ID,
  214. DPFLTR_ERROR_LEVEL,
  215. "SXS: %s() found assembly information section with user data extending beyond section data\n"
  216. " Section header: %p\n"
  217. " UserDataSize: %lu\n"
  218. " UserDataOffset: %lu\n"
  219. " Section size: %lu\n",
  220. __FUNCTION__,
  221. Header,
  222. Header->UserDataSize,
  223. Header->UserDataOffset,
  224. SectionLength);
  225. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  226. goto Exit;
  227. }
  228. if (FormatVersion != NULL)
  229. *FormatVersion = Header->FormatVersion;
  230. if (DataFormatVersion != NULL)
  231. *DataFormatVersion = Header->DataFormatVersion;
  232. if (SectionFlags != NULL)
  233. *SectionFlags = Header->Flags;
  234. if (ElementCount != NULL)
  235. *ElementCount = Header->ElementCount;
  236. if (Elements != NULL) {
  237. if (Header->ElementListOffset == 0)
  238. *Elements = NULL;
  239. else
  240. *Elements = (PCACTIVATION_CONTEXT_STRING_SECTION_ENTRY) (((ULONG_PTR) Header) + Header->ElementListOffset);
  241. }
  242. if (HashAlgorithm != NULL)
  243. *HashAlgorithm = Header->HashAlgorithm;
  244. if (SearchStructure != NULL) {
  245. if (Header->SearchStructureOffset == 0)
  246. *SearchStructure = NULL;
  247. else
  248. *SearchStructure = (PCVOID) (((ULONG_PTR) Header) + Header->SearchStructureOffset);
  249. }
  250. if (UserDataLength != NULL)
  251. *UserDataLength = Header->UserDataSize;
  252. if (UserData != NULL) {
  253. if (Header->UserDataOffset == 0)
  254. *UserData = NULL;
  255. else
  256. *UserData = (PCVOID) (((ULONG_PTR) Header) + Header->UserDataOffset);
  257. }
  258. Status = STATUS_SUCCESS;
  259. Exit:
  260. return Status;
  261. }
  262. NTSTATUS
  263. RtlpGetActiveActivationContextApplicationDirectory(
  264. IN SIZE_T InLength,
  265. OUT PVOID OutBuffer,
  266. OUT SIZE_T *OutLength
  267. )
  268. // This is never used.
  269. {
  270. NTSTATUS Status = STATUS_INTERNAL_ERROR;
  271. PCRTL_ACTIVATION_CONTEXT_STACK_FRAME Frame = NULL;
  272. PCACTIVATION_CONTEXT_DATA ActivationContextData = NULL;
  273. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER Header = NULL;
  274. const PPEB Peb = NtCurrentPeb();
  275. const PTEB Teb = NtCurrentTeb();
  276. PVOID pvTemp = NULL;
  277. ULONG ulTemp = 0;
  278. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION GlobalInfo = NULL;
  279. if (OutLength != NULL)
  280. *OutLength = 0;
  281. if (((InLength != 0) && (OutBuffer == NULL)) ||
  282. ((OutBuffer == NULL) && (OutLength == NULL))) {
  283. DbgPrintEx(
  284. DPFLTR_SXS_ID,
  285. DPFLTR_ERROR_LEVEL,
  286. "SXS: %s(): called with invalid parameters\n"
  287. " InLength = %Iu\n"
  288. " OutBuffer = %p\n"
  289. " OutLength = %p\n",
  290. __FUNCTION__,
  291. InLength,
  292. OutBuffer,
  293. OutLength);
  294. Status = STATUS_INVALID_PARAMETER;
  295. goto Exit;
  296. }
  297. Frame = (PCRTL_ACTIVATION_CONTEXT_STACK_FRAME) Teb->ActivationContextStack.ActiveFrame;
  298. if (Frame == NULL) {
  299. ActivationContextData = (PCACTIVATION_CONTEXT_DATA) Peb->ActivationContextData;
  300. } else {
  301. ActivationContextData = Frame->ActivationContext->ActivationContextData;
  302. }
  303. // We need to find the assembly metadata section...
  304. Status = RtlpLocateActivationContextSection(ActivationContextData, NULL, ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION, &pvTemp, &ulTemp);
  305. if (!NT_SUCCESS(Status))
  306. goto Exit;
  307. if (ulTemp < sizeof(ACTIVATION_CONTEXT_STRING_SECTION_HEADER)) {
  308. DbgPrintEx(
  309. DPFLTR_SXS_ID,
  310. DPFLTR_ERROR_LEVEL,
  311. "SXS: %s() found assembly information string section with header too small\n"
  312. " Expected at least %lu; got %lu bytes\n",
  313. __FUNCTION__,
  314. sizeof(ACTIVATION_CONTEXT_STRING_SECTION_HEADER),
  315. ulTemp);
  316. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  317. goto Exit;
  318. }
  319. Header = (PCACTIVATION_CONTEXT_STRING_SECTION_HEADER) pvTemp;
  320. if (Header->Magic != ACTIVATION_CONTEXT_STRING_SECTION_MAGIC) {
  321. DbgPrintEx(
  322. DPFLTR_SXS_ID,
  323. DPFLTR_ERROR_LEVEL,
  324. "SXS: %s() found assembly information section with wrong magic value\n"
  325. " Expected %lu; got %lu\n",
  326. __FUNCTION__,
  327. ACTIVATION_CONTEXT_STRING_SECTION_MAGIC,
  328. Header->Magic);
  329. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  330. goto Exit;
  331. }
  332. if (Header->UserDataOffset < sizeof(ACTIVATION_CONTEXT_STRING_SECTION_HEADER)) {
  333. DbgPrintEx(
  334. DPFLTR_SXS_ID,
  335. DPFLTR_ERROR_LEVEL,
  336. "SXS: %s() found assembly information section with user data overlapping section header\n"
  337. " Section header: %p\n"
  338. " User Data Offset: %lu\n",
  339. __FUNCTION__,
  340. Header,
  341. Header->UserDataOffset);
  342. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  343. goto Exit;
  344. }
  345. if (Header->UserDataSize < sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION)) {
  346. DbgPrintEx(
  347. DPFLTR_SXS_ID,
  348. DPFLTR_ERROR_LEVEL,
  349. "SXS: %s() found assembly information section with user data too small\n"
  350. " Section header: %p\n"
  351. " UserDataSize: %lu; needed: %lu\n",
  352. __FUNCTION__,
  353. Header,
  354. Header->UserDataSize, sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION));
  355. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  356. goto Exit;
  357. }
  358. if ((Header->UserDataOffset + Header->UserDataSize) > ulTemp) {
  359. DbgPrintEx(
  360. DPFLTR_SXS_ID,
  361. DPFLTR_ERROR_LEVEL,
  362. "SXS: %s() found assembly information section with user data extending beyond section data\n"
  363. " Section header: %p\n"
  364. " UserDataSize: %lu\n"
  365. " UserDataOffset: %lu\n"
  366. " Section size: %lu\n",
  367. __FUNCTION__,
  368. Header,
  369. Header->UserDataSize,
  370. Header->UserDataOffset,
  371. ulTemp);
  372. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  373. goto Exit;
  374. }
  375. GlobalInfo = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION) (((ULONG_PTR) Header) + Header->UserDataOffset);
  376. if (GlobalInfo->Size < sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION)) {
  377. DbgPrintEx(
  378. DPFLTR_SXS_ID,
  379. DPFLTR_ERROR_LEVEL,
  380. "SXS: %s() found assembly information section global data with size less than structure size\n"
  381. " Section header: %p\n"
  382. " Global Info: %p\n"
  383. " Global Info Size: %lu\n"
  384. " Structure size: %lu\n",
  385. __FUNCTION__,
  386. Header,
  387. GlobalInfo,
  388. GlobalInfo->Size,
  389. sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION));
  390. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  391. goto Exit;
  392. }
  393. if (GlobalInfo->ApplicationDirectoryOffset != 0) {
  394. if (GlobalInfo->ApplicationDirectoryOffset < sizeof(ACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION)) {
  395. DbgPrintEx(
  396. DPFLTR_SXS_ID,
  397. DPFLTR_ERROR_LEVEL,
  398. "SXS: %s() found assembly information section global data with app dir offset within base structure\n"
  399. " Section header: %p\n"
  400. " GlobalInfo: %p\n"
  401. " ApplicationDirectoryOffset: %lu\n",
  402. __FUNCTION__,
  403. Header,
  404. GlobalInfo,
  405. GlobalInfo->ApplicationDirectoryOffset);
  406. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  407. goto Exit;
  408. }
  409. if ((GlobalInfo->ApplicationDirectoryOffset + GlobalInfo->ApplicationDirectoryLength) > GlobalInfo->Size) {
  410. DbgPrintEx(
  411. DPFLTR_SXS_ID,
  412. DPFLTR_ERROR_LEVEL,
  413. "SXS: %s() found assembly information section global data with app dir extending beyond end of global data\n"
  414. " Section header: %p\n"
  415. " GlobalInfo: %p\n"
  416. " ApplicationDirectoryOffset: %lu\n"
  417. " ApplicationDirectoryLength: %lu\n"
  418. " GlobalInfo size: %lu\n",
  419. __FUNCTION__,
  420. Header,
  421. GlobalInfo,
  422. GlobalInfo->ApplicationDirectoryOffset,
  423. GlobalInfo->ApplicationDirectoryLength,
  424. GlobalInfo->Size);
  425. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  426. goto Exit;
  427. }
  428. if (InLength < GlobalInfo->ApplicationDirectoryLength) {
  429. if (OutLength != NULL)
  430. *OutLength = GlobalInfo->ApplicationDirectoryLength;
  431. Status = STATUS_BUFFER_TOO_SMALL;
  432. goto Exit;
  433. }
  434. RtlCopyMemory(
  435. OutBuffer,
  436. (PVOID) (((ULONG_PTR) GlobalInfo) + GlobalInfo->ApplicationDirectoryOffset),
  437. GlobalInfo->ApplicationDirectoryLength);
  438. if (OutLength != NULL)
  439. *OutLength = GlobalInfo->ApplicationDirectoryLength;
  440. } else {
  441. // Hmm... there's just no application directory
  442. if (OutLength != NULL)
  443. *OutLength = 0; // I think we already did this but what the heck
  444. }
  445. Status = STATUS_SUCCESS;
  446. Exit:
  447. return Status;
  448. }
  449. #define \
  450. RTLP_QUERY_INFORMATION_ACTIVATION_CONTEXT_BASIC_INFORMATION_FLAG_NO_ADDREF (0x00000001)
  451. NTSTATUS
  452. RtlpQueryInformationActivationContextBasicInformation(
  453. IN ULONG Flags,
  454. IN PCACTIVATION_CONTEXT ConstActivationContext,
  455. IN PCACTIVATION_CONTEXT_DATA ActivationContextData,
  456. IN ULONG SubInstanceIndex,
  457. OUT PVOID Buffer,
  458. IN SIZE_T InLength,
  459. OUT PSIZE_T OutLength OPTIONAL
  460. )
  461. {
  462. NTSTATUS Status = STATUS_INTERNAL_ERROR;
  463. PACTIVATION_CONTEXT ActivationContext = RTL_CONST_CAST(PACTIVATION_CONTEXT)(ConstActivationContext);
  464. PACTIVATION_CONTEXT_BASIC_INFORMATION Info = (PACTIVATION_CONTEXT_BASIC_INFORMATION) Buffer;
  465. if (OutLength != NULL)
  466. *OutLength = 0;
  467. if (SubInstanceIndex != 0) {
  468. DbgPrintEx(
  469. DPFLTR_SXS_ID,
  470. DPFLTR_ERROR_LEVEL,
  471. "SXS: %s() received invalid non-zero sub-instance index %lu\n",
  472. __FUNCTION__,
  473. SubInstanceIndex);
  474. Status = STATUS_INVALID_PARAMETER;
  475. goto Exit;
  476. }
  477. if (InLength < sizeof(ACTIVATION_CONTEXT_BASIC_INFORMATION)) {
  478. if (OutLength != NULL) {
  479. *OutLength = sizeof(ACTIVATION_CONTEXT_BASIC_INFORMATION);
  480. }
  481. Status = STATUS_BUFFER_TOO_SMALL;
  482. goto Exit;
  483. }
  484. if (ActivationContextData != NULL)
  485. Info->Flags = ActivationContextData->Flags;
  486. else
  487. Info->Flags = 0;
  488. if ((Flags & RTLP_QUERY_INFORMATION_ACTIVATION_CONTEXT_BASIC_INFORMATION_FLAG_NO_ADDREF) == 0) {
  489. RtlAddRefActivationContext(ActivationContext);
  490. }
  491. Info->ActivationContext = ActivationContext;
  492. if (OutLength != NULL)
  493. *OutLength = sizeof(ACTIVATION_CONTEXT_BASIC_INFORMATION);
  494. Status = STATUS_SUCCESS;
  495. Exit:
  496. return Status;
  497. }
  498. NTSTATUS
  499. RtlpQueryInformationActivationContextDetailedInformation(
  500. PCACTIVATION_CONTEXT_DATA ActivationContextData,
  501. ULONG SubInstanceIndex,
  502. OUT PVOID Buffer,
  503. IN SIZE_T InLength,
  504. OUT PSIZE_T OutLength OPTIONAL
  505. )
  506. {
  507. NTSTATUS Status = STATUS_INTERNAL_ERROR;
  508. PACTIVATION_CONTEXT_DETAILED_INFORMATION Info = (PACTIVATION_CONTEXT_DETAILED_INFORMATION) Buffer;
  509. SIZE_T BytesNeeded = 0;
  510. PCVOID StringSectionHeader;
  511. ULONG StringSectionSize;
  512. ULONG DataFormatVersion;
  513. PCVOID UserData;
  514. ULONG UserDataSize;
  515. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER AssemblyRosterHeader = NULL;
  516. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY AssemblyRosterEntryList = NULL;
  517. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION RootAssemblyInformation = NULL;
  518. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION AssemblyGlobalInformation = NULL;
  519. ULONG i;
  520. ULONG EntryCount;
  521. PWSTR Cursor = NULL;
  522. ULONG RtlpLocateActivationContextSectionForQueryDisposition = 0;
  523. if (OutLength != NULL)
  524. *OutLength = 0;
  525. if (SubInstanceIndex != 0) {
  526. DbgPrintEx(
  527. DPFLTR_SXS_ID,
  528. DPFLTR_ERROR_LEVEL,
  529. "SXS: %s() received invalid non-zero sub-instance index %lu\n",
  530. __FUNCTION__,
  531. SubInstanceIndex);
  532. Status = STATUS_INVALID_PARAMETER;
  533. goto Exit;
  534. }
  535. // We can't actually do the easy check of InLength against the structure size; we have to figure out the
  536. // total bytes we need to include all the paths, etc.
  537. // We need to find the assembly metadata section...
  538. RtlpLocateActivationContextSectionForQuery(
  539. &RtlpLocateActivationContextSectionForQueryDisposition,
  540. &Status,
  541. Buffer,
  542. InLength,
  543. OutLength,
  544. sizeof(*Info),
  545. ActivationContextData,
  546. NULL,
  547. ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION,
  548. &StringSectionHeader,
  549. &StringSectionSize
  550. );
  551. switch (RtlpLocateActivationContextSectionForQueryDisposition) {
  552. case RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_RETURN:
  553. goto Exit;
  554. case RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_CONTINUE:
  555. break;
  556. }
  557. Status = RtlpCrackActivationContextStringSectionHeader(
  558. StringSectionHeader,
  559. StringSectionSize,
  560. NULL,
  561. &DataFormatVersion,
  562. NULL,
  563. NULL,
  564. NULL,
  565. NULL,
  566. NULL,
  567. &UserDataSize,
  568. &UserData);
  569. if (!NT_SUCCESS(Status))
  570. goto Exit;
  571. AssemblyRosterHeader = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER) (((ULONG_PTR) ActivationContextData) + ActivationContextData->AssemblyRosterOffset);
  572. AssemblyRosterEntryList = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY) (((ULONG_PTR) ActivationContextData) + AssemblyRosterHeader->FirstEntryOffset);
  573. EntryCount = AssemblyRosterHeader->EntryCount;
  574. // 1-based counting for Asseblies in the actctx
  575. for (i=1; i<EntryCount; i++) {
  576. if (AssemblyRosterEntryList[i].Flags & ACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY_ROOT)
  577. break;
  578. }
  579. if (i == EntryCount) {
  580. DbgPrintEx(
  581. DPFLTR_SXS_ID,
  582. DPFLTR_ERROR_LEVEL,
  583. "SXS: %s() found activation context data at %p with assembly roster that has no root\n",
  584. __FUNCTION__,
  585. ActivationContextData);
  586. Status = STATUS_SXS_INVALID_ACTCTXDATA_FORMAT;
  587. goto Exit;
  588. }
  589. RootAssemblyInformation = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION) (((ULONG_PTR) ActivationContextData) + AssemblyRosterEntryList[i].AssemblyInformationOffset);
  590. AssemblyGlobalInformation = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_GLOBAL_INFORMATION) UserData;
  591. // Ok, we have everything we could need. Figure out the size of the buffer required.
  592. BytesNeeded = sizeof(ACTIVATION_CONTEXT_DETAILED_INFORMATION);
  593. if (RootAssemblyInformation->ManifestPathLength != 0)
  594. BytesNeeded += (RootAssemblyInformation->ManifestPathLength + sizeof(WCHAR));
  595. if (RootAssemblyInformation->PolicyPathLength != 0)
  596. BytesNeeded += (RootAssemblyInformation->PolicyPathLength + sizeof(WCHAR));
  597. if (AssemblyGlobalInformation->ApplicationDirectoryLength != 0)
  598. BytesNeeded += (AssemblyGlobalInformation->ApplicationDirectoryLength + sizeof(WCHAR));
  599. if (BytesNeeded > InLength) {
  600. if (OutLength != NULL)
  601. *OutLength = BytesNeeded;
  602. Status = STATUS_BUFFER_TOO_SMALL;
  603. goto Exit;
  604. }
  605. // Wow, it's all there and ready to go. Let's fill in!
  606. Cursor = (PWSTR) (Info + 1);
  607. Info->dwFlags = ActivationContextData->Flags;
  608. Info->ulFormatVersion = ActivationContextData->FormatVersion;
  609. Info->ulAssemblyCount = AssemblyRosterHeader->EntryCount - 1;
  610. Info->ulRootManifestPathType = RootAssemblyInformation->ManifestPathType;
  611. Info->ulRootManifestPathChars = (RootAssemblyInformation->ManifestPathLength / sizeof(WCHAR));
  612. Info->lpRootManifestPath = NULL;
  613. Info->ulRootConfigurationPathType = RootAssemblyInformation->PolicyPathType;
  614. Info->ulRootConfigurationPathChars = (RootAssemblyInformation->PolicyPathLength / sizeof(WCHAR));
  615. Info->lpRootConfigurationPath = NULL;
  616. Info->ulAppDirPathType = AssemblyGlobalInformation->ApplicationDirectoryPathType;
  617. Info->ulAppDirPathChars = (AssemblyGlobalInformation->ApplicationDirectoryLength / sizeof(WCHAR));
  618. Info->lpAppDirPath = NULL;
  619. // And copy the strings...
  620. if (RootAssemblyInformation->ManifestPathLength != 0) {
  621. RtlCopyMemory(
  622. Cursor,
  623. (PVOID) (((ULONG_PTR) StringSectionHeader) + RootAssemblyInformation->ManifestPathOffset),
  624. RootAssemblyInformation->ManifestPathLength);
  625. Info->lpRootManifestPath = Cursor;
  626. Cursor = (PWSTR) (((ULONG_PTR) Cursor) + RootAssemblyInformation->ManifestPathLength);
  627. *Cursor++ = L'\0';
  628. }
  629. if (RootAssemblyInformation->PolicyPathLength != 0) {
  630. RtlCopyMemory(
  631. Cursor,
  632. (PVOID) (((ULONG_PTR) StringSectionHeader) + RootAssemblyInformation->PolicyPathOffset),
  633. RootAssemblyInformation->PolicyPathLength);
  634. Info->lpRootConfigurationPath = Cursor;
  635. Cursor = (PWSTR) (((ULONG_PTR) Cursor) + RootAssemblyInformation->PolicyPathLength);
  636. *Cursor++ = L'\0';
  637. }
  638. if (AssemblyGlobalInformation->ApplicationDirectoryLength != 0) {
  639. RtlCopyMemory(
  640. Cursor,
  641. (PVOID) (((ULONG_PTR) AssemblyGlobalInformation) + AssemblyGlobalInformation->ApplicationDirectoryOffset),
  642. AssemblyGlobalInformation->ApplicationDirectoryLength);
  643. Info->lpAppDirPath = Cursor;
  644. Cursor = (PWSTR) (((ULONG_PTR) Cursor) + AssemblyGlobalInformation->ApplicationDirectoryLength);
  645. *Cursor++ = L'\0';
  646. }
  647. ASSERT((((ULONG_PTR) Cursor) - ((ULONG_PTR) Info)) == BytesNeeded);
  648. if (OutLength != NULL)
  649. *OutLength = BytesNeeded;
  650. Status = STATUS_SUCCESS;
  651. Exit:
  652. return Status;
  653. }
  654. NTSTATUS
  655. RtlpQueryAssemblyInformationActivationContextDetailedInformation(
  656. PCACTIVATION_CONTEXT_DATA ActivationContextData,
  657. ULONG SubInstanceIndex, // 0-based index of assembly
  658. OUT PVOID Buffer,
  659. IN SIZE_T InLength,
  660. OUT PSIZE_T OutLength OPTIONAL
  661. )
  662. {
  663. NTSTATUS Status = STATUS_INTERNAL_ERROR;
  664. SIZE_T BytesNeeded = 0;
  665. PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION Info= (PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION)Buffer;
  666. PCVOID StringSectionHeader;
  667. ULONG StringSectionSize;
  668. PWSTR Cursor = NULL;
  669. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER AssemblyRosterHeader = NULL;
  670. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY AssemblyRosterEntryList = NULL;
  671. PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION AssemlbyDataInfo = NULL;
  672. ULONG RtlpLocateActivationContextSectionForQueryDisposition = 0;
  673. if (OutLength != NULL)
  674. *OutLength = 0;
  675. // We can't actually do the easy check of InLength against the structure size; we have to figure out the
  676. // total bytes we need to include all the paths, etc.
  677. AssemblyRosterHeader = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER) (((ULONG_PTR) ActivationContextData) + ActivationContextData->AssemblyRosterOffset);
  678. AssemblyRosterEntryList = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY) (((ULONG_PTR) ActivationContextData) + AssemblyRosterHeader->FirstEntryOffset);
  679. if (SubInstanceIndex > AssemblyRosterHeader->EntryCount) // AssemblyRosterHeader->EntryCount is 1-based,
  680. {
  681. DbgPrintEx(
  682. DPFLTR_SXS_ID,
  683. DPFLTR_ERROR_LEVEL,
  684. "SXS: %s() received invalid sub-instance index %lu out of %lu Assemblies in the Acitvation Context\n",
  685. __FUNCTION__,
  686. SubInstanceIndex,
  687. AssemblyRosterHeader->EntryCount
  688. );
  689. Status = STATUS_INVALID_PARAMETER;
  690. goto Exit;
  691. }
  692. AssemlbyDataInfo = (PACTIVATION_CONTEXT_DATA_ASSEMBLY_INFORMATION)((ULONG_PTR)ActivationContextData + AssemblyRosterEntryList[SubInstanceIndex].AssemblyInformationOffset);
  693. // We need to find the assembly metadata section...
  694. RtlpLocateActivationContextSectionForQuery(
  695. &RtlpLocateActivationContextSectionForQueryDisposition,
  696. &Status,
  697. Buffer,
  698. InLength,
  699. OutLength,
  700. sizeof(ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION),
  701. ActivationContextData,
  702. NULL,
  703. ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION,
  704. &StringSectionHeader,
  705. &StringSectionSize
  706. );
  707. switch (RtlpLocateActivationContextSectionForQueryDisposition) {
  708. case RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_RETURN:
  709. goto Exit;
  710. case RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_CONTINUE:
  711. break;
  712. }
  713. // Figure out the size of the buffer required.
  714. BytesNeeded = sizeof(ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION);
  715. if (AssemlbyDataInfo->EncodedAssemblyIdentityLength != 0 )
  716. BytesNeeded += (AssemlbyDataInfo->EncodedAssemblyIdentityLength + sizeof(WCHAR));
  717. if (AssemlbyDataInfo->ManifestPathLength != 0 )
  718. BytesNeeded += (AssemlbyDataInfo->ManifestPathLength + sizeof(WCHAR));
  719. if (AssemlbyDataInfo->PolicyPathLength != 0 )
  720. BytesNeeded += (AssemlbyDataInfo->PolicyPathLength + sizeof(WCHAR));
  721. if (AssemlbyDataInfo->AssemblyDirectoryNameLength != 0 )
  722. BytesNeeded += (AssemlbyDataInfo->AssemblyDirectoryNameLength + sizeof(WCHAR));
  723. if (BytesNeeded > InLength) {
  724. if (OutLength != NULL)
  725. *OutLength = BytesNeeded;
  726. Status = STATUS_BUFFER_TOO_SMALL;
  727. goto Exit;
  728. }
  729. // fill in the struct
  730. Cursor = (PWSTR) (Info + 1);
  731. Info->ulFlags = AssemlbyDataInfo->Flags;
  732. Info->ulEncodedAssemblyIdentityLength = AssemlbyDataInfo->EncodedAssemblyIdentityLength;
  733. Info->ulManifestPathType = AssemlbyDataInfo->ManifestPathType;
  734. Info->ulManifestPathLength = AssemlbyDataInfo->ManifestPathLength ;
  735. Info->liManifestLastWriteTime = AssemlbyDataInfo->ManifestLastWriteTime;
  736. Info->ulPolicyPathType = AssemlbyDataInfo->PolicyPathType;
  737. Info->ulPolicyPathLength = AssemlbyDataInfo->PolicyPathLength;
  738. Info->liPolicyLastWriteTime = AssemlbyDataInfo->PolicyLastWriteTime;
  739. Info->ulMetadataSatelliteRosterIndex = AssemlbyDataInfo->MetadataSatelliteRosterIndex;
  740. Info->ulManifestVersionMajor = AssemlbyDataInfo->ManifestVersionMajor;
  741. Info->ulManifestVersionMinor = AssemlbyDataInfo->ManifestVersionMinor;
  742. Info->ulPolicyVersionMajor = AssemlbyDataInfo->PolicyVersionMajor;
  743. Info->ulPolicyVersionMinor = AssemlbyDataInfo->PolicyVersionMinor;
  744. Info->ulAssemblyDirectoryNameLength = AssemlbyDataInfo->AssemblyDirectoryNameLength; // in bytes
  745. Info->lpAssemblyEncodedAssemblyIdentity = NULL;
  746. Info->lpAssemblyManifestPath = NULL;
  747. Info->lpAssemblyPolicyPath = NULL;
  748. Info->lpAssemblyDirectoryName = NULL;
  749. Info->ulFileCount = AssemlbyDataInfo->NumOfFilesInAssembly;
  750. if (AssemlbyDataInfo->EncodedAssemblyIdentityLength != 0) {
  751. RtlCopyMemory(
  752. Cursor,
  753. (PVOID) (((ULONG_PTR) StringSectionHeader) + AssemlbyDataInfo->EncodedAssemblyIdentityOffset),
  754. AssemlbyDataInfo->EncodedAssemblyIdentityLength);
  755. Info->lpAssemblyEncodedAssemblyIdentity = Cursor;
  756. Cursor = (PWSTR) (((ULONG_PTR) Cursor) + AssemlbyDataInfo->EncodedAssemblyIdentityLength);
  757. *Cursor++ = L'\0';
  758. }
  759. if (AssemlbyDataInfo->ManifestPathLength != 0) {
  760. RtlCopyMemory(
  761. Cursor,
  762. (PVOID) (((ULONG_PTR) StringSectionHeader) + AssemlbyDataInfo->ManifestPathOffset),
  763. AssemlbyDataInfo->ManifestPathLength);
  764. Info->lpAssemblyManifestPath = Cursor;
  765. Cursor = (PWSTR) (((ULONG_PTR) Cursor) + AssemlbyDataInfo->ManifestPathLength);
  766. *Cursor++ = L'\0';
  767. }
  768. if (AssemlbyDataInfo->PolicyPathLength != 0) {
  769. RtlCopyMemory(
  770. Cursor,
  771. (PVOID) (((ULONG_PTR) StringSectionHeader) + AssemlbyDataInfo->PolicyPathOffset),
  772. AssemlbyDataInfo->PolicyPathLength);
  773. Info->lpAssemblyPolicyPath = Cursor;
  774. Cursor = (PWSTR) (((ULONG_PTR) Cursor) + AssemlbyDataInfo->PolicyPathLength);
  775. *Cursor++ = L'\0';
  776. }
  777. if (AssemlbyDataInfo->AssemblyDirectoryNameLength != 0) {
  778. RtlCopyMemory(
  779. Cursor,
  780. (PVOID) (((ULONG_PTR) StringSectionHeader) + AssemlbyDataInfo->AssemblyDirectoryNameOffset),
  781. AssemlbyDataInfo->AssemblyDirectoryNameLength);
  782. Info->lpAssemblyDirectoryName = Cursor;
  783. Cursor = (PWSTR) (((ULONG_PTR) Cursor) + AssemlbyDataInfo->AssemblyDirectoryNameLength);
  784. *Cursor++ = L'\0';
  785. }
  786. ASSERT((((ULONG_PTR) Cursor) - ((ULONG_PTR) Info)) == BytesNeeded);
  787. if (OutLength != NULL)
  788. *OutLength = BytesNeeded;
  789. Status = STATUS_SUCCESS;
  790. Exit:
  791. return Status;
  792. }
  793. NTSTATUS
  794. RtlpQueryFilesInAssemblyInformationActivationContextDetailedInformation(
  795. PCACTIVATION_CONTEXT_DATA ActivationContextData,
  796. PCACTIVATION_CONTEXT_QUERY_INDEX SubInstanceIndex,
  797. OUT PVOID Buffer,
  798. IN SIZE_T InLength,
  799. OUT PSIZE_T OutLength OPTIONAL
  800. )
  801. {
  802. NTSTATUS Status = STATUS_INTERNAL_ERROR;
  803. SIZE_T BytesNeeded = 0;
  804. PASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION Info= (PASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION)Buffer;
  805. PCACTIVATION_CONTEXT_STRING_SECTION_HEADER StringSectionHeader=NULL;
  806. ULONG StringSectionSize;
  807. PWSTR Cursor = NULL;
  808. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER AssemblyRosterHeader = NULL;
  809. PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY AssemblyRosterEntryList = NULL;
  810. PCACTIVATION_CONTEXT_STRING_SECTION_ENTRY ElementList = NULL;
  811. PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION EntryData = NULL;
  812. ULONG i, CounterForFilesFoundInSpecifiedAssembly;
  813. PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT PathSegments = NULL;
  814. ULONG RtlpLocateActivationContextSectionForQueryDisposition = 0;
  815. if (OutLength != NULL)
  816. *OutLength = 0;
  817. // We can't actually do the easy check of InLength against the structure size; we have to figure out the
  818. // total bytes we need to include all the paths, etc.
  819. AssemblyRosterHeader = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER) (((ULONG_PTR) ActivationContextData) + ActivationContextData->AssemblyRosterOffset);
  820. AssemblyRosterEntryList = (PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_ENTRY) (((ULONG_PTR) ActivationContextData) + AssemblyRosterHeader->FirstEntryOffset);
  821. if (SubInstanceIndex->ulAssemblyIndex >= AssemblyRosterHeader->EntryCount - 1)// AssemblyRosterHeader->EntryCount is 1-based,
  822. {
  823. DbgPrintEx(
  824. DPFLTR_SXS_ID,
  825. DPFLTR_ERROR_LEVEL,
  826. "SXS: %s() received invalid sub-instance index %lu out of %lu Assemblies in the Acitvation Context\n",
  827. __FUNCTION__,
  828. SubInstanceIndex->ulAssemblyIndex,
  829. AssemblyRosterHeader->EntryCount
  830. );
  831. Status = STATUS_INVALID_PARAMETER;
  832. goto Exit;
  833. }
  834. // We need to find the assembly metadata section...
  835. RtlpLocateActivationContextSectionForQuery(
  836. &RtlpLocateActivationContextSectionForQueryDisposition,
  837. &Status,
  838. Buffer,
  839. InLength,
  840. OutLength,
  841. sizeof(ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION),
  842. ActivationContextData,
  843. NULL,
  844. ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
  845. &StringSectionHeader,
  846. &StringSectionSize
  847. );
  848. switch (RtlpLocateActivationContextSectionForQueryDisposition) {
  849. case RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_RETURN:
  850. goto Exit;
  851. case RTLP_LOCATE_ACTIVATION_CONTEXT_SECTION_FOR_QUERY_CONTINUE:
  852. break;
  853. }
  854. if (SubInstanceIndex->ulFileIndexInAssembly >= StringSectionHeader->ElementCount)
  855. {
  856. DbgPrintEx(
  857. DPFLTR_SXS_ID,
  858. DPFLTR_ERROR_LEVEL,
  859. "SXS: %s() received invalid file index (%d) in Assembly (%d)\n",
  860. __FUNCTION__,
  861. SubInstanceIndex->ulFileIndexInAssembly,
  862. SubInstanceIndex->ulAssemblyIndex,
  863. StringSectionHeader->ElementCount
  864. );
  865. Status = STATUS_INVALID_PARAMETER;
  866. goto Exit;
  867. }
  868. if (StringSectionHeader->ElementListOffset != 0)
  869. ElementList = (PCACTIVATION_CONTEXT_STRING_SECTION_ENTRY)(((ULONG_PTR)StringSectionHeader) + StringSectionHeader->ElementListOffset);
  870. else
  871. {
  872. Status = STATUS_INTERNAL_ERROR;
  873. goto Exit;
  874. }
  875. CounterForFilesFoundInSpecifiedAssembly = 0 ;
  876. EntryData = NULL;
  877. for ( i = 0 ; i < StringSectionHeader->ElementCount; i++ )
  878. {
  879. // for a specified assembly
  880. if (ElementList[i].AssemblyRosterIndex == SubInstanceIndex->ulAssemblyIndex + 1)
  881. {
  882. // for specified file in this assembly
  883. if (CounterForFilesFoundInSpecifiedAssembly == SubInstanceIndex->ulFileIndexInAssembly)
  884. {
  885. if (ElementList[i].Offset != 0)
  886. {
  887. // we found the right one
  888. EntryData = (PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION)(((ULONG_PTR)StringSectionHeader) + ElementList[i].Offset);
  889. break;
  890. }
  891. }
  892. CounterForFilesFoundInSpecifiedAssembly ++;
  893. }
  894. }
  895. if (EntryData == NULL )
  896. {
  897. Status = STATUS_INTERNAL_ERROR;
  898. goto Exit;
  899. }
  900. // figure out buffer size needed
  901. BytesNeeded = sizeof(ASSEMBLY_DLL_REDIRECTION_DETAILED_INFORMATION);
  902. if (ElementList[i].KeyLength != 0)
  903. BytesNeeded += (ElementList[i].KeyLength + sizeof(WCHAR)); // for filename
  904. if (EntryData->TotalPathLength != 0)
  905. BytesNeeded += (EntryData->TotalPathLength + sizeof(WCHAR));
  906. if (BytesNeeded > InLength)
  907. {
  908. if (OutLength != NULL)
  909. *OutLength = BytesNeeded;
  910. Status = STATUS_BUFFER_TOO_SMALL;
  911. goto Exit;
  912. }
  913. // let us fill in
  914. Cursor = (PWSTR) (Info + 1);
  915. Info->ulFlags = EntryData->Flags;
  916. Info->ulFilenameLength = ElementList[i].KeyLength;
  917. Info->ulPathLength = EntryData->TotalPathLength;
  918. Info->lpFileName = NULL;
  919. Info->lpFilePath = NULL;
  920. // copy the strings...
  921. // copy the filename
  922. if (ElementList[i].KeyLength != 0) {
  923. RtlCopyMemory(
  924. Cursor,
  925. (PVOID) (((ULONG_PTR) StringSectionHeader) + ElementList[i].KeyOffset),
  926. ElementList[i].KeyLength);
  927. Info->lpFileName = Cursor;
  928. Cursor = (PWSTR) (((ULONG_PTR) Cursor) + ElementList[i].KeyLength);
  929. *Cursor++ = L'\0';
  930. }
  931. // concatenate the path
  932. if (EntryData->TotalPathLength != 0) {
  933. if (EntryData->PathSegmentOffset != 0)
  934. PathSegments = (PCACTIVATION_CONTEXT_DATA_DLL_REDIRECTION_PATH_SEGMENT)(StringSectionHeader + EntryData->PathSegmentOffset);
  935. if (PathSegments != NULL)
  936. {
  937. Info->lpFilePath = Cursor;
  938. for (i=0; i < EntryData->PathSegmentCount; i++)
  939. {
  940. if (PathSegments[i].Offset != 0)
  941. {
  942. RtlCopyMemory(
  943. Cursor,
  944. (PVOID) (((ULONG_PTR) StringSectionHeader) + PathSegments[i].Offset),
  945. PathSegments[i].Length);
  946. Cursor = (PWSTR) (((ULONG_PTR) Cursor) + PathSegments[i].Length);
  947. }
  948. }
  949. *Cursor++ = L'\0';
  950. }
  951. }
  952. ASSERT((((ULONG_PTR) Cursor) - ((ULONG_PTR) Info)) == BytesNeeded);
  953. Status = STATUS_SUCCESS;
  954. Exit:
  955. return Status;
  956. }
  957. NTSTATUS
  958. NTAPI
  959. RtlQueryInformationActivationContext(
  960. IN ULONG Flags,
  961. IN PCACTIVATION_CONTEXT ActivationContext,
  962. IN PVOID SubInstanceIndex,
  963. IN ACTIVATION_CONTEXT_INFO_CLASS InfoClass,
  964. OUT PVOID Buffer,
  965. IN SIZE_T InLength,
  966. OUT PSIZE_T OutLength OPTIONAL
  967. )
  968. {
  969. NTSTATUS Status = STATUS_INTERNAL_ERROR;
  970. BOOLEAN LoaderLockLocked = FALSE;
  971. PVOID LoaderLockCookie = NULL;
  972. PCACTIVATION_CONTEXT_DATA ActivationContextData = NULL;
  973. __try {
  974. if (OutLength != NULL) {
  975. *OutLength = 0;
  976. }
  977. if ((Flags &
  978. ~( RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT
  979. | RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_ACTIVATION_CONTEXT_IS_MODULE
  980. | RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_ACTIVATION_CONTEXT_IS_ADDRESS
  981. | RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_NO_ADDREF
  982. )) != 0) {
  983. DbgPrintEx(
  984. DPFLTR_SXS_ID,
  985. DPFLTR_ERROR_LEVEL,
  986. "SXS: %s() - Caller passed invalid flags (0x%08lx)\n",
  987. __FUNCTION__,
  988. Flags);
  989. Status = STATUS_INVALID_PARAMETER_1;
  990. goto Exit;
  991. }
  992. //
  993. // REVIEW do we really care?
  994. // And check that no other infoclass really does include an optionally addrefed actctx.
  995. //
  996. if ((Flags & RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_NO_ADDREF) != 0
  997. && InfoClass != ActivationContextBasicInformation) {
  998. DbgPrintEx(
  999. DPFLTR_SXS_ID,
  1000. DPFLTR_ERROR_LEVEL,
  1001. "SXS: %s() - Caller passed meaningless flags/class combination (0x%08lx/0x%08lx)\n",
  1002. __FUNCTION__,
  1003. Flags,
  1004. InfoClass);
  1005. Status = STATUS_INVALID_PARAMETER_1;
  1006. goto Exit;
  1007. }
  1008. if ((InfoClass != ActivationContextBasicInformation) &&
  1009. (InfoClass != ActivationContextDetailedInformation) &&
  1010. (InfoClass != AssemblyDetailedInformationInActivationContxt ) &&
  1011. (InfoClass != FileInformationInAssemblyOfAssemblyInActivationContxt))
  1012. {
  1013. DbgPrintEx(
  1014. DPFLTR_SXS_ID,
  1015. DPFLTR_ERROR_LEVEL,
  1016. "SXS: %s() - caller asked for unknown information class %lu\n",
  1017. __FUNCTION__,
  1018. InfoClass);
  1019. Status = STATUS_INVALID_PARAMETER_3;
  1020. goto Exit;
  1021. }
  1022. if ((InLength != 0) && (Buffer == NULL)) {
  1023. DbgPrintEx(
  1024. DPFLTR_SXS_ID,
  1025. DPFLTR_ERROR_LEVEL,
  1026. "SXS: %s() - caller passed nonzero buffer length but NULL buffer pointer\n",
  1027. __FUNCTION__);
  1028. Status = STATUS_INVALID_PARAMETER_4;
  1029. goto Exit;
  1030. }
  1031. if ((InLength == 0) && (OutLength == NULL)) {
  1032. DbgPrintEx(
  1033. DPFLTR_SXS_ID,
  1034. DPFLTR_ERROR_LEVEL,
  1035. "SXS: %s() - caller supplied no buffer to populate and no place to return required byte count\n",
  1036. __FUNCTION__);
  1037. Status = STATUS_INVALID_PARAMETER_6;
  1038. goto Exit;
  1039. }
  1040. switch (
  1041. Flags & (
  1042. RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT
  1043. | RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_ACTIVATION_CONTEXT_IS_MODULE
  1044. | RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_ACTIVATION_CONTEXT_IS_ADDRESS
  1045. )) {
  1046. default:
  1047. DbgPrintEx(
  1048. DPFLTR_SXS_ID,
  1049. DPFLTR_ERROR_LEVEL,
  1050. "SXS: %s() - Caller passed invalid flags (0x%08lx)\n",
  1051. __FUNCTION__,
  1052. Flags);
  1053. Status = STATUS_INVALID_PARAMETER_1;
  1054. goto Exit;
  1055. case 0:
  1056. break;
  1057. case RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT:
  1058. {
  1059. PCRTL_ACTIVATION_CONTEXT_STACK_FRAME Frame;
  1060. if (ActivationContext != NULL) {
  1061. DbgPrintEx(
  1062. DPFLTR_SXS_ID,
  1063. DPFLTR_ERROR_LEVEL,
  1064. "SXS: %s() - caller asked to use active activation context but passed %p\n",
  1065. __FUNCTION__,
  1066. ActivationContext);
  1067. Status = STATUS_INVALID_PARAMETER_2;
  1068. goto Exit;
  1069. }
  1070. Frame = (PCRTL_ACTIVATION_CONTEXT_STACK_FRAME) NtCurrentTeb()->ActivationContextStack.ActiveFrame;
  1071. if (Frame != NULL) {
  1072. ActivationContext = Frame->ActivationContext;
  1073. }
  1074. }
  1075. break;
  1076. case RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_ACTIVATION_CONTEXT_IS_ADDRESS:
  1077. {
  1078. PVOID DllHandle;
  1079. if (ActivationContext == NULL) {
  1080. DbgPrintEx(
  1081. DPFLTR_SXS_ID,
  1082. DPFLTR_ERROR_LEVEL,
  1083. "SXS: %s() - Caller asked to use activation context from address in .dll but passed NULL\n",
  1084. __FUNCTION__
  1085. );
  1086. Status = STATUS_INVALID_PARAMETER_2;
  1087. goto Exit;
  1088. }
  1089. Status = LdrLockLoaderLock(0, NULL, &LoaderLockCookie);
  1090. if (!NT_SUCCESS(Status)) {
  1091. goto Exit;
  1092. }
  1093. LoaderLockLocked = TRUE;
  1094. DllHandle = RtlPcToFileHeader(RTL_CONST_CAST(PVOID)(ActivationContext), &DllHandle);
  1095. if (DllHandle == NULL) {
  1096. DbgPrintEx(
  1097. DPFLTR_SXS_ID,
  1098. DPFLTR_ERROR_LEVEL,
  1099. "SXS: %s() - Caller passed invalid address, not in any .dll (%p)\n",
  1100. __FUNCTION__,
  1101. ActivationContext);
  1102. Status = STATUS_DLL_NOT_FOUND; // REVIEW
  1103. goto Exit;
  1104. }
  1105. ActivationContext = DllHandle;
  1106. }
  1107. // FALLTHROUGH
  1108. case RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_ACTIVATION_CONTEXT_IS_MODULE:
  1109. {
  1110. PLDR_DATA_TABLE_ENTRY LdrDataTableEntry;
  1111. if (ActivationContext == NULL) {
  1112. DbgPrintEx(
  1113. DPFLTR_SXS_ID,
  1114. DPFLTR_ERROR_LEVEL,
  1115. "SXS: %s() - Caller asked to use activation context from hmodule but passed NULL\n",
  1116. __FUNCTION__
  1117. );
  1118. Status = STATUS_INVALID_PARAMETER_2;
  1119. goto Exit;
  1120. }
  1121. if (!LoaderLockLocked) {
  1122. Status = LdrLockLoaderLock(0, NULL, &LoaderLockCookie);
  1123. if (!NT_SUCCESS(Status))
  1124. goto Exit;
  1125. LoaderLockLocked = TRUE;
  1126. }
  1127. if (!LdrpCheckForLoadedDllHandle(RTL_CONST_CAST(PVOID)(ActivationContext), &LdrDataTableEntry)) {
  1128. DbgPrintEx(
  1129. DPFLTR_SXS_ID,
  1130. DPFLTR_ERROR_LEVEL,
  1131. "SXS: %s() - Caller passed invalid hmodule (%p)\n",
  1132. __FUNCTION__,
  1133. ActivationContext);
  1134. Status = STATUS_DLL_NOT_FOUND; // REVIEW
  1135. goto Exit;
  1136. }
  1137. ActivationContext = LdrDataTableEntry->EntryPointActivationContext;
  1138. }
  1139. break;
  1140. }
  1141. Status = RtlpGetActivationContextData(
  1142. RTLP_GET_ACTIVATION_CONTEXT_DATA_MAP_NULL_TO_EMPTY,
  1143. ActivationContext,
  1144. NULL,
  1145. &ActivationContextData);
  1146. if (!NT_SUCCESS(Status))
  1147. goto Exit;
  1148. if (ActivationContextData == NULL) {
  1149. switch (InfoClass) {
  1150. case ActivationContextBasicInformation:
  1151. default:
  1152. break;
  1153. case ActivationContextDetailedInformation:
  1154. case AssemblyDetailedInformationInActivationContxt:
  1155. case FileInformationInAssemblyOfAssemblyInActivationContxt:
  1156. Status = STATUS_INVALID_PARAMETER_1;
  1157. goto Exit;
  1158. }
  1159. }
  1160. switch (InfoClass) {
  1161. case ActivationContextBasicInformation:
  1162. {
  1163. ULONG BasicInfoFlags = 0;
  1164. if ((Flags & RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_NO_ADDREF) != 0) {
  1165. BasicInfoFlags |= RTLP_QUERY_INFORMATION_ACTIVATION_CONTEXT_BASIC_INFORMATION_FLAG_NO_ADDREF;
  1166. }
  1167. Status = RtlpQueryInformationActivationContextBasicInformation(
  1168. BasicInfoFlags,
  1169. ActivationContext,
  1170. ActivationContextData,
  1171. 0,
  1172. Buffer,
  1173. InLength,
  1174. OutLength
  1175. );
  1176. if (!NT_SUCCESS(Status))
  1177. goto Exit;
  1178. }
  1179. break;
  1180. case ActivationContextDetailedInformation:
  1181. Status = RtlpQueryInformationActivationContextDetailedInformation(
  1182. ActivationContextData,
  1183. 0,
  1184. Buffer,
  1185. InLength,
  1186. OutLength
  1187. );
  1188. if (!NT_SUCCESS(Status))
  1189. goto Exit;
  1190. break;
  1191. case AssemblyDetailedInformationInActivationContxt:
  1192. if (SubInstanceIndex == NULL) {
  1193. Status = STATUS_INVALID_PARAMETER;
  1194. goto Exit;
  1195. }
  1196. Status = RtlpQueryAssemblyInformationActivationContextDetailedInformation(
  1197. ActivationContextData,
  1198. *((ULONG *)SubInstanceIndex),
  1199. Buffer,
  1200. InLength,
  1201. OutLength
  1202. );
  1203. if (!NT_SUCCESS(Status))
  1204. goto Exit;
  1205. break;
  1206. case FileInformationInAssemblyOfAssemblyInActivationContxt:
  1207. Status = RtlpQueryFilesInAssemblyInformationActivationContextDetailedInformation(
  1208. ActivationContextData,
  1209. ((ACTIVATION_CONTEXT_QUERY_INDEX *)SubInstanceIndex),
  1210. Buffer,
  1211. InLength,
  1212. OutLength
  1213. );
  1214. if (!NT_SUCCESS(Status))
  1215. goto Exit;
  1216. break;
  1217. default:
  1218. DbgPrintEx(
  1219. DPFLTR_SXS_ID,
  1220. DPFLTR_ERROR_LEVEL,
  1221. "SXS: %s() - internal coding error; missing switch statement branch for InfoClass == %lu\n",
  1222. __FUNCTION__,
  1223. InfoClass);
  1224. Status = STATUS_INTERNAL_ERROR;
  1225. goto Exit;
  1226. }
  1227. Status = STATUS_SUCCESS;
  1228. Exit:
  1229. ;
  1230. } __finally {
  1231. if (LoaderLockLocked)
  1232. LdrUnlockLoaderLock(0, LoaderLockCookie);
  1233. }
  1234. return Status;
  1235. }
  1236. NTSTATUS
  1237. NTAPI
  1238. RtlQueryInformationActiveActivationContext(
  1239. IN ACTIVATION_CONTEXT_INFO_CLASS InfoClass,
  1240. OUT PVOID OutBuffer,
  1241. IN SIZE_T InLength,
  1242. OUT PSIZE_T OutLength OPTIONAL
  1243. )
  1244. {
  1245. return RtlQueryInformationActivationContext(
  1246. RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT,
  1247. NULL,
  1248. 0,
  1249. InfoClass,
  1250. OutBuffer,
  1251. InLength,
  1252. OutLength);
  1253. }