Leaked source code of windows server 2003
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.

1442 lines
53 KiB

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