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.

5317 lines
182 KiB

  1. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2. ;;
  3. ;; Copyright (c) 1998-2001 Microsoft Corporation
  4. ;;
  5. ;; Module Name:
  6. ;;
  7. ;; whnt32.tpl
  8. ;;
  9. ;; Abstract:
  10. ;;
  11. ;; This template defines the thunks for the NT api set.
  12. ;;
  13. ;; Author:
  14. ;;
  15. ;; 6-Oct-98 mzoran
  16. ;;
  17. ;; Revision History:
  18. ;; 8-9-99 [askhalid] added call to CpuNotify___ for dll load/unload and call to CpuFlushInstructionCache
  19. ;; for NtAllocateVirtualMemory NtProtectVirtualMemory and NtFlushInstructionCache.
  20. ;;
  21. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  22. [Macros]
  23. MacroName=CallNameFromApiName
  24. NumArgs=1
  25. Begin=
  26. @MArg(1)
  27. End=
  28. [EFunc]
  29. TemplateName=NtAccessCheckByType
  30. NoType=ObjectTypeList
  31. PreCall=
  32. ObjectTypeList = whNT32ShallowThunkAllocObjectTypeList32TO64((NT32OBJECT_TYPE_LIST *)ObjectTypeListHost,ObjectTypeListLength); @NL
  33. End=
  34. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  35. ;;;;;;;;;;;; Thunking Registry APIs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  36. TemplateName=NtCreateKey
  37. Begin=
  38. @GenApiThunk(Wow64@ApiName)
  39. End=
  40. TemplateName=NtDeleteKey
  41. Begin=
  42. @GenApiThunk(Wow64@ApiName)
  43. End=
  44. TemplateName=NtDeleteValueKey
  45. Begin=
  46. @GenApiThunk(Wow64@ApiName)
  47. End=
  48. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  49. ;;
  50. ;; Registry routines
  51. ;; Special handling is needed since they can be asynchronous.
  52. ;;
  53. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  54. ;; The following is the list of structures passed.
  55. ;; None of them are pointer dependent.
  56. ;; List taken from ntos\config\mtapi.c
  57. TemplateName=NtEnumerateKey
  58. Case=(KeyBasicInformation,PKEY_BASIC_INFORMATION)
  59. Case=(KeyNodeInformation,PKEY_NODE_INFORMATION)
  60. Case=(KeyFullInformation,PKEY_FULL_INFORMATION)
  61. Begin=
  62. @GenDebugNonPtrDepCases(Wow64@ApiName,KeyInformationClass)
  63. End=
  64. ;; The following is the list of structures passed.
  65. ;; None of them are pointer dependent.
  66. ;; List taken from ntos\config\mtapi.c
  67. TemplateName=NtEnumerateValueKey
  68. Case=(KeyValueBasicInformation,PKEY_VALUE_BASIC_INFORMATION)
  69. Case=(KeyValueFullInformation,PKEY_VALUE_FULL_INFORMATION)
  70. Case=(KeyValuePartialInformation,PKEY_VALUE_PARTIAL_INFORMATION)
  71. Begin=
  72. @GenDebugNonPtrDepCases(Wow64@ApiName,KeyValueInformationClass)
  73. End=
  74. TemplateName=NtFlushKey
  75. Begin=
  76. @GenApiThunk(Wow64@ApiName)
  77. End=
  78. TemplateName=NtInitializeRegistry
  79. Begin=
  80. @GenApiThunk(Wow64@ApiName)
  81. End=
  82. TemplateName=NtCreateFile
  83. Begin=
  84. @GenApiThunk(Wow64@ApiName)
  85. End=
  86. TemplateName=NtOpenFile
  87. Begin=
  88. @GenApiThunk(Wow64@ApiName)
  89. End=
  90. TemplateName=NtNotifyChangeMultipleKeys
  91. NoType=SlaveObjects
  92. PreCall=
  93. {@Indent(@NL
  94. @NL try { @NL
  95. NT32OBJECT_ATTRIBUTES *Entries32 = (NT32OBJECT_ATTRIBUTES *)SlaveObjectsHost; @NL
  96. ULONG TempEntryCount = Count; @NL
  97. POBJECT_ATTRIBUTES Entries64 = (POBJECT_ATTRIBUTES)Wow64AllocateTemp(sizeof(OBJECT_ATTRIBUTES) * Count); @NL
  98. SlaveObjects = Entries64; @NL
  99. @NL
  100. for(;TempEntryCount > 0; TempEntryCount--, Entries32++, Entries64++) { @NL
  101. Entries64->Length = sizeof (OBJECT_ATTRIBUTES); @NL;
  102. Entries64->ObjectName = Wow64ShallowThunkAllocUnicodeString32TO64(Entries32->ObjectName); @NL
  103. Entries64->SecurityQualityOfService = (PVOID)Entries32->SecurityQualityOfService; @NL
  104. Entries64->SecurityDescriptor = (PVOID)Entries32->SecurityDescriptor; @NL
  105. Entries64->Attributes = (ULONG)Entries32->Attributes; @NL
  106. Entries64->RootDirectory = (HANDLE)Entries32->RootDirectory; @NL
  107. }@NL
  108. } except( NULL, EXCEPTION_EXECUTE_HANDLER){ @NL
  109. return GetExceptionCode (); @NL
  110. } @NL
  111. )}@NL
  112. Wow64WrapApcProc(&ApcRoutine, &ApcContext);
  113. End=
  114. Begin=
  115. @GenApiThunk(Wow64@ApiName)
  116. End=
  117. TemplateName=NtLoadKey
  118. Begin=
  119. @GenApiThunk(Wow64@ApiName)
  120. End=
  121. TemplateName=NtLoadKey2
  122. Begin=
  123. @GenApiThunk(Wow64@ApiName)
  124. End=
  125. TemplateName=NtOpenKey
  126. Begin=
  127. @GenApiThunk(Wow64@ApiName)
  128. End=
  129. TemplateName=NtQueryKey
  130. Begin=
  131. @GenApiThunk(Wow64@ApiName)
  132. End=
  133. TemplateName=NtQueryValueKey
  134. Begin=
  135. @GenApiThunk(Wow64@ApiName)
  136. End=
  137. TemplateName=NtReplaceKey
  138. Begin=
  139. @GenApiThunk(Wow64@ApiName)
  140. End=
  141. TemplateName=NtRestoreKey
  142. Begin=
  143. @GenApiThunk(Wow64@ApiName)
  144. End=
  145. TemplateName=NtSaveKey
  146. Begin=
  147. @GenApiThunk(Wow64@ApiName)
  148. End=
  149. TemplateName=NtSaveMergedKeys
  150. Begin=
  151. @GenApiThunk(Wow64@ApiName)
  152. End=
  153. TemplateName=NtSetValueKey
  154. Begin=
  155. @GenApiThunk(Wow64@ApiName)
  156. End=
  157. TemplateName=NtUnloadKey
  158. Begin=
  159. @GenApiThunk(Wow64@ApiName)
  160. End=
  161. TemplateName=NtQueryOpenSubKeys
  162. Begin=
  163. @GenApiThunk(Wow64@ApiName)
  164. End=
  165. TemplateName=NtClose
  166. PreCall=
  167. WOW64_REMOVE_LEGACY_PORT_HANDLE_MARK (Handle);
  168. End=
  169. Begin=
  170. @GenApiThunk(Wow64@ApiName)
  171. End=
  172. ;; to reflect registrykey security if applicable
  173. TemplateName=NtSetSecurityObject
  174. Begin=
  175. @GenApiThunk(Wow64@ApiName)
  176. End=
  177. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  178. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  179. TemplateName=NtAccessCheckByTypeAndAuditAlarm
  180. NoType=ObjectTypeList
  181. PreCall=
  182. ObjectTypeList = whNT32ShallowThunkAllocObjectTypeList32TO64((NT32OBJECT_TYPE_LIST *)ObjectTypeListHost,ObjectTypeListLength); @NL
  183. End=
  184. TemplateName=NtAccessCheckByTypeResultList
  185. NoType=ObjectTypeList
  186. PreCall=
  187. ObjectTypeList = whNT32ShallowThunkAllocObjectTypeList32TO64((NT32OBJECT_TYPE_LIST *)ObjectTypeListHost,ObjectTypeListLength); @NL
  188. End=
  189. TemplateName=NtAccessCheckByTypeResultListAndAuditAlarm
  190. NoType=ObjectTypeList
  191. PreCall=
  192. ObjectTypeList = whNT32ShallowThunkAllocObjectTypeList32TO64((NT32OBJECT_TYPE_LIST *)ObjectTypeListHost,ObjectTypeListLength); @NL
  193. End=
  194. TemplateName=NtAdjustGroupsToken
  195. NoType=PreviousState
  196. Header=
  197. @NoFormat(
  198. NTSTATUS
  199. whNT32AdjustGroupToken(
  200. IN HANDLE TokenHandle,
  201. IN BOOLEAN ResetToDefault,
  202. IN PTOKEN_GROUPS NewState,
  203. IN ULONG BufferLength,
  204. OUT PVOID PreviousState,
  205. IN PULONG ReturnLength
  206. )
  207. {
  208. NTSTATUS Status;
  209. PTOKEN_GROUPS LocalPreviousState;
  210. if(BufferLength != 0 && PreviousState != NULL) {
  211. LocalPreviousState = Wow64AllocateTemp(BufferLength);
  212. }
  213. else {
  214. LocalPreviousState = (PTOKEN_GROUPS)PreviousState;
  215. }
  216. Status = NtAdjustGroupsToken(TokenHandle,
  217. ResetToDefault,
  218. NewState,
  219. BufferLength,
  220. LocalPreviousState,
  221. ReturnLength
  222. );
  223. if(NT_ERROR(Status) || BufferLength == 0 || PreviousState == NULL) {
  224. return Status;
  225. }
  226. //Thunk the PreviousState
  227. WriteReturnLengthStatus(ReturnLength,
  228. &Status,
  229. whNT32DeepThunkTokenGroups64TO32Length(LocalPreviousState));
  230. whNT32DeepThunkTokenGroups64TO32((NT32TOKEN_GROUPS*)PreviousState, LocalPreviousState);
  231. return Status;
  232. }
  233. )
  234. End=
  235. PreCall=
  236. PreviousState = (PTOKEN_GROUPS)PreviousStateHost; @NL
  237. End=
  238. Begin=
  239. @GenApiThunk(whNT32AdjustGroupToken)
  240. End=
  241. TemplateName=NtFilterToken
  242. NoType=SidsToDisable
  243. NoType=RestrictedSids
  244. PreCall=
  245. SidsToDisable = whNT32ShallowThunkAllocTokenGroups32TO64((NT32TOKEN_GROUPS *)SidsToDisableHost); @NL
  246. RestrictedSids = whNT32ShallowThunkAllocTokenGroups32TO64((NT32TOKEN_GROUPS *)RestrictedSidsHost); @NL
  247. End=
  248. TemplateName=NtQueryInformationAtom
  249. Case=(AtomBasicInformation,PATOM_BASIC_INFORMATION)
  250. Case=(AtomTableInformation,PATOM_TABLE_INFORMATION)
  251. Begin=
  252. @GenDebugNonPtrDepCases(@ApiName,AtomInformationClass)
  253. End=
  254. TemplateName=NtQueryDirectoryObject
  255. Header=
  256. @NoFormat(
  257. NTSTATUS
  258. whNT32QueryDirectoryObject(
  259. IN HANDLE DirectoryHandle,
  260. OUT PVOID Buffer,
  261. IN ULONG Length,
  262. IN BOOLEAN ReturnSingleEntry,
  263. IN BOOLEAN RestartScan,
  264. IN OUT PULONG Context,
  265. OUT PULONG ReturnLength
  266. )
  267. {
  268. NTSTATUS Status;
  269. ULONG TempBufferLength, TempBufferReturnedLength;
  270. PVOID TempBuffer;
  271. ULONG SystemContext;
  272. ULONG GrabbedEntries, TotalSizeNeeded, SizeNeeded, EntriesToReturn, BytesToReturn, c;
  273. POBJECT_DIRECTORY_INFORMATION DirInfo64;
  274. NT32OBJECT_DIRECTORY_INFORMATION *DirInfo32;
  275. WCHAR *Strings;
  276. TempBufferLength = 0x800;
  277. try {
  278. do {
  279. TempBufferLength <<= 1;
  280. TempBuffer = Wow64AllocateTemp(TempBufferLength);
  281. // Grab the entire list of objects starting with the context specified from the app.
  282. // Note that the context is equal to the next entry number.
  283. SystemContext = *Context;
  284. Status = NtQueryDirectoryObject(DirectoryHandle,
  285. TempBuffer,
  286. TempBufferLength,
  287. ReturnSingleEntry,
  288. RestartScan,
  289. &SystemContext,
  290. &TempBufferReturnedLength);
  291. if(NT_ERROR(Status) && Status != STATUS_BUFFER_TOO_SMALL) {
  292. WriteReturnLength(ReturnLength, 0);
  293. return Status;
  294. }
  295. } while(Status != STATUS_NO_MORE_ENTRIES && Status != STATUS_SUCCESS);
  296. if (STATUS_NO_MORE_ENTRIES == Status) {
  297. WOWASSERT(SystemContext == *Context);
  298. WOWASSERT(sizeof(*DirInfo64) == TempBufferReturnedLength)
  299. WriteReturnLength(ReturnLength, 0);
  300. return Status;
  301. }
  302. DirInfo64 = (POBJECT_DIRECTORY_INFORMATION)TempBuffer;
  303. BytesToReturn = TotalSizeNeeded = sizeof(NT32OBJECT_DIRECTORY_INFORMATION);
  304. GrabbedEntries = 0;
  305. EntriesToReturn = 0;
  306. Status = STATUS_NO_MORE_ENTRIES;
  307. while(!(DirInfo64->Name.Buffer == NULL && DirInfo64->TypeName.Buffer == NULL)) {
  308. GrabbedEntries++;
  309. //The kernel will terminate the strings, so that doesn't need to be done here.
  310. SizeNeeded = sizeof(NT32OBJECT_DIRECTORY_INFORMATION) +
  311. DirInfo64->Name.Length + DirInfo64->TypeName.Length +
  312. sizeof(UNICODE_NULL) + sizeof(UNICODE_NULL);
  313. TotalSizeNeeded += SizeNeeded;
  314. if(Length >= TotalSizeNeeded) {
  315. EntriesToReturn++;
  316. BytesToReturn += SizeNeeded;
  317. }
  318. Status = STATUS_SUCCESS;
  319. DirInfo64++;
  320. }
  321. if (Length < BytesToReturn) {
  322. // If only one entry was asked for, fail the API and set the desired return length.
  323. if(ReturnSingleEntry) {
  324. WriteReturnLength(ReturnLength, BytesToReturn);
  325. return STATUS_BUFFER_TOO_SMALL;
  326. }
  327. Status = STATUS_MORE_ENTRIES;
  328. }
  329. //Copy the entries out to the buffer.
  330. DirInfo32 = (NT32OBJECT_DIRECTORY_INFORMATION *)Buffer;
  331. Strings = (WCHAR *)(DirInfo32 + EntriesToReturn + 1);
  332. DirInfo64 = (POBJECT_DIRECTORY_INFORMATION)TempBuffer;
  333. for(c=0; c < EntriesToReturn; c++) {
  334. DirInfo32->Name.Length = DirInfo64->Name.Length;
  335. DirInfo32->Name.MaximumLength = DirInfo64->Name.MaximumLength;
  336. DirInfo32->Name.Buffer = (NT32PWCHAR)PtrToUlong(Strings);
  337. RtlCopyMemory((PVOID)Strings, DirInfo64->Name.Buffer, DirInfo64->Name.Length);
  338. Strings += (DirInfo64->Name.Length / sizeof(WCHAR));
  339. *Strings++ = UNICODE_NULL;
  340. DirInfo32->TypeName.Length = DirInfo64->TypeName.Length;
  341. DirInfo32->TypeName.MaximumLength = DirInfo64->TypeName.MaximumLength;
  342. DirInfo32->TypeName.Buffer = (NT32PWCHAR)PtrToUlong(Strings);
  343. RtlCopyMemory((PVOID)Strings, DirInfo64->TypeName.Buffer, DirInfo64->TypeName.Length);
  344. Strings += (DirInfo64->TypeName.Length / sizeof(WCHAR));
  345. *Strings++ = UNICODE_NULL;
  346. DirInfo32++;
  347. DirInfo64++;
  348. }
  349. // Clear the last entry
  350. RtlZeroMemory(DirInfo32, sizeof(NT32OBJECT_DIRECTORY_INFORMATION));
  351. // Context is actually the number of the next entry to recieve. This needs to be adjusted since
  352. // the entire list may not have been sent to the app.
  353. WOWASSERT(SystemContext >= GrabbedEntries);
  354. *Context = SystemContext - (GrabbedEntries - EntriesToReturn);
  355. WriteReturnLength(ReturnLength, BytesToReturn);
  356. } except (EXCEPTION_EXECUTE_HANDLER) {
  357. Status = GetExceptionCode ();
  358. }
  359. return Status;
  360. }
  361. )
  362. End=
  363. Begin=
  364. #define WriteReturnLength(rl, length) WriteReturnLengthSilent((rl), (length))
  365. @GenApiThunk(whNT32QueryDirectoryObject)
  366. #undef WriteReturnLength
  367. End=
  368. TemplateName=NtQueryEvent
  369. Case=(EventBasicInformation,PEVENT_BASIC_INFORMATION)
  370. Begin=
  371. @GenDebugNonPtrDepCases(@ApiName,EventInformationClass)
  372. End=
  373. TemplateName=NtQueryInformationJobObject
  374. Case=(JobObjectBasicAccountingInformation,PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION)
  375. Case=(JobObjectBasicLimitInformation,PJOBOBJECT_BASIC_LIMIT_INFORMATION)
  376. Case=(JobObjectBasicUIRestrictions,PJOBOBJECT_BASIC_UI_RESTRICTIONS)
  377. Case=(JobObjectBasicProcessIdList)
  378. Case=(JobObjectEndOfJobTimeInformation,PJOBOBJECT_END_OF_JOB_TIME_INFORMATION)
  379. Case=(JobObjectExtendedLimitInformation,PJOBOBJECT_EXTENDED_LIMIT_INFORMATION)
  380. Case=(JobObjectSecurityLimitInformation)
  381. SpecialQueryCase=
  382. case JobObjectSecurityLimitInformation: { @Indent( @NL
  383. // PJOBOBJECT_SECURITY_LIMIT_INFORMATION @NL
  384. PCHAR Buffer; @NL
  385. ULONG BufferSize; @NL
  386. ULONG RequiredLength; @NL
  387. NT32JOBOBJECT_SECURITY_LIMIT_INFORMATION *SecurityLimit32; @NL
  388. PJOBOBJECT_SECURITY_LIMIT_INFORMATION SecurityLimit64; @NL
  389. @NL
  390. @NL
  391. BufferSize = max(JobObjectInformationLength * 2, 0xFFFFFFFF); @NL
  392. Buffer = Wow64AllocateTemp(BufferSize); @NL
  393. RetVal = NtQueryInformationJobObject(JobHandle, JobObjectInformationClass, Buffer, BufferSize, ReturnLength); @NL
  394. if (!NT_ERROR(RetVal)) { @Indent( @NL
  395. SecurityLimit64 = (PJOBOBJECT_SECURITY_LIMIT_INFORMATION)Buffer; @NL
  396. SecurityLimit32 = (NT32JOBOBJECT_SECURITY_LIMIT_INFORMATION *)JobObjectInformation; @NL
  397. RequiredLength = sizeof(NT32JOBOBJECT_SECURITY_LIMIT_INFORMATION); @NL
  398. if (ARGUMENT_PRESENT(SecurityLimit64->SidsToDisable)) { @Indent( @NL
  399. RequiredLength += whNT32DeepThunkTokenGroups64TO32Length(SecurityLimit64->SidsToDisable); @NL
  400. }) @NL
  401. if (ARGUMENT_PRESENT(SecurityLimit64->PrivilegesToDelete)) { @Indent( @NL
  402. RequiredLength += sizeof(ULONG) + (SecurityLimit64->PrivilegesToDelete->PrivilegeCount * sizeof(ULONG));
  403. }) @NL
  404. if (ARGUMENT_PRESENT(SecurityLimit64->RestrictedSids)) { @Indent( @NL
  405. RequiredLength += whNT32DeepThunkTokenGroups64TO32Length(SecurityLimit64->RestrictedSids); @NL
  406. }) @NL
  407. if (RequiredLength > JobObjectInformationLength) { @Indent( @NL
  408. RetVal = STATUS_BUFFER_OVERFLOW; @NL
  409. }) @NL
  410. else { @Indent( @NL
  411. SIZE_T Size = sizeof(NT32JOBOBJECT_SECURITY_LIMIT_INFORMATION); @NL
  412. WriteReturnLength(ReturnLength, RequiredLength); @NL
  413. SecurityLimit32->SecurityLimitFlags = SecurityLimit64->SecurityLimitFlags; @NL
  414. SecurityLimit32->JobToken = (NT32HANDLE)SecurityLimit64->JobToken; @NL
  415. if (ARGUMENT_PRESENT(SecurityLimit64->SidsToDisable)) { @Indent( @NL
  416. PCHAR CopyDest = (PCHAR)SecurityLimit32 + Size; @NL
  417. Size += whNT32DeepThunkTokenGroups64TO32Length(SecurityLimit64->SidsToDisable); @NL
  418. whNT32DeepThunkTokenGroups64TO32((NT32TOKEN_GROUPS *)CopyDest, SecurityLimit64->SidsToDisable); @NL
  419. SecurityLimit32->SidsToDisable = (NT32PTOKEN_GROUPS)CopyDest; @NL
  420. }) @NL
  421. else { @Indent( @NL
  422. SecurityLimit32->SidsToDisable = (NT32PTOKEN_GROUPS)SecurityLimit64->SidsToDisable; @NL
  423. }) @NL
  424. if (ARGUMENT_PRESENT(SecurityLimit64->PrivilegesToDelete)) { @Indent( @NL
  425. PCHAR CopyDest = (PCHAR)SecurityLimit32 + Size; @NL
  426. SIZE_T SizeTokenPrivileges = sizeof(ULONG) + (sizeof(LUID_AND_ATTRIBUTES) * SecurityLimit64->PrivilegesToDelete->PrivilegeCount); @NL
  427. RtlCopyMemory(CopyDest, SecurityLimit64->PrivilegesToDelete, SizeTokenPrivileges); @NL
  428. SecurityLimit32->PrivilegesToDelete = (NT32PTOKEN_PRIVILEGES)CopyDest; @NL
  429. Size += SizeTokenPrivileges; @NL
  430. }) @NL
  431. else { @Indent( @NL
  432. SecurityLimit32->PrivilegesToDelete = (NT32PTOKEN_PRIVILEGES)SecurityLimit64->PrivilegesToDelete; @NL
  433. }) @NL
  434. if (ARGUMENT_PRESENT(SecurityLimit64->RestrictedSids)) { @Indent( @NL
  435. PCHAR CopyDest = (PCHAR)SecurityLimit32 + Size; @NL
  436. Size += whNT32DeepThunkTokenGroups64TO32Length(SecurityLimit64->RestrictedSids); @NL
  437. whNT32DeepThunkTokenGroups64TO32((NT32TOKEN_GROUPS*)CopyDest, SecurityLimit64->RestrictedSids); @NL
  438. SecurityLimit32->RestrictedSids = (NT32PTOKEN_GROUPS)CopyDest; @NL
  439. }) @NL
  440. else { @Indent( @NL
  441. SecurityLimit32->RestrictedSids = (NT32PTOKEN_GROUPS)SecurityLimit64->RestrictedSids; @NL
  442. }) @NL
  443. }) @NL
  444. )} @NL
  445. })@NL
  446. case JobObjectBasicProcessIdList:
  447. @Indent( @NL
  448. {
  449. PJOBOBJECT_BASIC_PROCESS_ID_LIST JobProcessIdList64 = (PJOBOBJECT_BASIC_PROCESS_ID_LIST)JobObjectInformation;
  450. struct NT32_JOBOBJECT_BASIC_PROCESS_ID_LIST *JobProcessIdList32 = (struct NT32_JOBOBJECT_BASIC_PROCESS_ID_LIST *)JobObjectInformation;
  451. ULONG JobObjectInformationLength64 = JobObjectInformationLength;
  452. ULONG ActualReturnLength64;
  453. ULONG i;
  454. if ((ARGUMENT_PRESENT (JobProcessIdList64) != 0) &&
  455. (JobObjectInformationLength64 >= sizeof (struct NT32_JOBOBJECT_BASIC_PROCESS_ID_LIST))) {
  456. ULONG ProcessIds = (((JobObjectInformationLength64 - sizeof (struct NT32_JOBOBJECT_BASIC_PROCESS_ID_LIST)) * sizeof (ULONG_PTR)) / sizeof(ULONG));
  457. JobObjectInformationLength64 = ProcessIds + sizeof (JOBOBJECT_BASIC_PROCESS_ID_LIST);
  458. JobProcessIdList64 = Wow64AllocateTemp (JobObjectInformationLength64);
  459. if (JobProcessIdList64 == NULL) {
  460. return STATUS_NO_MEMORY;
  461. }
  462. }
  463. RetVal = NtQueryInformationJobObject(
  464. JobHandle,
  465. JobObjectInformationClass,
  466. JobProcessIdList64,
  467. JobObjectInformationLength64,
  468. &ActualReturnLength64); @NL
  469. if (NT_SUCCESS (RetVal)) {
  470. JobProcessIdList32->NumberOfAssignedProcesses = JobProcessIdList64->NumberOfAssignedProcesses;
  471. JobProcessIdList32->NumberOfProcessIdsInList = JobProcessIdList64->NumberOfProcessIdsInList;
  472. JobProcessIdList32->ProcessIdList[0] = (ULONG)JobProcessIdList64->ProcessIdList[0];
  473. for (i = 1 ; i < JobProcessIdList64->NumberOfProcessIdsInList ; i++) {
  474. JobProcessIdList32->ProcessIdList[i] = (ULONG)JobProcessIdList64->ProcessIdList[i];
  475. }
  476. if (ARGUMENT_PRESENT(ReturnLength) != 0) {
  477. *ReturnLength = sizeof (struct NT32_JOBOBJECT_BASIC_PROCESS_ID_LIST) + ((JobProcessIdList32->NumberOfProcessIdsInList - 1) * sizeof(ULONG));
  478. }
  479. }
  480. }
  481. break;)@NL
  482. End=
  483. Begin=
  484. #define WriteReturnLength(rl, length) WriteReturnLengthStatus((rl), &RetVal, (length))
  485. @GenQueryThunk(@ApiName,JobObjectInformationClass,JobObjectInformation,JobObjectInformationLength,ReturnLength,ULONG)
  486. #undef WriteReturnLength
  487. End=
  488. ;; None of these structures are pointer dependent.
  489. ;; List taken from ntos\io\complete.c
  490. TemplateName=NtQueryIoCompletion
  491. Case=(IoCompletionBasicInformation,PIO_COMPLETION_BASIC_INFORMATION)
  492. Begin=
  493. @GenDebugNonPtrDepCases(@ApiName,IoCompletionInformationClass)
  494. End=
  495. TemplateName=NtCreateProcess
  496. Also=NtCreateProcessEx
  497. Begin=
  498. @GenApiThunk(@ApiName)
  499. End=
  500. PostCall=
  501. @NoFormat(
  502. if (!NT_ERROR(RetVal) && SectionHandle) {
  503. PEB Peb64;
  504. PEB32 Peb32;
  505. PPEB32 pPeb32;
  506. SIZE_T Size;
  507. HANDLE Process = *ProcessHandle;
  508. ULONG_PTR Wow64Info;
  509. PROCESS_BASIC_INFORMATION pbi;
  510. CHILD_PROCESS_INFO ChildInfo;
  511. // Check the image type to determine if the process is already 32-bit
  512. // or not.
  513. RetVal = NtQueryInformationProcess(Process,
  514. ProcessWow64Information,
  515. &Wow64Info,
  516. sizeof(Wow64Info),
  517. NULL);
  518. if (!NT_SUCCESS(RetVal) || Wow64Info != 0) {
  519. // Either error or the process's image is 32-bit and nothing
  520. // more needs to be done.
  521. goto Done;
  522. }
  523. RetVal = NtQueryInformationProcess(Process,
  524. ProcessBasicInformation,
  525. &pbi,
  526. sizeof(pbi),
  527. NULL);
  528. if (!NT_SUCCESS(RetVal)) {
  529. goto Done;
  530. }
  531. // Read in the process's PEB64
  532. RetVal = NtReadVirtualMemory(Process,
  533. pbi.PebBaseAddress,
  534. &Peb64,
  535. sizeof(Peb64),
  536. NULL);
  537. if (!NT_SUCCESS(RetVal)) {
  538. goto Error;
  539. }
  540. // Thunk the PEB64 to a PEB32
  541. ThunkPeb64ToPeb32(&Peb64, &Peb32);
  542. // Allocate space for a PEB32 in the low 2gb of the process
  543. pPeb32 = NULL;
  544. Size = PAGE_SIZE;
  545. RetVal = NtAllocateVirtualMemory(Process,
  546. &pPeb32,
  547. MAX_WOW64_ADDRESS (), // ZeroBits
  548. &Size,
  549. MEM_RESERVE|MEM_COMMIT,
  550. PAGE_EXECUTE_READWRITE);
  551. if (!NT_SUCCESS(RetVal)) {
  552. goto Error;
  553. }
  554. // Write the PEB32 into the process
  555. RetVal = NtWriteVirtualMemory(Process,
  556. pPeb32,
  557. &Peb32,
  558. sizeof(Peb32),
  559. NULL);
  560. if (!NT_SUCCESS(RetVal)) {
  561. goto Error;
  562. }
  563. //
  564. // Gather up some data that will be needed for the NtCreateThread
  565. // call which creates the initial thread.
  566. //
  567. ChildInfo.Signature = CHILD_PROCESS_SIGNATURE;
  568. ChildInfo.TailSignature = CHILD_PROCESS_SIGNATURE;
  569. ChildInfo.pPeb32 = pPeb32;
  570. RetVal = NtQuerySection(SectionHandle,
  571. SectionImageInformation,
  572. &ChildInfo.ImageInformation,
  573. sizeof(ChildInfo.ImageInformation),
  574. NULL);
  575. if (!NT_SUCCESS(RetVal)) {
  576. goto Error;
  577. }
  578. //
  579. // Stuff the information into the child process, immediately after
  580. // the PEB64 in memory
  581. //
  582. NtWriteVirtualMemory(Process,
  583. ((BYTE*)pbi.PebBaseAddress) + PAGE_SIZE - sizeof(ChildInfo),
  584. &ChildInfo,
  585. sizeof(ChildInfo),
  586. NULL);
  587. if (!NT_SUCCESS(RetVal)) {
  588. goto Error;
  589. }
  590. LOGPRINT((TRACELOG, "@ApiName: Peb32 at %p ChildInfo at %p\n",
  591. ChildInfo.pPeb32, ((BYTE*)pbi.PebBaseAddress) + PAGE_SIZE - sizeof(ChildInfo)));
  592. goto Done;
  593. Error:
  594. NtTerminateProcess(Process, RetVal);
  595. Done:;
  596. }
  597. )
  598. End=
  599. TemplateName=NtTerminateProcess
  600. PreCall=
  601. // Handle the special case of NtTerminateProcess() getting called@NL
  602. // to terminate all threads but the current one@NL
  603. if (!ProcessHandle) {@NL
  604. CpuProcessTerm(ProcessHandle);@NL
  605. }@NL
  606. // KERNEL32 call this function with NtCurrentProcess when exiting. @NL
  607. // This is as good as any place to put shutdown code. @NL
  608. if (NtCurrentProcess() == ProcessHandle) {@Indent(@NL
  609. Wow64Shutdown(ProcessHandle); @NL
  610. )}@NL
  611. End=
  612. ; The input and output types are aways the same with this function.
  613. TemplateName=NtPowerInformation
  614. Case=(SystemPowerPolicyAc,PSYSTEM_POWER_POLICY)
  615. Case=(SystemPowerPolicyDc,PSYSTEM_POWER_POLICY)
  616. Case=(AdministratorPowerPolicy,PADMINISTRATOR_POWER_POLICY)
  617. Case=(VerifySystemPolicyAc,PSYSTEM_POWER_POLICY)
  618. Case=(VerifySystemPolicyDc,PSYSTEM_POWER_POLICY)
  619. Case=(SystemPowerPolicyCurrent,PSYSTEM_POWER_POLICY)
  620. Case=(SystemPowerCapabilities,PSYSTEM_POWER_CAPABILITIES)
  621. Case=(SystemBatteryState,PSYSTEM_BATTERY_STATE)
  622. Case=(SystemPowerStateHandler,PVOID)
  623. Case=(ProcessorStateHandler,PVOID)
  624. Case=(SystemReserveHiberFile,PBOOLEAN)
  625. Case=(SystemPowerInformation,PSYSTEM_POWER_INFORMATION)
  626. Case=(ProcessorInformation,PPROCESSOR_POWER_INFORMATION)
  627. Begin=
  628. // ProcessorInformation is dependent on the number of processors, but no good method exists
  629. // to emulate this since it returns a record for each bit that is set in the active processor mask.
  630. // Since the 32bit mask returned to the app is bogus, this API is difficult to emulate.
  631. // Fortunately, the only code that uses these APIs are control panel applications and they are going
  632. // to be 64bit.
  633. @GenDebugNonPtrDepCases(@ApiName,InformationLevel)
  634. End=
  635. TemplateName=NtQueryInformationProcess
  636. Case=(ProcessBasicInformation)
  637. Case=(ProcessIoCounters,PULONG)
  638. Case=(ProcessVmCounters)
  639. Case=(ProcessTimes,PKERNEL_USER_TIMES)
  640. Case=(ProcessBasePriority,KPRIORITY*)
  641. Case=(ProcessRaisePriority,PULONG)
  642. Case=(ProcessDebugPort,PHANDLE)
  643. Case=(ProcessExceptionPort,PHANDLE)
  644. Case=(ProcessAccessToken,PPROCESS_ACCESS_TOKEN)
  645. Case=(ProcessLdtInformation,PULONG) ; this is really PROCESS_LDT_INFORMATION but that isn't defined on Alpha
  646. Case=(ProcessLdtSize,PULONG) ; this is really PROCESS_LDT_SIZE but that isn't defined on alpha
  647. Case=(ProcessDefaultHardErrorMode,PULONG)
  648. Case=(ProcessPooledUsageAndLimits,PPOOLED_USAGE_AND_LIMITS)
  649. Case=(ProcessWorkingSetWatch)
  650. Case=(ProcessEnableAlignmentFaultFixup,BOOLEAN *)
  651. Case=(ProcessPriorityClass,PPROCESS_PRIORITY_CLASS)
  652. Case=(ProcessWx86Information,PHANDLE)
  653. Case=(ProcessHandleCount,PULONG)
  654. Case=(ProcessAffinityMask)
  655. Case=(ProcessPriorityBoost,PULONG)
  656. Case=(ProcessDeviceMap,PPROCESS_DEVICEMAP_INFORMATION)
  657. Case=(ProcessSessionInformation,PPROCESS_SESSION_INFORMATION)
  658. Case=(ProcessForegroundInformation,PPROCESS_FOREGROUND_BACKGROUND)
  659. Case=(ProcessWow64Information,PULONG_PTR)
  660. Case=(ProcessLUIDDeviceMapsEnabled,PULONG)
  661. Case=(ProcessDebugFlags)
  662. Case=(ProcessImageFileName)
  663. Case=(ProcessHandleTracing)
  664. Case=(ProcessQuotaLimits)
  665. SpecialQueryCase=
  666. @NoFormat(
  667. case ProcessBasicInformation:
  668. {
  669. PROCESS_BASIC_INFORMATION pbi;
  670. if (ProcessInformationLengthHost != sizeof(NT32PROCESS_BASIC_INFORMATION)) {
  671. RetVal = STATUS_INFO_LENGTH_MISMATCH;
  672. break;
  673. }
  674. RetVal = NtQueryInformationProcess(ProcessHandle,
  675. ProcessBasicInformation,
  676. &pbi,
  677. sizeof(pbi),
  678. (PULONG)ReturnLengthHost);
  679. if (!NT_ERROR(RetVal)) {
  680. NT32PROCESS_BASIC_INFORMATION *pbi32 = (NT32PROCESS_BASIC_INFORMATION*)ProcessInformationHost;
  681. NTSTATUS st;
  682. ULONG_PTR Wow64Info;
  683. //
  684. // Set the right length
  685. //
  686. if (ARGUMENT_PRESENT (ReturnLengthHost)) {
  687. *(PULONG)ReturnLengthHost = sizeof (NT32PROCESS_BASIC_INFORMATION);
  688. }
  689. // Copy back the "easy" fields
  690. pbi32->ExitStatus = pbi.ExitStatus;
  691. pbi32->AffinityMask = Wow64ThunkAffinityMask64TO32(pbi.AffinityMask);
  692. pbi32->UniqueProcessId = (NT32ULONG_PTR)pbi.UniqueProcessId;
  693. pbi32->InheritedFromUniqueProcessId = (NT32ULONG_PTR)pbi.InheritedFromUniqueProcessId;
  694. // PebBaseAddress is special. If the process is 32-bit then
  695. // return the PEB32 pointer. If the process is 64-bit but has no
  696. // threads, create a PEB32 and return a pointer to it. Lastly,
  697. // if the process is 64-bit and has threads, return a bad pointer
  698. // so 32-bit apps don't get all confused. Most nicely check the
  699. // return value from NtReadVirtualMemory() and gracefully fail if
  700. // the read fails.
  701. st = NtQueryInformationProcess(ProcessHandle,
  702. ProcessWow64Information,
  703. &Wow64Info,
  704. sizeof(Wow64Info),
  705. NULL);
  706. if (NT_ERROR(st)) {
  707. //
  708. // Query failed for some reason. Return a bad pointer but don't
  709. // fail the API call.
  710. //
  711. LOGPRINT((TRACELOG, "whNtQueryInformationProcess: ProcessWow64Information failed status %X, return 0 for PEB\n", st));
  712. pbi32->PebBaseAddress = 0;
  713. break;
  714. } else if (Wow64Info) {
  715. //
  716. // Process is 32-bit. The PEB32 pointer is Wow64Info
  717. //
  718. LOGPRINT((TRACELOG, "whNtQueryInformationProcess: Process is 32bit returning %x as PEB32\n", (ULONG)Wow64Info));
  719. pbi32->PebBaseAddress = (ULONG)Wow64Info;
  720. } else {
  721. //
  722. // Process is 64-bit. If the process has no threads, then
  723. // we're in the middle of a 32-bit CreateProcess() and it's OK to
  724. // temporarily create a PEB32 in the process.
  725. //
  726. CHILD_PROCESS_INFO ChildInfo;
  727. PEB32 ChildPeb32;
  728. SIZE_T BytesRead;
  729. //
  730. // Assume failure, that we don't want to report back a PEB32 address
  731. //
  732. pbi32->PebBaseAddress = 0;
  733. // Read in the process's PEB64
  734. st = NtReadVirtualMemory(ProcessHandle,
  735. ((BYTE*)pbi.PebBaseAddress) + PAGE_SIZE - sizeof(ChildInfo),
  736. &ChildInfo,
  737. sizeof(ChildInfo),
  738. NULL);
  739. if (!NT_SUCCESS(st)) {
  740. LOGPRINT((TRACELOG, "whNtQueryInformationProcess: could not read the child info, status %X.\n", st));
  741. st = STATUS_SUCCESS;
  742. break;
  743. }
  744. //
  745. // Verify the signatures at the head and tail of the ChildInfo
  746. // structure are correct. The memory the ChildInfo struct is
  747. // stored in is "borrowed". It may be reused by the process to
  748. // store process handles. We validate that the structure appears
  749. // to atleast look correct before dereferencing it.
  750. //
  751. if ((ChildInfo.Signature != CHILD_PROCESS_SIGNATURE) ||
  752. (ChildInfo.TailSignature != CHILD_PROCESS_SIGNATURE)) {
  753. LOGPRINT((TRACELOG, "whNtQueryInformationProcess: ChildInfo signatures don't match\n"));
  754. st = STATUS_SUCCESS;
  755. break;
  756. }
  757. //
  758. // Now try and read the PEB32, again this is to verify the
  759. // PEB32 pointer looks good.
  760. //
  761. st = NtReadVirtualMemory(
  762. ProcessHandle,
  763. ChildInfo.pPeb32,
  764. &ChildPeb32,
  765. sizeof(ChildPeb32),
  766. &BytesRead);
  767. if (!NT_SUCCESS(st))
  768. {
  769. LOGPRINT((TRACELOG, "whNtQueryInformationProcess: Couldn't validate 32bit PEB\n"));
  770. LOGPRINT((TRACELOG, "whNtQueryInformationProcess: Returned %p bytes of %p requested\n",
  771. BytesRead, sizeof(ChildPeb32)));
  772. st = STATUS_SUCCESS;
  773. break;
  774. }
  775. // Tell the caller where the PEB32 is
  776. LOGPRINT((TRACELOG, "whNtQueryInformationProcess: process is 64bit and has a fake 32bit peb at %p.\n", ChildInfo.pPeb32));
  777. pbi32->PebBaseAddress = (NT32PPEB)ChildInfo.pPeb32;
  778. }
  779. }
  780. break;
  781. }
  782. case ProcessQuotaLimits: @NL
  783. {
  784. QUOTA_LIMITS_EX QuotaLimitsEx64;
  785. RetVal = STATUS_SUCCESS;
  786. if (ProcessInformationLength == sizeof (NT32QUOTA_LIMITS)) {
  787. ProcessInformationLength = sizeof (QUOTA_LIMITS);
  788. } else if (ProcessInformationLength == sizeof (NT32QUOTA_LIMITS_EX)) {
  789. ProcessInformationLength = sizeof (QUOTA_LIMITS_EX);
  790. } else {
  791. RetVal = STATUS_INFO_LENGTH_MISMATCH;
  792. }
  793. if (NT_SUCCESS (RetVal)) {
  794. RetVal = NtQueryInformationProcess (ProcessHandle,
  795. ProcessInformationClass,
  796. &QuotaLimitsEx64,
  797. ProcessInformationLength,
  798. ReturnLength
  799. );
  800. if (NT_SUCCESS (RetVal)) {
  801. //
  802. // Thunk the return length
  803. //
  804. if (ARGUMENT_PRESENT (ReturnLengthHost)) {
  805. if (*ReturnLength == sizeof (QUOTA_LIMITS_EX)) {
  806. *ReturnLength = sizeof (NT32QUOTA_LIMITS_EX);
  807. } else if (*ReturnLength == sizeof (QUOTA_LIMITS)) {
  808. *ReturnLength = sizeof (NT32QUOTA_LIMITS);
  809. } else {
  810. //
  811. // Invalid case
  812. //
  813. WOWASSERT (FALSE);
  814. }
  815. }
  816. if (ProcessInformationLength == sizeof (QUOTA_LIMITS_EX)) {
  817. @ForceType(PostCall,((PQUOTA_LIMITS_EX)(&QuotaLimitsEx64)),(NT32QUOTA_LIMITS_EX *)ProcessInformation,PQUOTA_LIMITS_EX,OUT) @NL
  818. } else if (ProcessInformationLength == sizeof (QUOTA_LIMITS)) {
  819. @ForceType(PostCall,((PQUOTA_LIMITS)(&QuotaLimitsEx64)),(NT32QUOTA_LIMITS *)ProcessInformation,PQUOTA_LIMITS,OUT) @NL
  820. } else {
  821. //
  822. // Invalid case
  823. //
  824. WOWASSERT (FALSE);
  825. }
  826. }
  827. }
  828. break;
  829. }
  830. case ProcessHandleTracing: @NL
  831. {
  832. PPROCESS_HANDLE_TRACING_QUERY Pht64;
  833. NT32PROCESS_HANDLE_TRACING_QUERY *Pht32 = (NT32PROCESS_HANDLE_TRACING_QUERY *)ProcessInformation;
  834. ULONG StacksLeft;
  835. NT32PROCESS_HANDLE_TRACING_ENTRY *NextTrace32;
  836. PPROCESS_HANDLE_TRACING_ENTRY NextTrace64;
  837. ULONG Length64;
  838. ULONG ReturnLength64;
  839. ULONG Count;
  840. if (ProcessInformationLength < FIELD_OFFSET (NT32PROCESS_HANDLE_TRACING_QUERY, HandleTrace)) {
  841. return STATUS_INFO_LENGTH_MISMATCH;
  842. }
  843. StacksLeft = ((ProcessInformationLength - FIELD_OFFSET (NT32PROCESS_HANDLE_TRACING_QUERY, HandleTrace)) / sizeof (Pht32->HandleTrace[0]));
  844. //
  845. // Allocate as much as we need here
  846. //
  847. try {
  848. Length64 = (StacksLeft * sizeof (Pht64->HandleTrace[0])) + (FIELD_OFFSET (PROCESS_HANDLE_TRACING_QUERY, HandleTrace));
  849. Pht64 = Wow64AllocateTemp (Length64);
  850. Pht64->Handle = (HANDLE) LongToPtr (Pht32->Handle);
  851. RetVal = NtQueryInformationProcess (ProcessHandle,
  852. ProcessInformationClass,
  853. Pht64,
  854. Length64,
  855. &ReturnLength64);
  856. //
  857. // If all is well
  858. //
  859. if (NT_SUCCESS (RetVal)) {
  860. Pht32->TotalTraces = Pht64->TotalTraces;
  861. NextTrace32 = (NT32PROCESS_HANDLE_TRACING_ENTRY *)&Pht32->HandleTrace[0];
  862. NextTrace64 = &Pht64->HandleTrace[0];
  863. for (Count = 0 ; Count < Pht64->TotalTraces ; Count++) {
  864. NextTrace32->Handle = PtrToLong (NextTrace64->Handle);
  865. @ForceType(PostCall,((PCLIENT_ID)&NextTrace64->ClientId),((NT32CLIENT_ID *)&NextTrace32->ClientId),PCLIENT_ID,OUT) @NL
  866. NextTrace32->Type = NextTrace64->Type;
  867. for (StacksLeft = 0 ; StacksLeft < (sizeof (NextTrace64->Stacks) / sizeof (NextTrace64->Stacks[0])) ; StacksLeft++) {
  868. NextTrace32->Stacks[StacksLeft] = PtrToUlong (NextTrace64->Stacks[StacksLeft]);
  869. }
  870. NextTrace32++;
  871. NextTrace64++;
  872. }
  873. //
  874. // Update the return length
  875. //
  876. if (ARGUMENT_PRESENT (ReturnLengthHost)) {
  877. *ReturnLength = ((PCHAR)NextTrace32 - (PCHAR)Pht32);
  878. }
  879. } else {
  880. //
  881. // We may have returned the actual length
  882. //
  883. Pht32->TotalTraces = Pht64->TotalTraces;
  884. if (ARGUMENT_PRESENT (ReturnLengthHost)) {
  885. *ReturnLength = ((Pht64->TotalTraces * sizeof (Pht32->HandleTrace[0])) + FIELD_OFFSET (NT32PROCESS_HANDLE_TRACING_QUERY, HandleTrace));
  886. }
  887. }
  888. } except (EXCEPTION_EXECUTE_HANDLER) {
  889. RetVal = GetExceptionCode ();
  890. }
  891. break;
  892. }
  893. case ProcessWorkingSetWatch: @NL
  894. @Indent(
  895. WOWASSERT(TRUE); @NL
  896. return STATUS_NOT_IMPLEMENTED; @NL
  897. ) @NL
  898. case ProcessAffinityMask: @NL
  899. {
  900. ULONG_PTR Affinity64;
  901. if (ProcessInformationLength != sizeof(ULONG)) {
  902. RetVal = STATUS_INFO_LENGTH_MISMATCH;
  903. break;
  904. }
  905. RetVal = NtQueryInformationProcess(ProcessHandle,
  906. ProcessAffinityMask,
  907. &Affinity64,
  908. sizeof(Affinity64),
  909. NULL);
  910. *(PULONG)ProcessInformation = Wow64ThunkAffinityMask64TO32(Affinity64);
  911. }
  912. case ProcessImageFileName:
  913. {
  914. ULONG ReturnLengthLocal;
  915. PUNICODE_STRING32 ProcessInformation32 = (PUNICODE_STRING32)ProcessInformation;
  916. PUNICODE_STRING ProcessInformation64 = (PUNICODE_STRING)ProcessInformation32;
  917. if (ProcessInformationLength > 0) {
  918. ProcessInformationLength += (sizeof (UNICODE_STRING) - sizeof (UNICODE_STRING32));
  919. ProcessInformation64 = Wow64AllocateTemp (ProcessInformationLength);
  920. }
  921. RetVal = NtQueryInformationProcess(ProcessHandle,
  922. ProcessInformationClass,
  923. ProcessInformation64,
  924. ProcessInformationLength,
  925. ReturnLength
  926. );
  927. if (NT_SUCCESS (RetVal)) {
  928. if (ProcessInformation32 != NULL) {
  929. @ForceType(PostCall,ProcessInformation64,ProcessInformation32,PUNICODE_STRING,OUT) @NL
  930. try {
  931. RtlCopyMemory (ProcessInformation32+1,
  932. ProcessInformation64+1,
  933. ProcessInformation64->MaximumLength);
  934. ProcessInformation32->Buffer = (PWCHAR)(ProcessInformation32+1);
  935. } except (EXCEPTION_EXECUTE_HANDLER) {
  936. RetVal = GetExceptionCode ();
  937. }
  938. }
  939. }
  940. }
  941. break;
  942. case ProcessDebugFlags:
  943. {
  944. PVOID Peb32;
  945. RetVal = NtQueryInformationProcess(ProcessHandle,
  946. ProcessWow64Information,
  947. &Peb32, sizeof(Peb32),
  948. NULL);
  949. if (NT_SUCCESS(RetVal) && Peb32) {
  950. RetVal = NtQueryInformationProcess(ProcessHandle,
  951. ProcessInformationClass,
  952. ProcessInformation,
  953. ProcessInformationLength,
  954. ReturnLength);
  955. }
  956. else {
  957. RetVal = STATUS_INVALID_INFO_CLASS;
  958. }
  959. break;
  960. }
  961. case ProcessVmCounters: @NL @Indent(
  962. {
  963. VM_COUNTERS_EX VmCountersEx64;
  964. if (ProcessInformationLength == sizeof (NT32VM_COUNTERS)) {
  965. ProcessInformationLength = sizeof (VM_COUNTERS);
  966. RetVal = STATUS_SUCCESS;
  967. } else if (ProcessInformationLength == sizeof (NT32VM_COUNTERS_EX)) {
  968. ProcessInformationLength = sizeof (VM_COUNTERS_EX);
  969. RetVal = STATUS_SUCCESS;
  970. } else {
  971. RetVal = STATUS_INFO_LENGTH_MISMATCH;
  972. }
  973. if (NT_SUCCESS (RetVal)) {
  974. RetVal = NtQueryInformationProcess (ProcessHandle,
  975. ProcessInformationClass,
  976. &VmCountersEx64,
  977. ProcessInformationLength,
  978. ReturnLength
  979. );
  980. if (NT_SUCCESS (RetVal)) {
  981. //
  982. // Thunk the return length
  983. //
  984. if (ARGUMENT_PRESENT(ReturnLengthHost)) {
  985. if (*ReturnLength == sizeof (VM_COUNTERS_EX)) {
  986. *ReturnLength = sizeof (NT32VM_COUNTERS_EX);
  987. } else if (*ReturnLength == sizeof (VM_COUNTERS)) {
  988. *ReturnLength = sizeof (NT32VM_COUNTERS);
  989. } else {
  990. //
  991. // Invalid case
  992. //
  993. WOWASSERT (FALSE);
  994. }
  995. }
  996. if (ProcessInformationLength == sizeof (VM_COUNTERS_EX)) {
  997. @ForceType(PostCall,((PVM_COUNTERS_EX)(&VmCountersEx64)),(NT32VM_COUNTERS_EX *)ProcessInformation,PVM_COUNTERS_EX,OUT) @NL
  998. } else if (ProcessInformationLength == sizeof (VM_COUNTERS)) {
  999. @ForceType(PostCall,((PVM_COUNTERS_EX)(&VmCountersEx64)),(NT32VM_COUNTERS *)ProcessInformation,PVM_COUNTERS,OUT) @NL
  1000. } else {
  1001. //
  1002. // Invalid case
  1003. //
  1004. WOWASSERT (FALSE);
  1005. }
  1006. }
  1007. }
  1008. break;
  1009. }
  1010. )
  1011. End=
  1012. Begin=
  1013. #define WriteReturnLength(rl, length) WriteReturnLengthStatus((rl), &RetVal, (length))
  1014. @GenQueryThunk(@ApiName,ProcessInformationClass,ProcessInformation,ProcessInformationLength,ReturnLength,ULONG)
  1015. #undef WriteReturnLength
  1016. End=
  1017. TemplateName=NtQueryInformationThread
  1018. Case=(ThreadTimes,PKERNEL_USER_TIMES)
  1019. Case=(ThreadQuerySetWin32StartAddress,PULONG)
  1020. Case=(ThreadPerformanceCount,PLARGE_INTEGER)
  1021. Case=(ThreadAmILastThread,PULONG)
  1022. Case=(ThreadPriorityBoost,PULONG)
  1023. Case=(ThreadIsIoPending,PULONG)
  1024. Case=(ThreadDescriptorTableEntry)
  1025. Case=(ThreadBasicInformation)
  1026. SpecialQueryCase=
  1027. case ThreadDescriptorTableEntry: @NL
  1028. @Indent(
  1029. return Wow64GetThreadSelectorEntry(ThreadHandle,
  1030. ThreadInformation,
  1031. ThreadInformationLength,
  1032. ReturnLength); @NL
  1033. break; @NL
  1034. )@NL
  1035. case ThreadBasicInformation: @Indent( @NL
  1036. return @CallApi(whNtQueryInformationThreadBasicInformation,RetVal)
  1037. break; @NL
  1038. )@NL
  1039. End=
  1040. Header=
  1041. NTSTATUS @NL
  1042. whNtQueryInformationThreadBasicInformation(IN HANDLE ThreadHandle,
  1043. IN THREADINFOCLASS ThreadInformationClass,
  1044. OUT PVOID ThreadInformationHost,
  1045. IN ULONG ThreadInformationLength,
  1046. OUT PULONG ReturnLength OPTIONAL
  1047. ) @NL
  1048. { @Indent( @NL
  1049. NTSTATUS Status; @NL
  1050. PTHREAD_BASIC_INFORMATION ThreadInformation; @NL
  1051. @Types(Locals,ThreadInformation,PTHREAD_BASIC_INFORMATION)
  1052. if (ThreadInformationHost == NULL) { @Indent( @NL
  1053. WriteReturnLength(ReturnLength, sizeof(NT32THREAD_BASIC_INFORMATION)); @NL
  1054. return STATUS_INVALID_PARAMETER; @NL
  1055. }) @NL
  1056. if (ThreadInformationLength != sizeof(NT32THREAD_BASIC_INFORMATION)) { @Indent( @NL
  1057. WriteReturnLength(ReturnLength, sizeof(NT32THREAD_BASIC_INFORMATION)); @NL
  1058. return STATUS_INFO_LENGTH_MISMATCH; @NL
  1059. }) @NL
  1060. @Types(PreCall,ThreadInformation,PTHREAD_BASIC_INFORMATION)
  1061. Status = Wow64QueryBasicInformationThread(ThreadHandle,(PTHREAD_BASIC_INFORMATION)ThreadInformation); @NL
  1062. @Types(PostCall,ThreadInformation,PTHREAD_BASIC_INFORMATION)
  1063. if (ReturnLength) { @Indent( @NL
  1064. WriteReturnLength(ReturnLength, sizeof(NT32THREAD_BASIC_INFORMATION)); @NL
  1065. }) @NL
  1066. return Status; @NL
  1067. }) @NL
  1068. End=
  1069. Begin=
  1070. #define WriteReturnLength(rl, length) WriteReturnLengthSilent((rl), (length))
  1071. @GenQueryThunk(NtQueryInformationThread,ThreadInformationClass,ThreadInformation,ThreadInformationLength,ReturnLength,ULONG)
  1072. #undef WriteReturnLength
  1073. End=
  1074. TemplateName=NtQueryInformationToken
  1075. Case=(TokenUser,PTOKEN_USER)
  1076. Case=(TokenGroups,PTOKEN_GROUPS)
  1077. Case=(TokenPrivileges,PTOKEN_PRIVILEGES)
  1078. Case=(TokenOwner,PTOKEN_OWNER)
  1079. Case=(TokenPrimaryGroup,PTOKEN_PRIMARY_GROUP)
  1080. Case=(TokenDefaultDacl,PTOKEN_DEFAULT_DACL)
  1081. Case=(TokenSource,PTOKEN_SOURCE)
  1082. Case=(TokenType,PTOKEN_TYPE)
  1083. Case=(TokenImpersonationLevel,PSECURITY_IMPERSONATION_LEVEL)
  1084. Case=(TokenStatistics,PTOKEN_STATISTICS)
  1085. Case=(TokenRestrictedSids,PTOKEN_GROUPS)
  1086. Case=(TokenSessionId,PULONG)
  1087. Case=(TokenSandBoxInert,PULONG)
  1088. Case=(TokenGroupsAndPrivileges)
  1089. SpecialQueryCase=
  1090. @Indent( @NL
  1091. case TokenGroupsAndPrivileges:
  1092. {
  1093. PTOKEN_GROUPS_AND_PRIVILEGES TokenInformation64;
  1094. struct NT32_TOKEN_GROUPS_AND_PRIVILEGES *TokenInformation32 = (struct NT32_TOKEN_GROUPS_AND_PRIVILEGES *)TokenInformation;
  1095. struct NT32_SID_AND_ATTRIBUTES *Sids;
  1096. PCHAR Sid, Start;
  1097. NTSTATUS NtStatus;
  1098. INT AllocSize = 0, SidLength;
  1099. ULONG i, RetInfoLen;
  1100. ULONG ReturnLength64;
  1101. AllocSize += LENGTH + sizeof(struct _TOKEN_GROUPS_AND_PRIVILEGES) - sizeof(struct NT32_TOKEN_GROUPS_AND_PRIVILEGES);
  1102. TokenInformation64 = Wow64AllocateTemp(AllocSize);
  1103. if (TokenInformation64 == NULL) {
  1104. RtlRaiseStatus (STATUS_NO_MEMORY);
  1105. }
  1106. NtStatus = NtQueryInformationToken (TokenHandle,
  1107. TokenInformationClass,
  1108. TokenInformation64,
  1109. AllocSize,
  1110. &ReturnLength64);
  1111. if (NT_ERROR (NtStatus)) {
  1112. WriteReturnLength (ReturnLength, ReturnLength64);
  1113. return NtStatus;
  1114. }
  1115. if (WOW64_ISPTR (TokenInformation32)) {
  1116. if (ReturnLength64 > TokenInformationLength) {
  1117. return STATUS_INFO_LENGTH_MISMATCH;
  1118. }
  1119. TokenInformation32->SidCount = TokenInformation64->SidCount;
  1120. TokenInformation32->Sids = (struct NT32SID_AND_ATTRIBUTES *)((PCHAR)(TokenInformation32) + sizeof(struct NT32_TOKEN_GROUPS_AND_PRIVILEGES));
  1121. Sids = TokenInformation32->Sids;
  1122. Sid = (PCHAR) (Sids + (TokenInformation32->SidCount));
  1123. Start = (PCHAR)Sids;
  1124. for (i=0 ; i<TokenInformation64->SidCount ; i++) {
  1125. Sids[i].Sid = Sid;
  1126. Sids[i].Attributes = TokenInformation64->Sids[i].Attributes;
  1127. SidLength = RtlLengthSid(TokenInformation64->Sids[i].Sid);
  1128. RtlCopyMemory(Sid, TokenInformation64->Sids[i].Sid, SidLength);
  1129. Sid += SidLength;
  1130. }
  1131. TokenInformation32->SidLength = ((PCHAR)Sid - (PCHAR)Sids);
  1132. if (TokenInformation32->SidLength == 0) {
  1133. TokenInformation32->Sids = 0;
  1134. }
  1135. TokenInformation32->RestrictedSidCount = TokenInformation64->RestrictedSidCount;
  1136. TokenInformation32->RestrictedSids = (struct NT32_SID_AND_ATTRIBUTES *)Sid;
  1137. Sids = (struct NT32_SID_AND_ATTRIBUTES *)Sid;
  1138. Start = (PCHAR)Sids;
  1139. Sid = (PCHAR) (Sids + (TokenInformation32->RestrictedSidCount));
  1140. for (i=0 ; i<TokenInformation64->RestrictedSidCount ; i++) {
  1141. Sids[i].Sid = Sid;
  1142. Sids[i].Attributes = TokenInformation64->RestrictedSids[i].Attributes;
  1143. SidLength = RtlLengthSid(TokenInformation64->RestrictedSids[i].Sid);
  1144. RtlCopyMemory(Sid, TokenInformation64->RestrictedSids[i].Sid, SidLength);
  1145. Sid += SidLength;
  1146. }
  1147. TokenInformation32->RestrictedSidLength = ((PCHAR)Sid - Start);
  1148. if (TokenInformation32->RestrictedSidLength == 0) {
  1149. TokenInformation32->RestrictedSids = 0;
  1150. }
  1151. TokenInformation32->PrivilegeCount = TokenInformation64->PrivilegeCount;
  1152. TokenInformation32->PrivilegeLength = TokenInformation64->PrivilegeLength;
  1153. if (TokenInformation32->PrivilegeCount > 0) {
  1154. TokenInformation32->Privileges = (struct NT32LUID_AND_ATTRIBUTES *)Sid;
  1155. RtlCopyMemory (Sid, TokenInformation64->Privileges, TokenInformation32->PrivilegeCount * sizeof(NT32LUID_AND_ATTRIBUTES));
  1156. Sid += TokenInformation32->PrivilegeCount;
  1157. }
  1158. else
  1159. {
  1160. TokenInformation32->Privileges = 0;
  1161. }
  1162. RtlCopyMemory (&TokenInformation32->AuthenticationId,
  1163. &TokenInformation64->AuthenticationId,
  1164. sizeof (TokenInformation64->AuthenticationId));
  1165. RetInfoLen = (Sid - (PCHAR)TokenInformation32);
  1166. } else {
  1167. RetInfoLen = ReturnLength64;
  1168. }
  1169. //
  1170. // update the return length
  1171. //
  1172. WriteReturnLength (ReturnLength, RetInfoLen);
  1173. RetVal = NtStatus;
  1174. }
  1175. break;
  1176. ) @NL
  1177. Begin=
  1178. #define WriteReturnLength(rl, length) WriteReturnLengthStatus((rl), &RetVal, (length))
  1179. @GenQueryThunk(@ApiName,TokenInformationClass,TokenInformation,TokenInformationLength,ReturnLength,ULONG)
  1180. #undef WriteReturnLength
  1181. End=
  1182. TemplateName=NtQueryMutant
  1183. Case=(MutantBasicInformation,PMUTANT_BASIC_INFORMATION)
  1184. Begin=
  1185. @GenDebugNonPtrDepCases(@ApiName,MutantInformationClass)
  1186. End=
  1187. TemplateName=NtQueryObject
  1188. Case=(ObjectBasicInformation,POBJECT_BASIC_INFORMATION)
  1189. Case=(ObjectNameInformation)
  1190. Case=(ObjectTypeInformation)
  1191. Case=(ObjectTypesInformation)
  1192. Case=(ObjectHandleFlagInformation,POBJECT_HANDLE_FLAG_INFORMATION)
  1193. SpecialQueryCase=
  1194. @NoFormat(
  1195. case ObjectNameInformation: @NL
  1196. @Indent({
  1197. SIZE_T AllocSize = 0;
  1198. POBJECT_NAME_INFORMATION NameInformation;
  1199. struct NT32_OBJECT_NAME_INFORMATION *Name32 = (struct NT32_OBJECT_NAME_INFORMATION *)ObjectInformation;
  1200. AllocSize += LENGTH + sizeof(OBJECT_NAME_INFORMATION) - sizeof(struct NT32_OBJECT_NAME_INFORMATION);
  1201. NameInformation = Wow64AllocateTemp(AllocSize);
  1202. RetVal=NtQueryObject(Handle,
  1203. ObjectNameInformation,
  1204. NameInformation,
  1205. AllocSize,
  1206. ReturnLength
  1207. );
  1208. if (!NT_ERROR(RetVal)) {
  1209. // Thunk the Name (a UNICODE_STRING) by hand... the Buffer
  1210. // pointer actually points to the first byte past the end of
  1211. // the OBJECT_TYPE_INFORMATION struct.
  1212. try {
  1213. Name32->Name.Length = NameInformation->Name.Length;
  1214. Name32->Name.MaximumLength = NameInformation->Name.MaximumLength;
  1215. Name32->Name.Buffer = PtrToUlong(Name32+1);
  1216. RtlCopyMemory((PVOID)Name32->Name.Buffer, NameInformation->Name.Buffer, NameInformation->Name.Length);
  1217. ((PWSTR)Name32->Name.Buffer)[ (NameInformation->Name.Length/sizeof(WCHAR)) ] = UNICODE_NULL;
  1218. WriteReturnLength(ReturnLength, sizeof(struct NT32_OBJECT_NAME_INFORMATION) + Name32->Name.MaximumLength);
  1219. } except (EXCEPTION_EXECUTE_HANDLER) {
  1220. RetVal = GetExceptionCode ();
  1221. }
  1222. }
  1223. }
  1224. break;)
  1225. case ObjectTypeInformation: @NL
  1226. @Indent({
  1227. SIZE_T AllocSize = 0;
  1228. POBJECT_TYPE_INFORMATION TypeInformation;
  1229. struct NT32_OBJECT_TYPE_INFORMATION *Type32 = (struct NT32_OBJECT_TYPE_INFORMATION *)ObjectInformation;
  1230. AllocSize += LENGTH + sizeof(OBJECT_TYPE_INFORMATION) - sizeof(struct NT32_OBJECT_TYPE_INFORMATION);
  1231. TypeInformation = Wow64AllocateTemp(AllocSize);
  1232. LENGTH = (NT32SIZE_T)AllocSize;
  1233. RetVal=NtQueryObject(Handle,
  1234. ObjectTypeInformation,
  1235. TypeInformation,
  1236. Length,
  1237. ReturnLength
  1238. );
  1239. if (!NT_ERROR(RetVal)) {
  1240. // Thunk the TypeName (a UNICODE_STRING) by hand... the Buffer
  1241. // pointer actually points to the first byte past the end of
  1242. // the OBJECT_TYPE_INFORMATION struct.
  1243. try {
  1244. Type32->TypeName.Length = TypeInformation->TypeName.Length;
  1245. Type32->TypeName.MaximumLength = TypeInformation->TypeName.MaximumLength;
  1246. Type32->TypeName.Buffer = PtrToUlong(Type32+1);
  1247. RtlCopyMemory((PVOID)Type32->TypeName.Buffer, TypeInformation->TypeName.Buffer, TypeInformation->TypeName.Length);
  1248. // NULL out the UNICODE string
  1249. ((PWSTR)(Type32->TypeName.Buffer))[ Type32->TypeName.Length/sizeof(WCHAR) ] = UNICODE_NULL;
  1250. // Thunk the other fields in the OBJECT_TYPE_INFORMATION by a simple
  1251. // copy
  1252. RtlCopyMemory(&Type32->TotalNumberOfObjects,
  1253. &TypeInformation->TotalNumberOfObjects,
  1254. sizeof(NT32OBJECT_TYPE_INFORMATION)-FIELD_OFFSET(struct NT32_OBJECT_TYPE_INFORMATION, TotalNumberOfObjects));
  1255. WriteReturnLength(ReturnLength, sizeof(struct NT32_OBJECT_TYPE_INFORMATION) + Type32->TypeName.MaximumLength);
  1256. } except (EXCEPTION_EXECUTE_HANDLER) {
  1257. RetVal = GetExceptionCode ();
  1258. }
  1259. }
  1260. }
  1261. break;)
  1262. case ObjectTypesInformation: @NL
  1263. @Indent({
  1264. SIZE_T AllocSize = 0;
  1265. SIZE_T OldLength = 0;
  1266. PULONG TypesInformation;
  1267. ULONG n;
  1268. // figure out how many OBJECT_TYPE_INFORMATIONs the caller had space for, and
  1269. // grow the 64-bit temp size to handle 'n' 64-bit OBJECT_TYPE_INFORMATIONs.
  1270. n = (LENGTH-sizeof(ULONG)) / sizeof(struct NT32_OBJECT_TYPE_INFORMATION);
  1271. AllocSize += LENGTH + n*(sizeof(OBJECT_TYPE_INFORMATION) - sizeof(struct NT32_OBJECT_TYPE_INFORMATION));
  1272. TypesInformation = Wow64AllocateTemp(AllocSize);
  1273. OldLength = LENGTH;
  1274. LENGTH = (NT32SIZE_T)AllocSize;
  1275. RetVal=NtQueryObject(Handle,
  1276. ObjectTypesInformation,
  1277. TypesInformation,
  1278. Length,
  1279. ReturnLength
  1280. );
  1281. // Note: if this fails with STATUS_INFO_LENGTH_MISMATCH, it will return
  1282. // back the 64-bit ReturnLength value. That should be OK for a 32-bit
  1283. // app to use if it needs to allocate a bigger buffer for a second call.
  1284. if (!NT_ERROR(RetVal)) {
  1285. POBJECT_TYPE_INFORMATION Type64;
  1286. struct NT32_OBJECT_TYPE_INFORMATION *Type32;
  1287. try {
  1288. // Copy over the count of objects
  1289. *(PULONG)ObjectInformation = *TypesInformation;
  1290. Type64 = (POBJECT_TYPE_INFORMATION) (ALIGN_UP(((ULONG)(TypesInformation+1)), PVOID));
  1291. Type32 = (struct NT32_OBJECT_TYPE_INFORMATION*)( ((PULONG)ObjectInformation)+1 );
  1292. for (n = 0; n<*TypesInformation; n++) {
  1293. // Thunk the TypeName (a UNICODE_STRING) by hand... the Buffer
  1294. // pointer actually points to the first byte past the end of
  1295. // the OBJECT_TYPE_INFORMATION struct.
  1296. Type32->TypeName.Length = Type64->TypeName.Length;
  1297. Type32->TypeName.MaximumLength = Type64->TypeName.MaximumLength;
  1298. Type32->TypeName.Buffer = PtrToUlong((Type32+1));
  1299. RtlCopyMemory((PVOID)Type32->TypeName.Buffer, Type64->TypeName.Buffer, Type64->TypeName.Length);
  1300. ((PWSTR)(Type32->TypeName.Buffer))[ Type64->TypeName.Length/sizeof(WCHAR) ] = UNICODE_NULL;
  1301. // Thunk the other fields in the OBJECT_TYPE_INFORMATION by a simple
  1302. // copy
  1303. RtlCopyMemory(&Type32->TotalNumberOfObjects,
  1304. &Type64->TotalNumberOfObjects,
  1305. sizeof(struct NT32_OBJECT_TYPE_INFORMATION)-FIELD_OFFSET(struct NT32_OBJECT_TYPE_INFORMATION, TotalNumberOfObjects));
  1306. // Move the pointers forward
  1307. Type64 = (POBJECT_TYPE_INFORMATION)(
  1308. (PCHAR)(Type64+1) + ALIGN_UP(Type64->TypeName.MaximumLength, PVOID));
  1309. Type32 = (struct NT32_OBJECT_TYPE_INFORMATION *)(
  1310. (PCHAR)(Type32+1) + ALIGN_UP(Type32->TypeName.MaximumLength, ULONG));
  1311. }
  1312. WriteReturnLength(ReturnLength, (ULONG)( (PBYTE)Type32 - (PBYTE)ObjectInformation ));
  1313. } except (EXCEPTION_EXECUTE_HANDLER) {
  1314. RetVal = GetExceptionCode ();
  1315. }
  1316. }
  1317. }
  1318. break;)
  1319. )
  1320. Begin=
  1321. #define WriteReturnLength(rl, length) WriteReturnLengthSilent((rl), (length))
  1322. @GenQueryThunk(@ApiName,ObjectInformationClass,ObjectInformation,Length,ReturnLength,ULONG)
  1323. #undef WriteReturnLength
  1324. End=
  1325. TemplateName=NtQuerySection
  1326. Case=(SectionBasicInformation,PSECTION_BASIC_INFORMATION)
  1327. Case=(SectionImageInformation,PSECTION_IMAGE_INFORMATION)
  1328. Header=
  1329. End=
  1330. Begin=
  1331. #define WriteReturnLength(rl, length) WriteReturnLengthSilent((PULONG)(rl), (ULONG)(length))
  1332. @GenQueryThunk(@ApiName,SectionInformationClass,SectionInformation,SectionInformationLength,ReturnLength,SIZE_T)
  1333. #undef WriteReturnLength
  1334. End=
  1335. PostCall=
  1336. @NoFormat(
  1337. if (!NT_ERROR(RetVal) && SectionInformationClass == SectionImageInformation) {
  1338. struct NT32_SECTION_IMAGE_INFORMATION *pSecInfo32 = (struct NT32_SECTION_IMAGE_INFORMATION *)SectionInformation;
  1339. #if defined(_AMD64_)
  1340. if (pSecInfo32->Machine == IMAGE_FILE_MACHINE_AMD64)
  1341. #elif defined(_IA64_)
  1342. if (pSecInfo32->Machine == IMAGE_FILE_MACHINE_IA64)
  1343. #else
  1344. #error "No Target Architecture"
  1345. #endif
  1346. {
  1347. // Image section is 64-bit. Lie about a number of the fields
  1348. // so RtlCreateUserProcess and CreateProcessW are happy.
  1349. pSecInfo32->TransferAddress = 0x81231234; // bogus nonzero value
  1350. pSecInfo32->MaximumStackSize = 1024*1024; // max stack size = 1meg
  1351. pSecInfo32->CommittedStackSize = 64*1024; // 64k commit
  1352. }
  1353. }
  1354. )
  1355. End=
  1356. TemplateName=NtQuerySecurityObject
  1357. NoType=SecurityDescriptor
  1358. Header=
  1359. @NoFormat(
  1360. NTSTATUS
  1361. whNT32QuerySecurityObject(
  1362. IN HANDLE Handle,
  1363. IN SECURITY_INFORMATION SecurityInformation,
  1364. OUT PVOID SecurityDescriptor,
  1365. IN ULONG Length,
  1366. OUT PULONG LengthNeeded
  1367. )
  1368. {
  1369. NTSTATUS Status;
  1370. SECURITY_DESCRIPTOR *Descriptor64;
  1371. NT32SECURITY_DESCRIPTOR *Descriptor32;
  1372. Status = NtQuerySecurityObject(Handle,
  1373. SecurityInformation,
  1374. (PSECURITY_DESCRIPTOR)SecurityDescriptor,
  1375. Length,
  1376. LengthNeeded
  1377. );
  1378. if (NT_ERROR(Status) || !SecurityDescriptor) {
  1379. return Status;
  1380. }
  1381. Descriptor64 = (SECURITY_DESCRIPTOR *)SecurityDescriptor;
  1382. try {
  1383. if (Descriptor64->Control & SE_SELF_RELATIVE) {
  1384. //Descriptor is self-relative, no thunking needed.
  1385. return Status;
  1386. }
  1387. Descriptor32 = (NT32SECURITY_DESCRIPTOR *)SecurityDescriptor;
  1388. //Copy up the lower fields.
  1389. //Note that the destination structure is small.
  1390. Descriptor32->Owner = (NT32PSID)Descriptor64->Owner;
  1391. Descriptor32->Group = (NT32PSID)Descriptor64->Group;
  1392. Descriptor32->Sacl = (NT32PSID)Descriptor64->Sacl;
  1393. Descriptor32->Dacl = (NT32PSID)Descriptor64->Dacl;
  1394. } except (EXCEPTION_EXECUTE_HANDLER) {
  1395. Status = GetExceptionCode ();
  1396. }
  1397. return Status;
  1398. }
  1399. )
  1400. End=
  1401. PreCall=
  1402. SecurityDescriptor = (PSECURITY_DESCRIPTOR)SecurityDescriptorHost; @NL
  1403. Begin=
  1404. @GenApiThunk(whNT32QuerySecurityObject)
  1405. End=
  1406. TemplateName=NtQuerySystemInformation
  1407. Case=(SystemBasicInformation,PSYSTEM_BASIC_INFORMATION)
  1408. Case=(SystemProcessorInformation,PSYSTEM_PROCESSOR_INFORMATION)
  1409. Case=(SystemEmulationBasicInformation,PSYSTEM_BASIC_INFORMATION)
  1410. Case=(SystemEmulationProcessorInformation,PSYSTEM_PROCESSOR_INFORMATION)
  1411. Case=(SystemPerformanceInformation,PSYSTEM_PERFORMANCE_INFORMATION)
  1412. Case=(SystemTimeOfDayInformation,PSYSTEM_TIMEOFDAY_INFORMATION)
  1413. Case=(SystemCallCountInformation,PSYSTEM_CALL_COUNT_INFORMATION)
  1414. Case=(SystemDeviceInformation,PSYSTEM_DEVICE_INFORMATION)
  1415. Case=(SystemProcessorPerformanceInformation)
  1416. Case=(SystemFlagsInformation,PSYSTEM_FLAGS_INFORMATION)
  1417. Case=(SystemModuleInformation,PRTL_PROCESS_MODULES)
  1418. Case=(SystemLocksInformation,PRTL_PROCESS_LOCKS)
  1419. Case=(SystemStackTraceInformation,PRTL_PROCESS_BACKTRACES)
  1420. Case=(SystemPagedPoolInformation,PSYSTEM_POOL_INFORMATION)
  1421. Case=(SystemNonPagedPoolInformation,PSYSTEM_POOL_INFORMATION)
  1422. Case=(SystemHandleInformation,PSYSTEM_HANDLE_INFORMATION)
  1423. Case=(SystemObjectInformation,PSYSTEM_OBJECTTYPE_INFORMATION)
  1424. Case=(SystemPageFileInformation,PSYSTEM_PAGEFILE_INFORMATION)
  1425. Case=(SystemFileCacheInformation,PSYSTEM_FILECACHE_INFORMATION)
  1426. Case=(SystemPoolTagInformation,PSYSTEM_POOLTAG_INFORMATION)
  1427. Case=(SystemInterruptInformation,PSYSTEM_INTERRUPT_INFORMATION)
  1428. Case=(SystemDpcBehaviorInformation,PSYSTEM_DPC_BEHAVIOR_INFORMATION)
  1429. Case=(SystemFullMemoryInformation,PSYSTEM_MEMORY_INFORMATION)
  1430. Case=(SystemTimeAdjustmentInformation,PSYSTEM_QUERY_TIME_ADJUST_INFORMATION)
  1431. Case=(SystemSummaryMemoryInformation,PSYSTEM_MEMORY_INFORMATION)
  1432. Case=(SystemExceptionInformation,PSYSTEM_EXCEPTION_INFORMATION)
  1433. Case=(SystemKernelDebuggerInformation,PSYSTEM_KERNEL_DEBUGGER_INFORMATION)
  1434. Case=(SystemContextSwitchInformation,PSYSTEM_CONTEXT_SWITCH_INFORMATION)
  1435. Case=(SystemRegistryQuotaInformation,PSYSTEM_REGISTRY_QUOTA_INFORMATION)
  1436. Case=(SystemCurrentTimeZoneInformation,PRTL_TIME_ZONE_INFORMATION)
  1437. Case=(SystemLookasideInformation,PSYSTEM_LOOKASIDE_INFORMATION)
  1438. Case=(SystemProcessorIdleInformation,PSYSTEM_PROCESSOR_IDLE_INFORMATION)
  1439. Case=(SystemLostDelayedWriteInformation,PULONG)
  1440. Case=(SystemRangeStartInformation,ULONG_PTR*)
  1441. Case=(SystemComPlusPackage,PULONG)
  1442. Case=(SystemNumaProcessorMap)
  1443. Case=(SystemNumaAvailableMemory)
  1444. Case=(SystemVerifierInformation)
  1445. Case=(SystemPerformanceTraceInformation)
  1446. Case=(SystemCallTimeInformation)
  1447. Case=(SystemPathInformation)
  1448. Case=(SystemVdmInstemulInformation)
  1449. Case=(SystemVdmBopInformation)
  1450. Case=(SystemProcessInformation)
  1451. Case=(SystemExtendedProcessInformation)
  1452. Case=(SystemSessionPoolTagInformation)
  1453. Case=(SystemSessionProcessInformation)
  1454. Case=(SystemSessionMappedViewInformation)
  1455. Case=(SystemLogicalProcessorInformation)
  1456. Header=
  1457. @NoFormat(
  1458. NTSTATUS
  1459. whNT32ThunkProcessInformationEx (
  1460. IN PSYSTEM_PROCESS_INFORMATION ProcessInformation,
  1461. IN BOOLEAN ExtendedProcessInformation,
  1462. IN OUT NT32SYSTEM_PROCESS_INFORMATION **ProcessInformation32,
  1463. OUT PULONG SystemInformationLength32 //return remaining length in buffer not the valid content in Buffer
  1464. ) @NL
  1465. {
  1466. PSYSTEM_THREAD_INFORMATION ThreadInfo;
  1467. PSYSTEM_EXTENDED_THREAD_INFORMATION ThreadInfoEx;
  1468. NT32SYSTEM_PROCESS_INFORMATION *ProcessInfo32 = *ProcessInformation32;
  1469. NT32SYSTEM_THREAD_INFORMATION *ThreadInfo32;
  1470. NT32SYSTEM_EXTENDED_THREAD_INFORMATION *ThreadInfoEx32;
  1471. PVOID pvLast;
  1472. ULONG NumberOfThreads;
  1473. ULONG BufferLength = *SystemInformationLength32;
  1474. //
  1475. // Check if the user has enough space
  1476. //
  1477. if (BufferLength < sizeof (NT32SYSTEM_PROCESS_INFORMATION)) {
  1478. return STATUS_INFO_LENGTH_MISMATCH;
  1479. }
  1480. BufferLength = BufferLength - sizeof (NT32SYSTEM_PROCESS_INFORMATION);
  1481. @ForceType(PostCall,ProcessInformation,ProcessInfo32,SYSTEM_PROCESS_INFORMATION*,OUT)
  1482. NumberOfThreads = ProcessInformation->NumberOfThreads;
  1483. ThreadInfo = (PSYSTEM_THREAD_INFORMATION) (ProcessInformation + 1);
  1484. ThreadInfoEx = (PSYSTEM_EXTENDED_THREAD_INFORMATION) (ProcessInformation + 1);
  1485. ThreadInfo32 = (NT32SYSTEM_THREAD_INFORMATION *) (ProcessInfo32 + 1);
  1486. ThreadInfoEx32 = (NT32SYSTEM_EXTENDED_THREAD_INFORMATION *) (ProcessInfo32 + 1);
  1487. pvLast = (ProcessInfo32 + 1);
  1488. if (ExtendedProcessInformation) {
  1489. if (BufferLength < (sizeof (PSYSTEM_EXTENDED_THREAD_INFORMATION) * NumberOfThreads)) {
  1490. return STATUS_INFO_LENGTH_MISMATCH;
  1491. }
  1492. BufferLength = BufferLength - (sizeof (PSYSTEM_EXTENDED_THREAD_INFORMATION) * NumberOfThreads);
  1493. } else {
  1494. if (BufferLength < (sizeof (PSYSTEM_THREAD_INFORMATION) * NumberOfThreads)) {
  1495. return STATUS_INFO_LENGTH_MISMATCH;
  1496. }
  1497. BufferLength = BufferLength - (sizeof (PSYSTEM_THREAD_INFORMATION) * NumberOfThreads);
  1498. }
  1499. while (NumberOfThreads > 0) {
  1500. if (ExtendedProcessInformation) {
  1501. @ForceType(PostCall,ThreadInfoEx,ThreadInfoEx32,PSYSTEM_EXTENDED_THREAD_INFORMATION,OUT)
  1502. ThreadInfoEx = ThreadInfoEx + 1;
  1503. ThreadInfoEx32 = ThreadInfoEx32 + 1;
  1504. pvLast = ThreadInfoEx32;
  1505. } else {
  1506. @ForceType(PostCall,ThreadInfo,ThreadInfo32,PSYSTEM_THREAD_INFORMATION,OUT)
  1507. ThreadInfo = ThreadInfo + 1;
  1508. ThreadInfo32 = ThreadInfo32 + 1;
  1509. pvLast = ThreadInfo32;
  1510. }
  1511. NumberOfThreads--;
  1512. }
  1513. if (ProcessInformation->ImageName.Buffer != NULL) {
  1514. if (BufferLength < ProcessInformation->ImageName.MaximumLength) {
  1515. return STATUS_INFO_LENGTH_MISMATCH;
  1516. }
  1517. BufferLength = BufferLength - ProcessInformation->ImageName.MaximumLength;
  1518. RtlCopyMemory (pvLast,
  1519. ProcessInformation->ImageName.Buffer,
  1520. ProcessInformation->ImageName.MaximumLength
  1521. );
  1522. ProcessInfo32->ImageName.Buffer = pvLast;
  1523. pvLast = (PCHAR)pvLast + ProcessInformation->ImageName.MaximumLength;
  1524. ProcessInfo32->ImageName.MaximumLength = ProcessInformation->ImageName.MaximumLength;
  1525. ProcessInfo32->ImageName.Length = ProcessInformation->ImageName.Length;
  1526. } else {
  1527. ProcessInfo32->ImageName.Buffer = NULL;
  1528. ProcessInfo32->ImageName.MaximumLength = ProcessInfo32->ImageName.Length = 0;
  1529. }
  1530. pvLast = ROUND_UP ((ULONG_PTR)pvLast, sizeof(ULONGLONG));
  1531. if (ProcessInformation->NextEntryOffset == 0)
  1532. ProcessInfo32->NextEntryOffset = 0;
  1533. else
  1534. ProcessInfo32->NextEntryOffset = (ULONG) ((PCHAR)pvLast - (PCHAR)ProcessInfo32);
  1535. *ProcessInformation32 = pvLast;
  1536. *SystemInformationLength32 = BufferLength;
  1537. return STATUS_SUCCESS;
  1538. }
  1539. NTSTATUS
  1540. whNT32QuerySystemSessionMappedViewInformation (
  1541. IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
  1542. OUT PVOID SystemInformation32,
  1543. IN ULONG SystemInformationLength32,
  1544. OUT PULONG ReturnLength32 OPTIONAL
  1545. ) @NL
  1546. {
  1547. NTSTATUS NtStatus;
  1548. ULONG SystemInformationLength;
  1549. ULONG ReturnLength;
  1550. NT32SYSTEM_SESSION_MAPPED_VIEW_INFORMATION *SystemInformationHost = (NT32SYSTEM_SESSION_MAPPED_VIEW_INFORMATION *)SystemInformation32;
  1551. PSYSTEM_SESSION_MAPPED_VIEW_INFORMATION SystemInformation;
  1552. PBYTE pBuffer;
  1553. //
  1554. // Allocate enough memory to make call to 64bit Kernel then copy info back to 32bit struct
  1555. //
  1556. ULONG ByteCount = sizeof( SYSTEM_SESSION_MAPPED_VIEW_INFORMATION ) * ( SystemInformationLength32 / sizeof (NT32SYSTEM_SESSION_MAPPED_VIEW_INFORMATION) + 8 ); //start with 4K memory.
  1557. if (SystemInformationLength32 < sizeof (NT32SYSTEM_SESSION_MAPPED_VIEW_INFORMATION) )
  1558. return STATUS_INFO_LENGTH_MISMATCH;
  1559. if ( (pBuffer = Wow64AllocateTemp(ByteCount )) == NULL ) {
  1560. return STATUS_NO_MEMORY; //OUT of memory
  1561. }
  1562. SystemInformation = (PSYSTEM_SESSION_MAPPED_VIEW_INFORMATION)pBuffer;
  1563. SystemInformation->SessionId = SystemInformationHost->SessionId;
  1564. /*
  1565. * get native info
  1566. */
  1567. NtStatus = NtQuerySystemInformation(
  1568. SystemSessionMappedViewInformation,
  1569. SystemInformation,
  1570. ByteCount,
  1571. &ReturnLength );
  1572. if (ReturnLength == 0 || !NT_SUCCESS(NtStatus)) {
  1573. if (ARGUMENT_PRESENT (ReturnLength32))
  1574. *ReturnLength32 = 0;
  1575. return NtStatus;
  1576. }
  1577. //
  1578. // Now loop through the buffer and thunk members.
  1579. //
  1580. ReturnLength = sizeof (NT32SYSTEM_SESSION_MAPPED_VIEW_INFORMATION);
  1581. for (;;) {
  1582. SystemInformationHost->NumberOfBytesAvailable = SystemInformation->NumberOfBytesAvailable;
  1583. SystemInformationHost->NumberOfBytesAvailableContiguous = SystemInformation->NumberOfBytesAvailableContiguous;
  1584. SystemInformationHost->SessionId = SystemInformation->SessionId;
  1585. SystemInformationHost->ViewFailures = SystemInformation->ViewFailures;
  1586. if (SystemInformation->NextEntryOffset == 0) {
  1587. SystemInformationHost->NextEntryOffset =0;
  1588. break;
  1589. } else {
  1590. SystemInformation = (PSYSTEM_SESSION_MAPPED_VIEW_INFORMATION)((PBYTE)SystemInformation +SystemInformation->NumberOfBytesAvailable);
  1591. SystemInformationHost->NextEntryOffset = ROUND_UP (SystemInformationHost->NextEntryOffset, sizeof(ULONGLONG));
  1592. SystemInformationHost->NextEntryOffset = sizeof (NT32SYSTEM_SESSION_MAPPED_VIEW_INFORMATION);
  1593. SystemInformationHost = (NT32SYSTEM_SESSION_MAPPED_VIEW_INFORMATION *)((PBYTE)SystemInformationHost +SystemInformationHost->NumberOfBytesAvailable);
  1594. ReturnLength += SystemInformationHost->NextEntryOffset;
  1595. if (ReturnLength > SystemInformationLength32 )
  1596. return STATUS_INFO_LENGTH_MISMATCH;
  1597. }
  1598. }
  1599. if (ARGUMENT_PRESENT (ReturnLength32))
  1600. *ReturnLength32 = ReturnLength;
  1601. return NtStatus;
  1602. }
  1603. NTSTATUS
  1604. whNT32QuerySystemVerifierInformation (
  1605. IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
  1606. OUT PVOID SystemInformation32,
  1607. IN ULONG SystemInformationLength32,
  1608. OUT PULONG ReturnLength32 OPTIONAL
  1609. ) @NL
  1610. {
  1611. NTSTATUS NtStatus;
  1612. ULONG SystemInformationLength;
  1613. ULONG ReturnLength;
  1614. PBYTE pNextBuff;
  1615. NT32SYSTEM_VERIFIER_INFORMATION *SystemInformationHost = (NT32SYSTEM_VERIFIER_INFORMATION *)SystemInformation32;
  1616. SYSTEM_VERIFIER_INFORMATION *SystemInformation;
  1617. //
  1618. // Allocate enough memory to make call to 64bit Kernel then copy info back to 32bit struct
  1619. //
  1620. ULONG ByteCount = 4096; //start with 4K memory.
  1621. if (SystemInformationLength32 < sizeof (NT32SYSTEM_VERIFIER_INFORMATION)) {
  1622. return STATUS_INFO_LENGTH_MISMATCH;
  1623. }
  1624. for (;;) {
  1625. if ((SystemInformation = (SYSTEM_VERIFIER_INFORMATION *)Wow64AllocateTemp (ByteCount)) == NULL ) {
  1626. return STATUS_NO_MEMORY;
  1627. }
  1628. //
  1629. // get process info
  1630. //
  1631. NtStatus = NtQuerySystemInformation(
  1632. SystemInformationClass,
  1633. SystemInformation,
  1634. ByteCount,
  1635. &ReturnLength );
  1636. if (NT_SUCCESS(NtStatus))
  1637. break;
  1638. //
  1639. // Make sure buffer is big enough
  1640. //
  1641. if (NtStatus != STATUS_INFO_LENGTH_MISMATCH) {
  1642. return (NtStatus);
  1643. }
  1644. ByteCount += 4096;
  1645. }
  1646. //
  1647. // 64bit call is done with the call now you need to copy info back to 32bit buffer
  1648. // or return STATUS_INFO_LENGTH_MISMATCH if not enough memory is supplied.
  1649. //
  1650. try {
  1651. if (ReturnLength != 0) {
  1652. ReturnLength = 0;
  1653. for (;;) {
  1654. if ((ReturnLength + sizeof (*SystemInformationHost)) > SystemInformationLength32) {
  1655. return STATUS_INFO_LENGTH_MISMATCH;
  1656. }
  1657. @ForceType(PostCall,SystemInformation,SystemInformationHost,PSYSTEM_VERIFIER_INFORMATION,OUT) @NL
  1658. ByteCount = ReturnLength;
  1659. if (SystemInformation->DriverName.Buffer != NULL) {
  1660. SystemInformationHost->DriverName.Buffer = ROUND_UP ((PBYTE)(SystemInformationHost+1), sizeof(ULONGLONG));
  1661. ReturnLength += ((PBYTE)(SystemInformationHost->DriverName.Buffer) - (PBYTE)(SystemInformationHost));
  1662. if ((ReturnLength + SystemInformation->DriverName.MaximumLength) > SystemInformationLength32) {
  1663. return STATUS_INFO_LENGTH_MISMATCH;
  1664. }
  1665. RtlCopyMemory ((PBYTE)SystemInformationHost->DriverName.Buffer,
  1666. SystemInformation->DriverName.Buffer,
  1667. SystemInformation->DriverName.MaximumLength
  1668. );
  1669. SystemInformationHost->DriverName.MaximumLength = SystemInformation->DriverName.MaximumLength;
  1670. SystemInformationHost->DriverName.Length = SystemInformation->DriverName.Length;
  1671. pNextBuff = (PBYTE)SystemInformationHost->DriverName.Buffer + SystemInformation->DriverName.MaximumLength;
  1672. } else {
  1673. SystemInformationHost->DriverName.Buffer = NULL;
  1674. SystemInformationHost->DriverName.MaximumLength = SystemInformationHost->DriverName.Length = 0;
  1675. pNextBuff = (PBYTE)SystemInformationHost + sizeof (*SystemInformationHost);
  1676. }
  1677. ReturnLength = ByteCount + (DWORD)( (PBYTE)pNextBuff - (PBYTE)SystemInformationHost);
  1678. if (SystemInformation->NextEntryOffset == 0) {
  1679. SystemInformationHost->NextEntryOffset = 0;
  1680. break;
  1681. }
  1682. SystemInformation = (PSYSTEM_VERIFIER_INFORMATION)((PBYTE)SystemInformation + SystemInformation->NextEntryOffset);
  1683. pNextBuff = ROUND_UP (pNextBuff, sizeof(ULONGLONG));
  1684. SystemInformationHost->NextEntryOffset = (DWORD)(pNextBuff - (PBYTE)SystemInformationHost);
  1685. ReturnLength = ByteCount + (DWORD)( (PBYTE)pNextBuff - (PBYTE)SystemInformationHost);
  1686. SystemInformationHost = (NT32SYSTEM_VERIFIER_INFORMATION *)pNextBuff;
  1687. }
  1688. }
  1689. if (NT_SUCCESS (NtStatus)) {
  1690. if (ARGUMENT_PRESENT (ReturnLength32)) {
  1691. *ReturnLength32 = ReturnLength;
  1692. }
  1693. }
  1694. } except (EXCEPTION_EXECUTE_HANDLER) {
  1695. NtStatus = GetExceptionCode ();
  1696. }
  1697. return NtStatus;
  1698. }
  1699. NTSTATUS
  1700. whNT32QuerySystemSessionProcessInformation (
  1701. IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
  1702. OUT PVOID SystemInformation32,
  1703. IN ULONG SystemInformationLength32,
  1704. OUT PULONG ReturnLength32 OPTIONAL
  1705. ) @NL
  1706. {
  1707. NTSTATUS NtStatus;
  1708. ULONG SystemInformationLength;
  1709. ULONG ReturnLength;
  1710. NT32SYSTEM_SESSION_PROCESS_INFORMATION *SystemInformationHost = (NT32SYSTEM_SESSION_PROCESS_INFORMATION *)SystemInformation32;
  1711. SYSTEM_SESSION_PROCESS_INFORMATION SystemInformation;
  1712. PSYSTEM_PROCESS_INFORMATION ProcessInfo;
  1713. NT32SYSTEM_PROCESS_INFORMATION *ProcessInformation32;
  1714. PBYTE pBuffer;
  1715. ULONG SystemInformationLength32Old = SystemInformationLength32;
  1716. //
  1717. // Allocate enough memory to make call to 64bit Kernel then copy info back to 32bit struct
  1718. //
  1719. ULONG ByteCount = 4096; //start with 4K memory.
  1720. if (SystemInformationLength32 < sizeof (NT32SYSTEM_SESSION_PROCESS_INFORMATION) )
  1721. return STATUS_INFO_LENGTH_MISMATCH;
  1722. else
  1723. SystemInformationLength32 -= sizeof (NT32SYSTEM_SESSION_PROCESS_INFORMATION);
  1724. SystemInformation.SessionId = SystemInformationHost->SessionId;
  1725. for(;;) {
  1726. if ( (pBuffer = Wow64AllocateTemp(ByteCount )) == NULL ) {
  1727. return STATUS_NO_MEMORY; //OUT of memory
  1728. }
  1729. SystemInformation.Buffer = pBuffer;
  1730. SystemInformation.SizeOfBuf = ByteCount;
  1731. //
  1732. // get process info
  1733. //
  1734. NtStatus = NtQuerySystemInformation(
  1735. SystemSessionProcessInformation,
  1736. &SystemInformation,
  1737. sizeof(SystemInformation),
  1738. &ReturnLength );
  1739. if ( NT_SUCCESS(NtStatus) )
  1740. break;
  1741. //
  1742. // Make sure buffer is big enough
  1743. //
  1744. if ( NtStatus != STATUS_INFO_LENGTH_MISMATCH )
  1745. return(NtStatus);
  1746. ByteCount += 4096;
  1747. }
  1748. if (ReturnLength == 0) {
  1749. if (ARGUMENT_PRESENT (ReturnLength32)) {
  1750. *ReturnLength32 = 0;
  1751. }
  1752. return NtStatus;
  1753. }
  1754. //
  1755. // 64bit call is done with the call now you need to copy info back to 32bit buffer
  1756. // or return STATUS_INFO_LENGTH_MISMATCH if not enough memory is supplied.
  1757. //
  1758. //
  1759. // Loop through all processes. Find first process running on this station
  1760. //
  1761. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
  1762. ProcessInformation32 = (NT32SYSTEM_PROCESS_INFORMATION *)SystemInformationHost->Buffer;
  1763. for (;;) {
  1764. if (ProcessInfo->NextEntryOffset == 0) {
  1765. break;
  1766. }
  1767. //
  1768. // Thunk the Individual Process structure here.
  1769. //
  1770. NtStatus = whNT32ThunkProcessInformationEx (
  1771. ProcessInfo,
  1772. FALSE,
  1773. &ProcessInformation32,
  1774. &SystemInformationLength32
  1775. );
  1776. if (!NT_SUCCESS(NtStatus)) {
  1777. break;
  1778. }
  1779. if (ProcessInfo->NextEntryOffset == 0) {
  1780. break;
  1781. }
  1782. ProcessInfo = (PSYSTEM_PROCESS_INFORMATION)( (PBYTE)ProcessInfo + ProcessInfo->NextEntryOffset);
  1783. }
  1784. if (NT_SUCCESS (NtStatus)) {
  1785. if (ARGUMENT_PRESENT (ReturnLength32)) {
  1786. *ReturnLength32 = SystemInformationLength32Old - SystemInformationLength32;
  1787. }
  1788. }
  1789. return NtStatus;
  1790. }
  1791. NTSTATUS
  1792. whNT32QuerySystemProcessInformationEx (
  1793. IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
  1794. OUT PVOID SystemInformation32,
  1795. IN ULONG SystemInformationLength32,
  1796. OUT PULONG ReturnLength32 OPTIONAL
  1797. ) @NL
  1798. {
  1799. NTSTATUS NtStatus;
  1800. ULONG SystemInformationLength;
  1801. ULONG ReturnLength;
  1802. BOOLEAN ExtendedProcessInformation;
  1803. PCHAR SystemInformationHost = (PCHAR)SystemInformation32;
  1804. PSYSTEM_PROCESS_INFORMATION SystemInformation;
  1805. //
  1806. // Allocate enough input buffer
  1807. //
  1808. SystemInformationLength = (SystemInformationLength32 + 0x400);
  1809. SystemInformation = Wow64AllocateTemp (SystemInformationLength);
  1810. if (SystemInformation == NULL) {
  1811. return STATUS_NO_MEMORY;
  1812. }
  1813. NtStatus = NtQuerySystemInformation (
  1814. SystemInformationClass,
  1815. SystemInformation,
  1816. SystemInformationLength,
  1817. &ReturnLength
  1818. );
  1819. if (NT_SUCCESS (NtStatus)) {
  1820. if (SystemInformationClass == SystemExtendedProcessInformation) {
  1821. ExtendedProcessInformation = TRUE;
  1822. } else {
  1823. ExtendedProcessInformation = FALSE;
  1824. }
  1825. //
  1826. // Thunk back the output to the caller.
  1827. //
  1828. try {
  1829. while (TRUE) {
  1830. NtStatus = whNT32ThunkProcessInformationEx (
  1831. SystemInformation,
  1832. ExtendedProcessInformation,
  1833. (NT32SYSTEM_PROCESS_INFORMATION **)&SystemInformation32,
  1834. &SystemInformationLength32
  1835. );
  1836. if (NT_SUCCESS (NtStatus)) {
  1837. if (SystemInformation->NextEntryOffset == 0) {
  1838. break;
  1839. }
  1840. SystemInformation = (PSYSTEM_PROCESS_INFORMATION) ((PCHAR)SystemInformation + SystemInformation->NextEntryOffset);
  1841. } else {
  1842. break;
  1843. }
  1844. }
  1845. //
  1846. // If all is good, let's update the output if present
  1847. //
  1848. if (NT_SUCCESS (NtStatus)) {
  1849. if (ARGUMENT_PRESENT (ReturnLength32)) {
  1850. *ReturnLength32 = ((PCHAR)SystemInformation32 - (PCHAR)SystemInformationHost);
  1851. }
  1852. }
  1853. } except (EXCEPTION_EXECUTE_HANDLER) {
  1854. NtStatus = GetExceptionCode ();
  1855. }
  1856. }
  1857. return NtStatus;
  1858. }
  1859. // SystemProcessorPerformanceInformation will return information about the processors in the system.
  1860. // On NT64, the maximum number of processors has increased to 64 instead of 32. Fortunately,
  1861. // the system will stop returning information when the client buffer is filled up. So a 32bit
  1862. // app will request preformance information on 32 processors, and the system will give them
  1863. // back information on 32 processors as expected.
  1864. NTSTATUS
  1865. whNT32QuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
  1866. OUT PVOID SystemInformation,
  1867. IN ULONG SystemInformationLength,
  1868. OUT PULONG ReturnLength OPTIONAL
  1869. )
  1870. {
  1871. PWOW64_SYSTEM_INFORMATION EmulatedSysInfo;
  1872. NTSTATUS RetVal = STATUS_SUCCESS;
  1873. EmulatedSysInfo = Wow64GetEmulatedSystemInformation();
  1874. switch(SystemInformationClass) {
  1875. case SystemBasicInformation:
  1876. if (SystemInformationLength != sizeof(SYSTEM_BASIC_INFORMATION)) {
  1877. return STATUS_INFO_LENGTH_MISMATCH;
  1878. }
  1879. if (SystemInformation == NULL) {
  1880. return STATUS_INVALID_PARAMETER;
  1881. }
  1882. RtlCopyMemory(SystemInformation,
  1883. &EmulatedSysInfo->BasicInfo,
  1884. sizeof(SYSTEM_BASIC_INFORMATION));
  1885. WriteReturnLength(ReturnLength, sizeof(SYSTEM_BASIC_INFORMATION));
  1886. return RetVal;
  1887. break;
  1888. case SystemProcessorInformation:
  1889. if (SystemInformationLength != sizeof(SYSTEM_PROCESSOR_INFORMATION)) {
  1890. return STATUS_INFO_LENGTH_MISMATCH;
  1891. }
  1892. if (SystemInformation == NULL) {
  1893. return STATUS_INVALID_PARAMETER;
  1894. }
  1895. RtlCopyMemory(SystemInformation,
  1896. &EmulatedSysInfo->ProcessorInfo,
  1897. sizeof(SYSTEM_PROCESSOR_INFORMATION)
  1898. );
  1899. WriteReturnLength(ReturnLength, sizeof(SYSTEM_PROCESSOR_INFORMATION));
  1900. return RetVal;
  1901. break;
  1902. case SystemRangeStartInformation:
  1903. if (SystemInformationLength != sizeof(ULONG_PTR)) {
  1904. return STATUS_INFO_LENGTH_MISMATCH;
  1905. }
  1906. if (SystemInformation == NULL) {
  1907. return STATUS_INVALID_PARAMETER;
  1908. }
  1909. RtlCopyMemory(SystemInformation,
  1910. &EmulatedSysInfo->RangeInfo,
  1911. sizeof(ULONG_PTR));
  1912. // WriteReturnLength(ReturnLength, sizeof(ULONG_PTR));
  1913. WriteReturnLength(ReturnLength, sizeof(ULONG));
  1914. return RetVal;
  1915. default:
  1916. return NtQuerySystemInformation(SystemInformationClass,
  1917. SystemInformation,
  1918. SystemInformationLength,
  1919. ReturnLength
  1920. );
  1921. }
  1922. }
  1923. NTSTATUS
  1924. whNT32QuerySystemSessionPoolTagInformation (
  1925. IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
  1926. OUT PVOID SystemInformation32,
  1927. IN ULONG SystemInformationLength,
  1928. OUT PULONG ReturnLength32 OPTIONAL
  1929. ) @NL
  1930. {
  1931. NTSTATUS NtStatus;
  1932. PSYSTEM_SESSION_PROCESS_INFORMATION SystemSessionProcessInformation64;
  1933. NT32SYSTEM_SESSION_PROCESS_INFORMATION *SystemSessionProcessInformation32;
  1934. PSYSTEM_SESSION_POOLTAG_INFORMATION SystemSessionPoolTagInfo64;
  1935. NT32SYSTEM_SESSION_POOLTAG_INFORMATION *SystemSessionPoolTagInfo32;
  1936. PSYSTEM_POOLTAG PoolTagInfo64;
  1937. NT32SYSTEM_POOLTAG *PoolTagInfo32;
  1938. ULONG Length64, ReturnLength64;
  1939. try {
  1940. if (SystemInformationLength < sizeof (NT32SYSTEM_SESSION_PROCESS_INFORMATION)) {
  1941. return STATUS_INFO_LENGTH_MISMATCH;
  1942. }
  1943. SystemSessionProcessInformation32 = (NT32SYSTEM_SESSION_PROCESS_INFORMATION *)SystemInformation32;
  1944. SystemSessionProcessInformation64 = (PSYSTEM_SESSION_PROCESS_INFORMATION) SystemSessionProcessInformation32;
  1945. Length64 = 0;
  1946. if ((ARGUMENT_PRESENT (SystemInformation32)) &&
  1947. (SystemInformationLength > 0)) {
  1948. Length64 = (SystemInformationLength << 1);
  1949. SystemSessionProcessInformation64 = Wow64AllocateTemp (Length64);
  1950. SystemSessionProcessInformation64->SessionId = SystemSessionProcessInformation32->SessionId;
  1951. SystemSessionProcessInformation64->SizeOfBuf = Length64 - sizeof (*SystemSessionProcessInformation64);
  1952. SystemSessionProcessInformation64->Buffer = (PVOID)(SystemSessionProcessInformation64 + 1);
  1953. }
  1954. NtStatus = NtQuerySystemInformation (SystemInformationClass,
  1955. SystemSessionProcessInformation64,
  1956. Length64,
  1957. &ReturnLength64
  1958. );
  1959. //
  1960. // Thunk the return values. check if they fit into the original caller's buffer
  1961. //
  1962. if (NT_SUCCESS (NtStatus)) {
  1963. ULONG TotalSize = 0;
  1964. ULONG PoolTagCount;
  1965. ULONG BufferLen32;
  1966. //
  1967. // Move session pool information from the 64-bit side to the 32-bit side.
  1968. //
  1969. SystemSessionPoolTagInfo64 = (PSYSTEM_SESSION_POOLTAG_INFORMATION)SystemSessionProcessInformation64->Buffer;
  1970. SystemSessionPoolTagInfo32 = (NT32SYSTEM_SESSION_POOLTAG_INFORMATION *)SystemSessionProcessInformation32->Buffer;
  1971. BufferLen32 = SystemSessionProcessInformation32->SizeOfBuf;
  1972. while (TRUE) {
  1973. //
  1974. // Each session's pool
  1975. //
  1976. if ((TotalSize + sizeof (NT32SYSTEM_SESSION_POOLTAG_INFORMATION)) > BufferLen32) {
  1977. return STATUS_INFO_LENGTH_MISMATCH;
  1978. }
  1979. TotalSize += sizeof (NT32SYSTEM_SESSION_POOLTAG_INFORMATION);
  1980. SystemSessionPoolTagInfo32->NextEntryOffset = sizeof (NT32SYSTEM_SESSION_POOLTAG_INFORMATION);
  1981. SystemSessionPoolTagInfo32->SessionId = SystemSessionPoolTagInfo64->SessionId;
  1982. SystemSessionPoolTagInfo32->Count = SystemSessionPoolTagInfo64->Count;
  1983. //
  1984. // Each pool info
  1985. //
  1986. PoolTagCount = SystemSessionPoolTagInfo64->Count;
  1987. PoolTagInfo64 = SystemSessionPoolTagInfo64->TagInfo;
  1988. PoolTagInfo32 = (NT32SYSTEM_POOLTAG *)SystemSessionPoolTagInfo32->TagInfo;
  1989. if (PoolTagCount > 0) {
  1990. if ((TotalSize + ((PoolTagCount-1) * sizeof (SYSTEM_POOLTAG))) > BufferLen32) {
  1991. return STATUS_INFO_LENGTH_MISMATCH;
  1992. }
  1993. TotalSize += ((PoolTagCount-1) * sizeof (NT32SYSTEM_POOLTAG));
  1994. SystemSessionPoolTagInfo32->NextEntryOffset += ((PoolTagCount - 1) * sizeof (NT32SYSTEM_POOLTAG));
  1995. while (PoolTagCount > 0) {
  1996. @ForceType(PostCall,PoolTagInfo64,PoolTagInfo32,PSYSTEM_POOLTAG,OUT); @NL
  1997. PoolTagInfo64++;
  1998. PoolTagInfo32++;
  1999. PoolTagCount--;
  2000. }
  2001. }
  2002. if (SystemSessionPoolTagInfo64->NextEntryOffset == 0) {
  2003. break;
  2004. }
  2005. SystemSessionPoolTagInfo32 = (NT32SYSTEM_SESSION_POOLTAG_INFORMATION *)((PCHAR)SystemSessionPoolTagInfo32 + SystemSessionPoolTagInfo32->NextEntryOffset);
  2006. }
  2007. SystemSessionPoolTagInfo32->NextEntryOffset = 0;
  2008. if (ARGUMENT_PRESENT (ReturnLength32)) {
  2009. *ReturnLength32 = TotalSize;
  2010. }
  2011. } else {
  2012. if (ARGUMENT_PRESENT (ReturnLength32)) {
  2013. *ReturnLength32 = ReturnLength64;
  2014. }
  2015. }
  2016. } except (EXCEPTION_EXECUTE_HANDLER) {
  2017. NtStatus = GetExceptionCode ();
  2018. }
  2019. return NtStatus;
  2020. }
  2021. )
  2022. End=
  2023. SpecialQueryCase=
  2024. case SystemPerformanceTraceInformation: @NL
  2025. case SystemCallTimeInformation: @NL
  2026. case SystemPathInformation: @NL @Indent(
  2027. // Note: Not implemented in the kernel. @NL
  2028. return STATUS_NOT_IMPLEMENTED; @NL
  2029. )
  2030. case SystemVdmInstemulInformation: @NL
  2031. case SystemVdmBopInformation: @NL @Indent(
  2032. // Note: not supported since VDM is not supported. @NL
  2033. return STATUS_NOT_IMPLEMENTED; @NL
  2034. )
  2035. case SystemProcessInformation:
  2036. case SystemExtendedProcessInformation:
  2037. return whNT32QuerySystemProcessInformationEx (
  2038. SystemInformationClass,
  2039. SystemInformation,
  2040. SystemInformationLength,
  2041. ReturnLength
  2042. );
  2043. break;
  2044. case SystemSessionPoolTagInformation:
  2045. {
  2046. return whNT32QuerySystemSessionPoolTagInformation (
  2047. SystemInformationClass,
  2048. SystemInformation,
  2049. SystemInformationLength,
  2050. ReturnLength
  2051. );
  2052. }
  2053. break;
  2054. case SystemSessionProcessInformation:
  2055. {
  2056. NTSTATUS NtStatus;
  2057. try {
  2058. NtStatus =
  2059. whNT32QuerySystemSessionProcessInformation (
  2060. SystemInformationClass,
  2061. SystemInformation,
  2062. SystemInformationLength,
  2063. ReturnLength
  2064. );
  2065. } except (EXCEPTION_EXECUTE_HANDLER) {
  2066. NtStatus = GetExceptionCode ();
  2067. }
  2068. return NtStatus;
  2069. }
  2070. break;
  2071. case SystemSessionMappedViewInformation:
  2072. {
  2073. NTSTATUS NtStatus;
  2074. try {
  2075. NtStatus =
  2076. whNT32QuerySystemSessionMappedViewInformation (
  2077. SystemInformationClass,
  2078. SystemInformation,
  2079. SystemInformationLength,
  2080. ReturnLength
  2081. );
  2082. } except (EXCEPTION_EXECUTE_HANDLER) {
  2083. NtStatus = GetExceptionCode ();
  2084. }
  2085. return NtStatus;
  2086. }
  2087. break;
  2088. case SystemVerifierInformation:
  2089. {
  2090. NTSTATUS NtStatus;
  2091. try {
  2092. NtStatus =
  2093. whNT32QuerySystemVerifierInformation (
  2094. SystemInformationClass,
  2095. SystemInformation,
  2096. SystemInformationLength,
  2097. ReturnLength
  2098. );
  2099. } except (EXCEPTION_EXECUTE_HANDLER) {
  2100. NtStatus = GetExceptionCode ();
  2101. }
  2102. return NtStatus;
  2103. }
  2104. break;
  2105. case SystemNumaAvailableMemory:
  2106. {
  2107. return whNT32QuerySystemInformation (
  2108. SystemInformationClass,
  2109. SystemInformation,
  2110. SystemInformationLength,
  2111. ReturnLength
  2112. );
  2113. }
  2114. break;
  2115. case SystemProcessorPerformanceInformation:
  2116. {
  2117. NTSTATUS NtStatus;
  2118. PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION ProcessorPerformanceInformation64;
  2119. NT32SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *ProcessorPerformanceInformation32;
  2120. ULONG EntriesCount;
  2121. ULONG ReturnLength64;
  2122. ProcessorPerformanceInformation32 = (NT32SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *)SystemInformation;
  2123. if (SystemInformationLength < sizeof (NT32SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)) {
  2124. return STATUS_INFO_LENGTH_MISMATCH;
  2125. }
  2126. EntriesCount = SystemInformationLength / sizeof (NT32SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
  2127. if (ARGUMENT_PRESENT (ProcessorPerformanceInformation32)) {
  2128. ProcessorPerformanceInformation64 = Wow64AllocateTemp (EntriesCount * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
  2129. if (ProcessorPerformanceInformation64 == NULL) {
  2130. return STATUS_NO_MEMORY;
  2131. }
  2132. } else {
  2133. ProcessorPerformanceInformation64 = (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)ProcessorPerformanceInformation32;
  2134. }
  2135. NtStatus = whNT32QuerySystemInformation (
  2136. SystemInformationClass,
  2137. ProcessorPerformanceInformation64,
  2138. EntriesCount * sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION),
  2139. &ReturnLength64
  2140. );
  2141. if (NT_SUCCESS (NtStatus)) {
  2142. ASSERT ((ReturnLength64 / sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)) <= EntriesCount);
  2143. ReturnLength64 = ReturnLength64 / sizeof (SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
  2144. try {
  2145. EntriesCount = ReturnLength64;
  2146. while (ReturnLength64 > 0) {
  2147. @ForceType(PostCall,ProcessorPerformanceInformation64,ProcessorPerformanceInformation32,PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION,OUT); @NL
  2148. ProcessorPerformanceInformation64++;
  2149. ProcessorPerformanceInformation32++;
  2150. ReturnLength64--;
  2151. }
  2152. if (ARGUMENT_PRESENT (ReturnLength)) {
  2153. *ReturnLength = EntriesCount * sizeof (NT32SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION);
  2154. }
  2155. } except (EXCEPTION_EXECUTE_HANDLER) {
  2156. NtStatus = GetExceptionCode ();
  2157. }
  2158. }
  2159. return NtStatus;
  2160. }
  2161. break;
  2162. case SystemNumaProcessorMap:
  2163. {
  2164. NTSTATUS NtStatus;
  2165. ULONG ReturnLength64;
  2166. DWORD Counter;
  2167. PSYSTEM_NUMA_INFORMATION Map;
  2168. NtStatus = whNT32QuerySystemInformation (
  2169. SystemInformationClass,
  2170. SystemInformation,
  2171. SystemInformationLength,
  2172. &ReturnLength64
  2173. );
  2174. if (NT_SUCCESS (NtStatus)) {
  2175. try {
  2176. Map = (PSYSTEM_NUMA_INFORMATION) SystemInformation;
  2177. if (ReturnLength64 > sizeof(Map->HighestNodeNumber)) {
  2178. for (Counter = 0 ; Counter <= Map->HighestNodeNumber ; Counter++) {
  2179. Map->ActiveProcessorsAffinityMask [Counter] = Wow64ThunkAffinityMask64TO32 (Map->ActiveProcessorsAffinityMask [Counter]);
  2180. }
  2181. }
  2182. if (ARGUMENT_PRESENT (ReturnLength)) {
  2183. *ReturnLength = ReturnLength64;
  2184. }
  2185. } except (EXCEPTION_EXECUTE_HANDLER) {
  2186. NtStatus = GetExceptionCode ();
  2187. }
  2188. }
  2189. return NtStatus;
  2190. }
  2191. break;
  2192. case SystemLogicalProcessorInformation:
  2193. {
  2194. NT32SYSTEM_LOGICAL_PROCESSOR_INFORMATION *LogicalProcessorInfo32;
  2195. PSYSTEM_LOGICAL_PROCESSOR_INFORMATION LogicalProcessorInfo64;
  2196. ULONG EntriesCount;
  2197. ULONG ReturnLength64;
  2198. NTSTATUS NtStatus;
  2199. if (SystemInformationLength < sizeof (NT32SYSTEM_LOGICAL_PROCESSOR_INFORMATION)) {
  2200. return STATUS_INFO_LENGTH_MISMATCH;
  2201. }
  2202. LogicalProcessorInfo32 = (NT32SYSTEM_LOGICAL_PROCESSOR_INFORMATION *)SystemInformation;
  2203. EntriesCount = (SystemInformationLength / sizeof (NT32SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
  2204. LogicalProcessorInfo64 = Wow64AllocateTemp (EntriesCount * sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
  2205. if (LogicalProcessorInfo64 != NULL) {
  2206. NtStatus = whNT32QuerySystemInformation (
  2207. SystemInformationClass,
  2208. LogicalProcessorInfo64,
  2209. (EntriesCount * sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION)),
  2210. &ReturnLength64);
  2211. if (NT_SUCCESS (NtStatus)) {
  2212. EntriesCount = (ReturnLength64 / sizeof (SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
  2213. //
  2214. // Put the right count in.
  2215. //
  2216. if (ARGUMENT_PRESENT (ReturnLength)) {
  2217. *ReturnLength = (EntriesCount * sizeof (NT32SYSTEM_LOGICAL_PROCESSOR_INFORMATION));
  2218. }
  2219. //
  2220. // Thunk back
  2221. //
  2222. while (EntriesCount > 0) {
  2223. @ForceType(PostCall,LogicalProcessorInfo64,LogicalProcessorInfo32,PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,OUT); @NL
  2224. LogicalProcessorInfo32++;
  2225. LogicalProcessorInfo64++;
  2226. EntriesCount--;
  2227. }
  2228. }
  2229. } else {
  2230. NtStatus = STATUS_NO_MEMORY;
  2231. }
  2232. return NtStatus;
  2233. }
  2234. break;
  2235. End=
  2236. Begin=
  2237. #define WriteReturnLength(rl, length) WriteReturnLengthStatus((rl), &RetVal, (length))
  2238. @GenQueryThunk(whNT32QuerySystemInformation,SystemInformationClass,SystemInformation,SystemInformationLength,ReturnLength,ULONG)
  2239. #undef WriteReturnLength
  2240. End=
  2241. TemplateName=NtWow64GetNativeSystemInformation
  2242. Case=(SystemBasicInformation,PSYSTEM_BASIC_INFORMATION)
  2243. Case=(SystemProcessorInformation,PSYSTEM_PROCESSOR_INFORMATION)
  2244. Case=(SystemEmulationBasicInformation,PSYSTEM_BASIC_INFORMATION)
  2245. Case=(SystemEmulationProcessorInformation,PSYSTEM_PROCESSOR_INFORMATION)
  2246. Begin=
  2247. #define WriteReturnLength(rl, length) WriteReturnLengthStatus((rl), &RetVal, (length))
  2248. @GenQueryThunk(NtQuerySystemInformation,SystemInformationClass,NativeSystemInformation,InformationLength,ReturnLength,ULONG)
  2249. #undef WriteReturnLength
  2250. End=
  2251. TemplateName=NtWow64QueryInformationProcess64
  2252. Case=(ProcessBasicInformation,PPROCESS_BASIC_INFORMATION64)
  2253. ; more ok here as needed
  2254. Header=
  2255. End=
  2256. Begin=
  2257. @GenDebugNonPtrDepCases(NtQueryInformationProcess,ProcessInformationClass)
  2258. End=
  2259. TemplateName=NtWow64ReadVirtualMemory64
  2260. Begin=
  2261. @GenApiThunk(NtReadVirtualMemory)
  2262. End=
  2263. TemplateName=NtWow64QueryVirtualMemory64
  2264. Case=(MemoryBasicInformation,PMEMORY_BASIC_INFORMATION64)
  2265. ; more ok here as needed
  2266. Header=
  2267. End=
  2268. Begin=
  2269. @GenDebugNonPtrDepCases(NtQueryVirtualMemory,MemoryInformationClass)
  2270. End=
  2271. TemplateName=NtQuerySemaphore
  2272. Case=(SemaphoreBasicInformation,PSEMAPHORE_BASIC_INFORMATION)
  2273. Begin=
  2274. @GenDebugNonPtrDepCases(@ApiName,SemaphoreInformationClass)
  2275. End=
  2276. TemplateName=NtQueryVirtualMemory
  2277. Case=(MemoryBasicInformation,PMEMORY_BASIC_INFORMATION)
  2278. Case=(MemoryWorkingSetInformation)
  2279. Case=(MemoryMappedFilenameInformation,POBJECT_NAME_INFORMATION)
  2280. Begin=
  2281. #define WriteReturnLength(rl, length) WriteReturnLengthSilent((PULONG)(rl), (ULONG)(length))
  2282. @GenQueryThunk(@ApiName,MemoryInformationClass,MemoryInformation,MemoryInformationLength,ReturnLength,SIZE_T)
  2283. #undef WriteReturnLength
  2284. End=
  2285. SpecialQueryCase=
  2286. case MemoryWorkingSetInformation: @NL
  2287. {
  2288. PMEMORY_WORKING_SET_INFORMATION MemoryWorkingSetInfo64;
  2289. PMEMORY_WORKING_SET_BLOCK MemoryWorkingSetBlock64;
  2290. NT32MEMORY_WORKING_SET_INFORMATION *MemoryWorkingSetInfo32;
  2291. NT32MEMORY_WORKING_SET_BLOCK *MemoryWorkingSetBlock32;
  2292. ULONG InformationLength32 = MemoryInformationLength;
  2293. SIZE_T ReturnLength64;
  2294. ULONG Count;
  2295. ReturnLength64 = 0;
  2296. if (InformationLength32 < sizeof (ULONG)) {
  2297. return STATUS_INFO_LENGTH_MISMATCH;
  2298. }
  2299. ReturnLength64 += sizeof (ULONG_PTR);
  2300. InformationLength32 -= sizeof (ULONG);
  2301. ReturnLength64 += ((InformationLength32 / sizeof (NT32MEMORY_WORKING_SET_BLOCK)) * sizeof (MEMORY_WORKING_SET_BLOCK));
  2302. MemoryWorkingSetInfo64 = Wow64AllocateTemp (ReturnLength64);
  2303. if (MemoryWorkingSetInfo64 == NULL) {
  2304. return STATUS_NO_MEMORY;
  2305. }
  2306. RetVal = NtQueryVirtualMemory (ProcessHandle,
  2307. BaseAddress,
  2308. MemoryInformationClass,
  2309. MemoryWorkingSetInfo64,
  2310. ReturnLength64,
  2311. &ReturnLength64);
  2312. if (NT_SUCCESS (RetVal)) {
  2313. try {
  2314. MemoryWorkingSetInfo32 = (NT32MEMORY_WORKING_SET_INFORMATION *) MemoryInformation;
  2315. MemoryWorkingSetInfo32->NumberOfEntries = MemoryWorkingSetInfo64->NumberOfEntries;
  2316. MemoryWorkingSetBlock32 = (NT32MEMORY_WORKING_SET_BLOCK *) &MemoryWorkingSetInfo32->WorkingSetInfo [0];
  2317. MemoryWorkingSetBlock64 = &MemoryWorkingSetInfo64->WorkingSetInfo [0];
  2318. while (Count > 0) {
  2319. @ForceType(PostCall,MemoryWorkingSetBlock64,MemoryWorkingSetBlock32,PMEMORY_WORKING_SET_BLOCK,OUT); @NL
  2320. Count--;
  2321. MemoryWorkingSetBlock32++;
  2322. MemoryWorkingSetBlock64++;
  2323. }
  2324. if (ARGUMENT_PRESENT (ReturnLength)) {
  2325. *ReturnLength = (((MemoryWorkingSetInfo32->NumberOfEntries - 1) * sizeof (ULONG)) + sizeof (NT32MEMORY_WORKING_SET_INFORMATION));
  2326. }
  2327. } except (EXCEPTION_EXECUTE_HANDLER) {
  2328. RetVal = GetExceptionCode ();
  2329. }
  2330. }
  2331. }
  2332. break; @NL
  2333. End=
  2334. TemplateName=NtQueryVirtualMemory64
  2335. Case=(MemoryBasicInformation,PUCHAR)
  2336. Case=(MemoryWorkingSetInformation,PMEMORY_WORKING_SET_INFORMATION)
  2337. Case=(MemoryMappedFilenameInformation,POBJECT_NAME_INFORMATION)
  2338. Begin=
  2339. #define WriteReturnLength(rl, length) WriteReturnLengthSilent((rl), (length))
  2340. @GenQueryThunk(@ApiName,MemoryInformationClass,MemoryInformation,MemoryInformationLength,ReturnLength,SIZE_T)
  2341. #undef WriteReturnLength
  2342. End=
  2343. TemplateName=NtQueryVolumeInformationFile
  2344. Case=(FileFsVolumeInformation,PFILE_FS_VOLUME_INFORMATION)
  2345. Case=(FileFsLabelInformation,PFILE_FS_LABEL_INFORMATION)
  2346. Case=(FileFsSizeInformation,PFILE_FS_SIZE_INFORMATION)
  2347. Case=(FileFsDeviceInformation,PFILE_FS_DEVICE_INFORMATION)
  2348. Case=(FileFsAttributeInformation,PFILE_FS_ATTRIBUTE_INFORMATION)
  2349. Case=(FileFsControlInformation,PFILE_FS_CONTROL_INFORMATION)
  2350. Case=(FileFsFullSizeInformation,PFILE_FS_FULL_SIZE_INFORMATION)
  2351. Case=(FileFsObjectIdInformation,PFILE_FS_OBJECTID_INFORMATION)
  2352. Case=(FileFsDriverPathInformation,PFILE_FS_DRIVER_PATH_INFORMATION)
  2353. Begin=
  2354. @GenDebugNonPtrDepCases(@ApiName,FsInformationClass)
  2355. End=
  2356. TemplateName=NtRaiseHardError
  2357. NoType=Parameters
  2358. Header=
  2359. @NoFormat(
  2360. NTSTATUS
  2361. whNT32RaiseHardError(
  2362. IN NTSTATUS ErrorStatus,
  2363. IN ULONG NumberOfParameters,
  2364. IN ULONG UnicodeStringParameterMask,
  2365. IN PVOID Parameters, //these parameters are not thunked yet(PULONG).
  2366. IN ULONG ValidResponseOptions,
  2367. OUT PULONG Response
  2368. )
  2369. {
  2370. ULONG ParameterCount;
  2371. PULONG Parameters32;
  2372. PULONG_PTR Parameters64;
  2373. Parameters32 = (PULONG)Parameters;
  2374. Parameters64 = Wow64AllocateTemp(NumberOfParameters * sizeof(ULONG_PTR));
  2375. for(ParameterCount=0; ParameterCount < NumberOfParameters; ParameterCount++) {
  2376. if (UnicodeStringParameterMask & (1<<ParameterCount)) {
  2377. //Parameter is a UNICODE_STRING
  2378. Parameters64[ParameterCount] = (ULONG_PTR)Wow64ShallowThunkAllocUnicodeString32TO64(Parameters32[ParameterCount]);
  2379. }
  2380. else {
  2381. Parameters64[ParameterCount] = (ULONG_PTR)Parameters32[ParameterCount];
  2382. }
  2383. }
  2384. return NtRaiseHardError(ErrorStatus,
  2385. NumberOfParameters,
  2386. UnicodeStringParameterMask,
  2387. Parameters64,
  2388. ValidResponseOptions,
  2389. Response
  2390. );
  2391. }
  2392. )
  2393. End=
  2394. PreCall=
  2395. Parameters = (PULONG_PTR)ParametersHost; @NL
  2396. Begin=
  2397. @GenApiThunk(whNT32RaiseHardError)
  2398. End=
  2399. TemplateName=NtSetInformationJobObject
  2400. Case=(JobObjectBasicLimitInformation,PJOBOBJECT_BASIC_LIMIT_INFORMATION)
  2401. Case=(JobObjectExtendedLimitInformation,PJOBOBJECT_EXTENDED_LIMIT_INFORMATION)
  2402. Case=(JobObjectBasicUIRestrictions,PJOBOBJECT_BASIC_UI_RESTRICTIONS)
  2403. Case=(JobObjectEndOfJobTimeInformation,PJOBOBJECT_END_OF_JOB_TIME_INFORMATION)
  2404. Case=(JobObjectAssociateCompletionPortInformation,PJOBOBJECT_ASSOCIATE_COMPLETION_PORT)
  2405. Case=(JobObjectSecurityLimitInformation,PJOBOBJECT_SECURITY_LIMIT_INFORMATION)
  2406. Begin=
  2407. @GenSetThunk(@ApiName,JobObjectInformationClass,JobObjectInformation,JobObjectInformationLength)
  2408. End=
  2409. TemplateName=NtCreateJobSet
  2410. NoType=UserJobSet
  2411. Locals=
  2412. UserJobSet = (PJOB_SET_ARRAY)UlongToPtr(UserJobSetHost);
  2413. End=
  2414. PreCall=
  2415. if ((NumJob > 0) &&
  2416. (ARGUMENT_PRESENT (UserJobSet) != 0)) {
  2417. ULONG JobIndex;
  2418. NT32JOB_SET_ARRAY *UserJobSet32 = (NT32JOB_SET_ARRAY *)UlongToPtr(UserJobSetHost);
  2419. UserJobSet = Wow64AllocateTemp (NumJob * sizeof (JOB_SET_ARRAY));
  2420. if (UserJobSet == NULL) {
  2421. return STATUS_NO_MEMORY;
  2422. }
  2423. try {
  2424. for (JobIndex = 0 ; JobIndex < NumJob ; JobIndex++) {
  2425. UserJobSet[JobIndex].Flags = UserJobSet32[JobIndex].Flags;
  2426. UserJobSet[JobIndex].MemberLevel = UserJobSet32[JobIndex].MemberLevel;
  2427. UserJobSet[JobIndex].JobHandle = LongToPtr(UserJobSet32[JobIndex].JobHandle);
  2428. }
  2429. } except (EXCEPTION_EXECUTE_HANDLER) {
  2430. return GetExceptionCode ();
  2431. }
  2432. }
  2433. End=
  2434. Begin=
  2435. @GenApiThunk(@ApiName)
  2436. End=
  2437. TemplateName=NtSetInformationObject
  2438. Case=(ObjectHandleFlagInformation,POBJECT_HANDLE_FLAG_INFORMATION)
  2439. Begin=
  2440. @GenDebugNonPtrDepCases(@ApiName,ObjectInformationClass)
  2441. End=
  2442. TemplateName=NtSetInformationProcess
  2443. Header=
  2444. @NoFormat(
  2445. NTSTATUS
  2446. whNtSetInformationProcessEnableAlignmentFaultFixup(IN HANDLE ProcessHandle,
  2447. IN PROCESSINFOCLASS ProcessInformationClass,
  2448. IN PVOID ProcessInformationHost,
  2449. IN ULONG ProcessInformationLength
  2450. )
  2451. { @Indent( @NL
  2452. // Force enabling of alignment fixup since 32bit NT silently ignored this setting and always
  2453. // fixed up alignment faults.
  2454. BOOLEAN b = TRUE;
  2455. if (!ProcessInformationHost) {
  2456. return STATUS_INVALID_PARAMETER;
  2457. }
  2458. if (sizeof(BOOLEAN) != ProcessInformationLength) {
  2459. return STATUS_INFO_LENGTH_MISMATCH;
  2460. }
  2461. return NtSetInformationProcess(ProcessHandle,
  2462. ProcessInformationClass,
  2463. &b,
  2464. sizeof(BOOLEAN));
  2465. }
  2466. NTSTATUS
  2467. whNtSetInformationProcessDefaultHardErrorMode(IN HANDLE ProcessHandle,
  2468. IN PROCESSINFOCLASS ProcessInformationClass,
  2469. IN PVOID ProcessInformationHost,
  2470. IN ULONG ProcessInformationLength
  2471. )
  2472. { @Indent( @NL
  2473. // Force enabling of alignment fixup since 32bit NT silently ignored this setting and always
  2474. // fixed up alignment faults.
  2475. ULONG ul;
  2476. if (!ProcessInformationHost) {
  2477. return STATUS_INVALID_PARAMETER;
  2478. }
  2479. if (sizeof(ULONG) != ProcessInformationLength) {
  2480. return STATUS_INFO_LENGTH_MISMATCH;
  2481. }
  2482. ul = *(ULONG *)ProcessInformationHost | PROCESS_HARDERROR_ALIGNMENT_BIT;
  2483. return NtSetInformationProcess(ProcessHandle,
  2484. ProcessInformationClass,
  2485. &ul,
  2486. sizeof(ULONG));
  2487. }
  2488. NTSTATUS
  2489. whNtSetInformationProcessAffinityMask(
  2490. IN HANDLE ProcessHandle,
  2491. IN PROCESSINFOCLASS ProcessInformationClass,
  2492. IN PVOID ProcessInformation,
  2493. IN ULONG ProcessInformationLength
  2494. )
  2495. {
  2496. ULONG_PTR AffinityMask;
  2497. if ((NULL == ProcessInformation) || (ProcessInformationLength != sizeof(ULONG))) {
  2498. // Let the NT Api fail this call with the correct return code.
  2499. return NtSetInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength);
  2500. }
  2501. AffinityMask = Wow64ThunkAffinityMask32TO64(*(PULONG)ProcessInformation);
  2502. return NtSetInformationProcess(ProcessHandle, ProcessInformationClass, &AffinityMask, sizeof(AffinityMask));
  2503. }
  2504. )
  2505. End=
  2506. Case=(ProcessBasicInformation)
  2507. Case=(ProcessWorkingSetWatch)
  2508. Case=(ProcessEnableAlignmentFaultFixup)
  2509. Case=(ProcessAffinityMask)
  2510. Case=(ProcessDefaultHardErrorMode)
  2511. Case=(ProcessQuotaLimits)
  2512. Case=(ProcessIoCounters,PULONG)
  2513. Case=(ProcessVmCounters,PVM_COUNTERS)
  2514. Case=(ProcessTimes,PKERNEL_USER_TIMES)
  2515. Case=(ProcessBasePriority,KPRIORITY*)
  2516. Case=(ProcessRaisePriority,PULONG)
  2517. Case=(ProcessDebugPort,PHANDLE)
  2518. Case=(ProcessExceptionPort,PHANDLE)
  2519. Case=(ProcessAccessToken,PPROCESS_ACCESS_TOKEN)
  2520. Case=(ProcessLdtInformation)
  2521. Case=(ProcessLdtSize)
  2522. Case=(ProcessPooledUsageAndLimits,PPOOLED_USAGE_AND_LIMITS)
  2523. Case=(ProcessUserModeIOPL)
  2524. Case=(ProcessPriorityClass,PPROCESS_PRIORITY_CLASS)
  2525. Case=(ProcessWx86Information,PHANDLE)
  2526. Case=(ProcessHandleCount,PULONG)
  2527. Case=(ProcessPriorityBoost,PULONG)
  2528. Case=(ProcessDeviceMap,PPROCESS_DEVICEMAP_INFORMATION)
  2529. Case=(ProcessSessionInformation,PPROCESS_SESSION_INFORMATION)
  2530. Case=(ProcessForegroundInformation,PPROCESS_FOREGROUND_BACKGROUND)
  2531. Case=(ProcessHandleTracing,PPROCESS_HANDLE_TRACING_ENABLE)
  2532. Case=(ProcessWow64Information,PULONG_PTR)
  2533. SpecialSetCase=
  2534. case ProcessWorkingSetWatch: @NL @Indent(
  2535. WOWASSERT(TRUE);
  2536. return STATUS_NOT_IMPLEMENTED;
  2537. )
  2538. case ProcessEnableAlignmentFaultFixup: @NL @Indent(
  2539. @CallApi(whNtSetInformationProcessEnableAlignmentFaultFixup,RetVal)
  2540. break;
  2541. )
  2542. case ProcessQuotaLimits: @NL @Indent(
  2543. {
  2544. PQUOTA_LIMITS QuotaLimits64Ptr;
  2545. QUOTA_LIMITS QuotaLimitsNotEx64;
  2546. PQUOTA_LIMITS_EX QuotaLimitsEx64Ptr;
  2547. QUOTA_LIMITS_EX QuotaLimitsEx64;
  2548. RetVal = STATUS_SUCCESS;
  2549. try {
  2550. if (ProcessInformationLength == sizeof (NT32QUOTA_LIMITS)) {
  2551. PQUOTA_LIMITS QuotaLimits64PtrCopy = &QuotaLimitsNotEx64;
  2552. @ForceType(PreCall,QuotaLimits64Ptr,(NT32QUOTA_LIMITS *)ProcessInformation,PQUOTA_LIMITS,IN) @NL
  2553. ProcessInformationLength = sizeof (QUOTA_LIMITS);
  2554. ProcessInformation = (PVOID)QuotaLimits64Ptr;
  2555. } else if (ProcessInformationLength == sizeof (NT32QUOTA_LIMITS_EX)) {
  2556. PQUOTA_LIMITS_EX QuotaLimitsEx64PtrCopy = &QuotaLimitsEx64;
  2557. @ForceType(PreCall,QuotaLimitsEx64Ptr,(NT32QUOTA_LIMITS_EX *)ProcessInformation,PQUOTA_LIMITS_EX,IN) @NL
  2558. ProcessInformation = (PVOID)QuotaLimitsEx64Ptr;
  2559. ProcessInformationLength = sizeof (QUOTA_LIMITS_EX);
  2560. } else {
  2561. RetVal = STATUS_INFO_LENGTH_MISMATCH;
  2562. }
  2563. } except (EXCEPTION_EXECUTE_HANDLER) {
  2564. RetVal = GetExceptionCode ();
  2565. }
  2566. if (NT_SUCCESS (RetVal)) {
  2567. RetVal = NtSetInformationProcess (ProcessHandle,
  2568. ProcessInformationClass,
  2569. ProcessInformation,
  2570. ProcessInformationLength
  2571. );
  2572. }
  2573. break;
  2574. }
  2575. )
  2576. case ProcessAffinityMask: @NL @Indent(
  2577. @CallApi(whNtSetInformationProcessAffinityMask,RetVal)
  2578. break;
  2579. )
  2580. case ProcessDefaultHardErrorMode: @NL @Indent(
  2581. @CallApi(whNtSetInformationProcessDefaultHardErrorMode,RetVal)
  2582. break;
  2583. )
  2584. Begin=
  2585. @GenSetThunk(@ApiName,ProcessInformationClass,ProcessInformation,ProcessInformationLength)
  2586. End=
  2587. TemplateName=NtSetInformationThread
  2588. Header=
  2589. @NoFormat(
  2590. NTSTATUS
  2591. whNtSetInformationThreadAffinityMask(
  2592. IN HANDLE ThreadHandle,
  2593. IN THREADINFOCLASS ThreadInformationClass,
  2594. IN PVOID ThreadInformation,
  2595. IN ULONG ThreadInformationLength
  2596. )
  2597. {
  2598. ULONG Affinity32;
  2599. ULONG_PTR Affinity64;
  2600. NTSTATUS StatusApi, StTemp;
  2601. HANDLE ProcessHandle;
  2602. THREAD_BASIC_INFORMATION ThreadInfo;
  2603. PROCESS_BASIC_INFORMATION ProcessInfo;
  2604. OBJECT_ATTRIBUTES ObjectAttributes;
  2605. if (NULL == ThreadInformation) {
  2606. return STATUS_INVALID_PARAMETER;
  2607. }
  2608. if (sizeof(ULONG) != ThreadInformationLength) {
  2609. return STATUS_INFO_LENGTH_MISMATCH;
  2610. }
  2611. Affinity32 = *(PULONG)ThreadInformation;
  2612. Affinity64 = Wow64ThunkAffinityMask32TO64(Affinity32);
  2613. StatusApi = NtSetInformationThread(ThreadHandle,
  2614. ThreadInformationClass,
  2615. &Affinity64,
  2616. sizeof(Affinity64));
  2617. if (StatusApi != STATUS_INVALID_PARAMETER) {
  2618. return StatusApi;
  2619. }
  2620. //Attempt to bash the thread affinity into being a subset of the process affinity.
  2621. //This should only happen if process the process affinty or thread affinity
  2622. //had some of the upper bits set set by some external entity and the app is trying
  2623. //to compute the thread affinity by subtracting bits from the process affinity.
  2624. //So query the process affinity, and try to mask off the bits. If we don't have
  2625. //permission to query the process affinity, fail the API.
  2626. StTemp = NtQueryInformationThread(ThreadHandle,
  2627. ThreadBasicInformation,
  2628. &ThreadInfo,
  2629. sizeof(ThreadInfo),
  2630. NULL);
  2631. if (!NT_SUCCESS(StTemp)) {
  2632. return StatusApi;
  2633. }
  2634. InitializeObjectAttributes(&ObjectAttributes,
  2635. NULL,
  2636. 0,
  2637. NULL,
  2638. NULL
  2639. );
  2640. StTemp = NtOpenProcess(&ProcessHandle,
  2641. PROCESS_VM_READ | PROCESS_QUERY_INFORMATION,
  2642. &ObjectAttributes, //ObjectAttributes
  2643. &(ThreadInfo.ClientId)
  2644. );
  2645. if (!NT_SUCCESS(StTemp)) {
  2646. return StatusApi;
  2647. }
  2648. StTemp = NtQueryInformationProcess(ProcessHandle,
  2649. ProcessBasicInformation,
  2650. &ProcessInfo,
  2651. sizeof(ProcessInfo),
  2652. NULL);
  2653. if (!NT_SUCCESS(StTemp)) {
  2654. goto done;
  2655. }
  2656. // Try to set the Affinity mask again after anding it with the process affinity.
  2657. // If this also fails, nothing more can be done. Just exit.
  2658. Affinity64 &= ProcessInfo.AffinityMask;
  2659. StatusApi = NtSetInformationThread(ThreadHandle,
  2660. ThreadInformationClass,
  2661. &Affinity64,
  2662. sizeof(Affinity64));
  2663. done:
  2664. NtClose(ProcessHandle);
  2665. return StatusApi;
  2666. }
  2667. End=
  2668. Case=(ThreadPriority,KPRIORITY*)
  2669. Case=(ThreadBasePriority,PLONG)
  2670. Case=(ThreadEnableAlignmentFaultFixup,PBOOLEAN)
  2671. Case=(ThreadImpersonationToken,PHANDLE)
  2672. Case=(ThreadQuerySetWin32StartAddress,PULONG_PTR)
  2673. Case=(ThreadIdealProcessor,PULONG)
  2674. Case=(ThreadPriorityBoost,PULONG)
  2675. Case=(ThreadZeroTlsCell,PULONG)
  2676. Case=(ThreadSetTlsArrayAddress,PVOID*)
  2677. Case=(ThreadHideFromDebugger)
  2678. Case=(ThreadAffinityMask)
  2679. SpecialSetCase=
  2680. case ThreadAffinityMask: @Indent( @NL
  2681. @CallApi(whNtSetInformationThreadAffinityMask,RetVal)
  2682. break; @NL
  2683. )@NL
  2684. case ThreadHideFromDebugger: @Indent( @NL
  2685. @CallApi(@ApiName,RetVal);
  2686. break; @NL
  2687. )@NL
  2688. End=
  2689. Begin=
  2690. @GenSetThunk(@ApiName,ThreadInformationClass,ThreadInformation,ThreadInformationLength)
  2691. End=
  2692. TemplateName=NtSetInformationToken
  2693. Case=(TokenOwner,PTOKEN_OWNER)
  2694. Case=(TokenPrimaryGroup,PTOKEN_PRIMARY_GROUP)
  2695. Case=(TokenDefaultDacl,PTOKEN_DEFAULT_DACL)
  2696. Case=(TokenSessionId,PULONG)
  2697. Case=(TokenSessionReference,PULONG)
  2698. Begin=
  2699. @GenSetThunk(@ApiName,TokenInformationClass,TokenInformation,TokenInformationLength)
  2700. End=
  2701. TemplateName=NtSetSystemInformation
  2702. Case=(SystemFlagsInformation,PSYSTEM_FLAGS_INFORMATION)
  2703. Case=(SystemTimeAdjustmentInformation,PSYSTEM_SET_TIME_ADJUST_INFORMATION)
  2704. Case=(SystemTimeSlipNotification,PHANDLE)
  2705. Case=(SystemRegistryQuotaInformation,PSYSTEM_REGISTRY_QUOTA_INFORMATION)
  2706. Case=(SystemPrioritySeperation,PULONG)
  2707. Case=(SystemExtendServiceTableInformation,PUNICODE_STRING)
  2708. Case=(SystemVerifierAddDriverInformation,PUNICODE_STRING)
  2709. Case=(SystemVerifierRemoveDriverInformation,PUNICODE_STRING)
  2710. Case=(SystemFileCacheInformation,PSYSTEM_FILECACHE_INFORMATION)
  2711. Case=(SystemDpcBehaviorInformation,PSYSTEM_DPC_BEHAVIOR_INFORMATION)
  2712. Case=(SystemSessionCreate,PULONG)
  2713. Case=(SystemSessionDetach,PULONG)
  2714. Case=(SystemComPlusPackage,PULONG)
  2715. Case=(SystemUnloadGdiDriverInformation)
  2716. Case=(SystemLoadGdiDriverInformation)
  2717. Case=(SystemVerifierInformation,PULONG)
  2718. SpecialSetCase=
  2719. //Only valid from kmode. @NL
  2720. case SystemUnloadGdiDriverInformation: @NL
  2721. case SystemLoadGdiDriverInformation: @NL
  2722. return STATUS_PRIVILEGE_NOT_HELD; @NL
  2723. End=
  2724. Begin=
  2725. @GenSetThunk(@ApiName,SystemInformationClass,SystemInformation,SystemInformationLength)
  2726. End=
  2727. TemplateName=NtWaitForMultipleObjects
  2728. NoType=Handles
  2729. Locals=
  2730. HANDLE *TempHandles; @NL
  2731. NT32HANDLE *TempHandlesHost; @NL
  2732. UINT TempIndex; @NL
  2733. End=
  2734. PreCall=
  2735. TempHandlesHost = (NT32HANDLE *)HandlesHost; @NL
  2736. TempHandles = Wow64AllocateTemp(sizeof(HANDLE) * Count); @NL
  2737. try { @NL
  2738. for(TempIndex = 0; TempIndex < Count; TempIndex++) { @NL
  2739. @Indent(
  2740. TempHandles[TempIndex] = (HANDLE)TempHandlesHost[TempIndex]; @NL
  2741. )
  2742. } @NL
  2743. } except (EXCEPTION_EXECUTE_HANDLER) { @NL
  2744. return GetExceptionCode (); @NL
  2745. } @NL
  2746. Handles = (HANDLE *)TempHandles; @NL
  2747. End=
  2748. PostCall=
  2749. End=
  2750. TemplateName=NtCompactKeys
  2751. NoType=KeyArray
  2752. Locals=
  2753. HANDLE *TempHandles; @NL
  2754. NT32HANDLE *TempHandlesHost; @NL
  2755. UINT TempIndex; @NL
  2756. End=
  2757. PreCall=
  2758. TempHandlesHost = (NT32HANDLE *)KeyArrayHost; @NL
  2759. TempHandles = Wow64AllocateTemp(sizeof(HANDLE) * Count); @NL
  2760. try { @NL
  2761. for(TempIndex = 0; TempIndex < Count; TempIndex++) { @NL
  2762. @Indent(
  2763. TempHandles[TempIndex] = (HANDLE)TempHandlesHost[TempIndex]; @NL
  2764. )
  2765. } @NL
  2766. } except (EXCEPTION_EXECUTE_HANDLER) { @NL
  2767. return GetExceptionCode (); @NL
  2768. } @NL
  2769. KeyArray = (HANDLE *)TempHandles; @NL
  2770. End=
  2771. PostCall=
  2772. End=
  2773. ;; These APIs take an APC routine.
  2774. TemplateName=NtQueueApcThread
  2775. PreCall=
  2776. Wow64WrapApcProc(&ApcRoutine, &ApcArgument1);
  2777. End=
  2778. TemplateName=NtSetTimer
  2779. PreCall=
  2780. Wow64WrapApcProc(&TimerApcRoutine, &TimerContext);
  2781. End=
  2782. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2783. ;;
  2784. ;; IO Routines
  2785. ;; Special handling is needed since they can be asynchronous.
  2786. ;;
  2787. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  2788. [Macros]
  2789. MacroName=AsynchronousIoPrecall
  2790. NumArgs=0
  2791. Begin=
  2792. Wow64WrapApcProc(&ApcRoutine, &ApcContext); @NL
  2793. { @Indent( @NL
  2794. NTSTATUS Status; @NL
  2795. IO_STATUS_BLOCK IosbTemp; @NL
  2796. FILE_MODE_INFORMATION ModeInfo; @NL
  2797. @NL
  2798. // Determine if the file is opened for asynchronous access. @NL
  2799. Status = NtQueryInformationFile(FileHandle, &IosbTemp, &ModeInfo, sizeof(ModeInfo), FileModeInformation); @NL
  2800. // This API will only return STATUS_SUCCESS on success; @NL
  2801. if (STATUS_SUCCESS != Status) { @Indent( @NL
  2802. RtlRaiseStatus(Status); @NL
  2803. )} @NL
  2804. if (!((ModeInfo.Mode & FILE_SYNCHRONOUS_IO_ALERT) || (ModeInfo.Mode & FILE_SYNCHRONOUS_IO_NONALERT))) { @Indent( @NL
  2805. // In this case, the operation will be asynchronous and a 32bit IO_STATUS_BLOCK will be passed. @NL
  2806. // Signal the kernel that a 32bit Iosb is being passed in. @NL
  2807. ApcRoutine = (PIO_APC_ROUTINE)((LONG_PTR)ApcRoutine | 1); @NL
  2808. // Signal the thunk that a 32bit Iosb is being passed in. @NL
  2809. IoStatusBlock = (PIO_STATUS_BLOCK)IoStatusBlockHost; @NL
  2810. AsynchronousIo = TRUE; @NL
  2811. )} @NL
  2812. if (ModeInfo.Mode & FILE_SYNCHRONOUS_IO_ALERT) {
  2813. AlertableIo = TRUE;
  2814. }
  2815. )} @NL
  2816. End=
  2817. [EFunc]
  2818. TemplateName=NtLockFile
  2819. Also=NtReadFile
  2820. Also=NtWriteFile
  2821. Also=NtNotifyChangeDirectoryFile
  2822. Locals=
  2823. BOOLEAN AsynchronousIo = FALSE;
  2824. BOOLEAN AlertableIo = FALSE;
  2825. End=
  2826. PreCall=
  2827. @AsynchronousIoPrecall
  2828. End=
  2829. TemplateName=NtFsControlFile
  2830. Also=NtDeviceIoControlFile
  2831. Locals=
  2832. BOOLEAN AsynchronousIo = FALSE;
  2833. BOOLEAN AlertableIo = FALSE;
  2834. BOOLEAN BuffersRealigned = FALSE;
  2835. PVOID OriginalInputBuffer;
  2836. PVOID OriginalOutputBuffer;
  2837. ULONG Ioctl = pBaseArgs[5];
  2838. HANDLE OriginalEvent;
  2839. End=
  2840. PreCall=
  2841. @AsynchronousIoPrecall
  2842. {@Indent( @NL
  2843. OriginalInputBuffer = InputBuffer;
  2844. OriginalOutputBuffer = OutputBuffer;
  2845. if (IS_IOCTL_REALIGNMENT_REQUIRED (Ioctl)) {
  2846. if ((InputBuffer != NULL) && (InputBufferLength > 0)) {
  2847. if (((ULONG_PTR)InputBuffer & ((MAX_NATURAL_ALIGNMENT) - 1)) != 0) {
  2848. InputBuffer = Wow64AllocateTemp (InputBufferLength);
  2849. if (InputBuffer == NULL) {
  2850. return STATUS_NO_MEMORY;
  2851. }
  2852. RetVal = STATUS_SUCCESS;
  2853. try {
  2854. RtlCopyMemory (InputBuffer,
  2855. OriginalInputBuffer,
  2856. InputBufferLength
  2857. );
  2858. }
  2859. except (EXCEPTION_EXECUTE_HANDLER) {
  2860. RetVal = GetExceptionCode ();
  2861. }
  2862. if (!NT_SUCCESS (RetVal)) {
  2863. return RetVal;
  2864. }
  2865. BuffersRealigned = TRUE;
  2866. }
  2867. }
  2868. if ((OutputBuffer != NULL) && (OutputBufferLength > 0)) {
  2869. if (((ULONG_PTR)OutputBuffer & ((MAX_NATURAL_ALIGNMENT) - 1)) != 0) {
  2870. OutputBuffer = Wow64AllocateTemp (OutputBufferLength);
  2871. if (OutputBuffer == NULL) {
  2872. return STATUS_NO_MEMORY;
  2873. }
  2874. BuffersRealigned = TRUE;
  2875. }
  2876. }
  2877. if ((BuffersRealigned == TRUE) && (AsynchronousIo == TRUE)) {
  2878. OriginalEvent = Event;
  2879. RetVal = NtCreateEvent (&Event,
  2880. EVENT_ALL_ACCESS,
  2881. NULL,
  2882. SynchronizationEvent,
  2883. FALSE
  2884. );
  2885. if (!NT_SUCCESS (RetVal)) {
  2886. return RetVal;
  2887. }
  2888. }
  2889. }
  2890. )} @NL
  2891. End=
  2892. PostCall=
  2893. {@Indent( @NL
  2894. if (BuffersRealigned == TRUE) {
  2895. if (NT_SUCCESS (RetVal)) {
  2896. if (RetVal == STATUS_PENDING) {
  2897. if (AsynchronousIo == TRUE) {
  2898. RetVal = NtWaitForSingleObject (Event,
  2899. AlertableIo,
  2900. NULL);
  2901. }
  2902. }
  2903. if (NT_SUCCESS (RetVal)) {
  2904. if (OutputBuffer != OriginalOutputBuffer) {
  2905. try {
  2906. RtlCopyMemory (OriginalOutputBuffer,
  2907. OutputBuffer,
  2908. OutputBufferLength
  2909. );
  2910. } except (EXCEPTION_EXECUTE_HANDLER) {
  2911. return GetExceptionCode ();
  2912. }
  2913. }
  2914. if ((OriginalEvent != NULL) &&
  2915. (AsynchronousIo == TRUE)) {
  2916. NtSetEvent (OriginalEvent,
  2917. NULL
  2918. );
  2919. }
  2920. }
  2921. }
  2922. if (AsynchronousIo == TRUE) {
  2923. NtClose (Event);
  2924. }
  2925. }
  2926. )} @NL
  2927. End=
  2928. TemplateName=NtReadFileScatter
  2929. NoType=SegmentArray
  2930. Locals=
  2931. BOOLEAN AsynchronousIo = FALSE;
  2932. BOOLEAN AlertableIo = FALSE;
  2933. ULONG ElementCount;
  2934. End=
  2935. PreCall=
  2936. if (!WOW64_IS_RDWR_SCATTER_GATHER_SUPPORTED ()) {
  2937. return STATUS_NOT_SUPPORTED;
  2938. }
  2939. @AsynchronousIoPrecall
  2940. SegmentArray = UlongToPtr (SegmentArrayHost);
  2941. End=
  2942. Begin=
  2943. @GenApiThunk(@ApiName)
  2944. End=
  2945. TemplateName=NtWriteFileGather
  2946. NoType=SegmentArray
  2947. Locals=
  2948. BOOLEAN AsynchronousIo = FALSE;
  2949. BOOLEAN AlertableIo = FALSE;
  2950. End=
  2951. PreCall=
  2952. if (!WOW64_IS_RDWR_SCATTER_GATHER_SUPPORTED ()) {
  2953. return STATUS_NOT_SUPPORTED;
  2954. }
  2955. @AsynchronousIoPrecall
  2956. SegmentArray = UlongToPtr (SegmentArrayHost);
  2957. End=
  2958. Begin=
  2959. @GenApiThunk(@ApiName)
  2960. End=
  2961. ;; The following is the list of structures passed.
  2962. ;; None of them are pointer dependent.
  2963. ;; List taken from ntos\io\dir.c
  2964. TemplateName=NtQueryDirectoryFile
  2965. Case=(FileDirectoryInformation,PFILE_DIRECTORY_INFORMATION)
  2966. Case=(FileFullDirectoryInformation,PFILE_FULL_DIR_INFORMATION)
  2967. Case=(FileBothDirectoryInformation,PFILE_BOTH_DIR_INFORMATION)
  2968. Case=(FileNamesInformation,PFILE_NAMES_INFORMATION)
  2969. Case=(FileObjectIdInformation,PFILE_OBJECT_INFORMATION)
  2970. Case=(FileQuotaInformation,PFILE_QUOTA_INFORMATION)
  2971. Case=(FileReparsePointInformation,FILE_REPARSE_POINT_INFORMATION)
  2972. Case=(FileIdBothDirectoryInformation,PFILE_ID_BOTH_DIR_INFORMATION)
  2973. Case=(FileIdFullDirectoryInformation,PFILE_ID_FULL_DIRECTORY_INFORMATION)
  2974. Case=(FileValidDataLengthInformation,PFILE_VALID_DATA_LENGTH_INFORMATION)
  2975. Locals=
  2976. BOOL bRealigned=FALSE;
  2977. PVOID *pTempFileInfo;
  2978. BOOLEAN AsynchronousIo = FALSE;
  2979. BOOLEAN AlertableIo = FALSE;
  2980. End=
  2981. PreCall=
  2982. @AsynchronousIoPrecall
  2983. //[LARGE_INTEGER ALIGNMENT FIXEX]
  2984. if ( (SIZE_T)(FileInformation) & (0x07) ) {
  2985. // allocate a buffer with correct alignment, to pass to the Win64 API
  2986. pTempFileInfo = FileInformation;
  2987. FileInformation = Wow64AllocateTemp(Length);
  2988. try {
  2989. RtlCopyMemory(FileInformation, pTempFileInfo, Length);
  2990. } except (EXCEPTION_EXECUTE_HANDLER) {
  2991. return GetExceptionCode ();
  2992. }
  2993. bRealigned = TRUE;
  2994. }
  2995. End=
  2996. Begin=
  2997. @GenDebugNonPtrDepCases(@ApiName,FileInformationClass)
  2998. End=
  2999. PostCall=
  3000. if (!NT_ERROR(RetVal) && bRealigned) {
  3001. RtlCopyMemory((PVOID)pTempFileInfo, FileInformation, Length);
  3002. }
  3003. End=
  3004. ;; The following is the list of structures passed.
  3005. ;; None of them are pointer dependent.
  3006. ;; List taken from ntos\io\iodata.c
  3007. TemplateName=NtQueryInformationFile
  3008. Case=(FileBasicInformation,PFILE_BASIC_INFORMATION)
  3009. Case=(FileStandardInformation,PFILE_STANDARD_INFORMATION)
  3010. Case=(FileInternalInformation,PFILE_INTERNAL_INFORMATION)
  3011. Case=(FileEaInformation,PFILE_EA_INFORMATION)
  3012. Case=(FileAccessInformation,PFILE_ACCESS_INFORMATION)
  3013. Case=(FileNameInformation,PFILE_NAME_INFORMATION)
  3014. Case=(FilePositionInformation,PFILE_POSITON_INFORMATION)
  3015. Case=(FileModeInformation,PFILE_MODE_INFORMATION)
  3016. Case=(FileAlignmentInformation,PFILE_ALIGNMENT_INFORMATION)
  3017. Case=(FileAllInformation,PFILE_ALL_INFORMATION)
  3018. Case=(FileAlternateNameInformation,PFILE_NAME_INFORMATION)
  3019. Case=(FileStreamInformation,PFILE_STREAM_INFORMATION)
  3020. Case=(FilePipeInformation,PFILE_PIPE_INFORMATION)
  3021. Case=(FilePipeLocalInformation,PFILE_PIPE_LOCAL_INFORMATION)
  3022. Case=(FilePipeRemoteInformation,PFILE_PIPE_REMOTE_INFORMATION)
  3023. Case=(FileMailslotQueryInformation,PFILE_MAILSLOT_QUERY_INFORMATION)
  3024. Case=(FileCompressionInformation,PFILE_COMPRESSION_INFORMATION)
  3025. Case=(FileObjectIdInformation,PFILE_OBJECTID_INFORMATION)
  3026. Case=(FileQuotaInformation,PFILE_QUOTA_INFORMATION)
  3027. Case=(FileReparsePointInformation,PFILE_REPARSE_POINT_INFORMATION)
  3028. Case=(FileNetworkOpenInformation,PFILE_NETWORK_OPEN_INFORMATION)
  3029. Case=(FileAttributeTagInformation,PFILE_ATTRIBUTE_TAB_INFORMATION)
  3030. Locals=
  3031. BOOL bRealigned=FALSE;
  3032. PVOID *pTempFileInfo;
  3033. End=
  3034. PreCall=
  3035. //[LARGE_INTEGER ALIGNMENT FIXEX]
  3036. if ( (SIZE_T)(FileInformation) & (0x07) ) {
  3037. // allocate a buffer with correct alignment, to pass to the Win64 API
  3038. pTempFileInfo = FileInformation;
  3039. FileInformation = Wow64AllocateTemp(Length);
  3040. try {
  3041. RtlCopyMemory(FileInformation, pTempFileInfo, Length);
  3042. } except (EXCEPTION_EXECUTE_HANDLER) {
  3043. return GetExceptionCode ();
  3044. }
  3045. bRealigned = TRUE;
  3046. }
  3047. End=
  3048. Begin=
  3049. @GenDebugNonPtrDepCases(@ApiName,FileInformationClass)
  3050. End=
  3051. PostCall=
  3052. if (!NT_ERROR(RetVal) && bRealigned) {
  3053. RtlCopyMemory((PVOID)pTempFileInfo, FileInformation, Length);
  3054. }
  3055. End=
  3056. TemplateName=NtSetInformationFile
  3057. Case=(FileBasicInformation,PFILE_BASIC_INFORMATION)
  3058. Case=(FileRenameInformation,PFILE_RENAME_INFORMATION)
  3059. Case=(FileLinkInformation,PFILE_LINK_INFORMATION)
  3060. Case=(FileDispositionInformation,PFILE_DISPOSITION_INFORMATION)
  3061. Case=(FilePositionInformation,PFILE_POSITION_INFORMATION)
  3062. Case=(FileModeInformation,PFILE_MODE_INFORMATION)
  3063. Case=(FileAllocationInformation,PFILE_ALLOCATION_INFORMATION)
  3064. Case=(FileEndOfFileInformation,PFILE_END_OF_FILE_INFORMATION)
  3065. Case=(FilePipeInformation,PFILE_PIPE_INFORMATION)
  3066. Case=(FilePipeRemoteInformation,PFILE_PIPE_REMOTE_INFORMATION)
  3067. Case=(FileMailslotSetInformation,PFILE_MAILSLOT_SET_INFORMATION)
  3068. Case=(FileObjectIdInformation,PFILE_OBJECTID_INFORMATION)
  3069. Case=(FileCompletionInformation,PFILE_COMPLETION_INFORMATION)
  3070. Case=(FileMoveClusterInformation,PFILE_MOVE_CLUSTER_INFORMATION)
  3071. Case=(FileQuotaInformation,PFILE_QUOTA_INFORMATION)
  3072. Case=(FileTrackingInformation,PFILE_TRACKING_INFORMATION)
  3073. Case=(FileValidDataLengthInformation,PFILE_VALID_DATA_LENGTH_INFORMATION)
  3074. Case=(FileShortNameInformation,PFILE_NAME_INFORMATION)
  3075. Locals=
  3076. BOOL bRealigned=FALSE;
  3077. PVOID *pTempFileInfo;
  3078. End=
  3079. PreCall=
  3080. //[LARGE_INTEGER ALIGNMENT FIXEX]
  3081. if ( (SIZE_T)(FileInformation) & (0x07) ) {
  3082. // allocate a buffer with correct alignment, to pass to the Win64 API
  3083. pTempFileInfo = FileInformation;
  3084. FileInformation = Wow64AllocateTemp(Length);
  3085. try {
  3086. RtlCopyMemory(FileInformation, pTempFileInfo, Length);
  3087. } except (EXCEPTION_EXECUTE_HANDLER) {
  3088. return GetExceptionCode ();
  3089. }
  3090. bRealigned = TRUE;
  3091. }
  3092. End=
  3093. Begin=
  3094. @GenSetThunk(@ApiName,FileInformationClass,FileInformation,Length)
  3095. End=
  3096. PostCall=
  3097. if (!NT_ERROR(RetVal) && bRealigned) {
  3098. RtlCopyMemory((PVOID)pTempFileInfo, FileInformation, Length);
  3099. }
  3100. End=
  3101. TemplateName=NtSetVolumeInformationFile
  3102. Case=(FileFsVolumeInformation,PFILE_FS_VOLUME_INFORMATION)
  3103. Case=(FileFsLabelInformation,PFILE_FS_LABEL_INFORMATION)
  3104. Case=(FileFsSizeInformation,PFILE_FS_SIZE_INFORMATION)
  3105. Case=(FileFsDeviceInformation,PFILE_FS_DEVICE_INFORMATION)
  3106. Case=(FileFsAttributeInformation,PFILE_FS_ATTRIBUTE_INFORMATION)
  3107. Case=(FileFsControlInformation,PFILE_FS_CONTROL_INFORMATION)
  3108. Case=(FileFsFullSizeInformation,PFILE_FS_FULL_SIZE_INFORMATION)
  3109. Case=(FileFsObjectIdInformation,PFILE_FS_OBJECTID_INFORMATION)
  3110. Begin=
  3111. @GenDebugNonPtrDepCases(@ApiName,FsInformationClass)
  3112. End=
  3113. TemplateName=NtQueryMultipleValueKey
  3114. NoType=ValueEntries
  3115. PreCall=
  3116. {@Indent(@NL
  3117. @NL try { @NL
  3118. NT32KEY_VALUE_ENTRY *Entries32 = (NT32KEY_VALUE_ENTRY *)ValueEntriesHost; @NL
  3119. ULONG TempEntryCount = EntryCount; @NL
  3120. PKEY_VALUE_ENTRY Entries64 = (PKEY_VALUE_ENTRY)Wow64AllocateTemp(sizeof(KEY_VALUE_ENTRY) * EntryCount); @NL
  3121. ValueEntries = Entries64; @NL
  3122. @NL
  3123. for(;TempEntryCount > 0; TempEntryCount--, Entries32++, Entries64++) { @NL
  3124. Entries64->ValueName = Wow64ShallowThunkAllocUnicodeString32TO64(Entries32->ValueName); @NL
  3125. Entries64->DataLength = (ULONG)Entries32->DataLength; @NL
  3126. Entries64->DataOffset = (ULONG)Entries32->DataOffset; @NL
  3127. Entries64->Type = (ULONG)Entries32->Type; @NL
  3128. }@NL
  3129. } except( NULL, EXCEPTION_EXECUTE_HANDLER){ @NL
  3130. return GetExceptionCode (); @NL
  3131. } @NL
  3132. )}@NL
  3133. End=
  3134. Begin=
  3135. @GenApiThunk(Wow64@ApiName)
  3136. End=
  3137. PostCall=
  3138. {@Indent(@NL
  3139. @NL try { @NL
  3140. NT32KEY_VALUE_ENTRY *Entries32 = (NT32KEY_VALUE_ENTRY *)ValueEntriesHost; @NL
  3141. ULONG TempEntryCount = EntryCount; @NL
  3142. PKEY_VALUE_ENTRY Entries64 = ValueEntries;@NL
  3143. @NL
  3144. for(;TempEntryCount > 0; TempEntryCount--, Entries32++, Entries64++) { @NL
  3145. (ULONG)Entries32->DataLength = Entries64->DataLength; @NL
  3146. (ULONG)Entries32->DataOffset = Entries64->DataOffset; @NL
  3147. (ULONG)Entries32->Type = Entries64->Type; @NL
  3148. }@NL
  3149. } except( NULL, EXCEPTION_EXECUTE_HANDLER){ @NL
  3150. return GetExceptionCode (); @NL
  3151. } @NL
  3152. )}@NL
  3153. End=
  3154. ;;All of the data passed is non pointer dependent.
  3155. ;;list taken from ntos\config\ntapi.c
  3156. TemplateName=NtSetInformationKey
  3157. Case=(KeyWriteTimeInformation,PLARGE_INTEGER)
  3158. Begin=
  3159. @GenDebugNonPtrDepCases(Wow64@ApiName,KeySetInformationClass)
  3160. End=
  3161. ;;These functions are asynchronous, but fortunately the Buffer is not used.
  3162. ;;The IO_STATUS_BLOCK will be thunked in the kernel.
  3163. TemplateName=NtNotifyChangeKey
  3164. NoType=IoStatusBlock
  3165. PreCall=
  3166. IoStatusBlock = (PIO_STATUS_BLOCK)IoStatusBlockHost; @NL
  3167. Wow64WrapApcProc(&ApcRoutine, &ApcContext);
  3168. End=
  3169. Begin=
  3170. @GenApiThunk(Wow64@ApiName)
  3171. End=
  3172. TemplateName=NtNotifyChangeKeys
  3173. NoType=IoStatusBlock
  3174. NoType=SlaveObjects
  3175. PreCall=
  3176. IoStatusBlock = (PIO_STATUS_BLOCK)IoStatusBlockHost; @NL
  3177. if (0 == Count) { @Indent( @NL
  3178. SlaveObjects = (POBJECT_ATTRIBUTES)SlaveObjectsHost; @NL
  3179. )} @NL
  3180. else { @Indent( @NL
  3181. if (Count > 1) { @Indent( @NL
  3182. // The kernel does not support a count > 1 @NL
  3183. return STATUS_INVALID_PARAMTER; @NL
  3184. )} @NL
  3185. // Count must be 1 @NL
  3186. RetVal = Wow64ShallowThunkAllocObjectAttributes32TO64(SlaveObjectsHost, &SlaveObjects); @NL
  3187. if (!NT_SUCCESS (RetVal)) {
  3188. return RetVal;
  3189. }
  3190. )} @NL
  3191. End=
  3192. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3193. ;;
  3194. ;; Many of the thread control functions are implemented in Wow64.
  3195. ;;
  3196. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3197. TemplateName=NtContinue
  3198. Begin=
  3199. @GenApiThunk(Wow64@ApiName)
  3200. End=
  3201. TemplateName=NtSuspendThread
  3202. Begin=
  3203. @GenApiThunk(Wow64SuspendThread)
  3204. End=
  3205. TemplateName=NtGetContextThread
  3206. Begin=
  3207. @GenApiThunk(Wow64GetContextThread)
  3208. End=
  3209. TemplateName=NtSetContextThread
  3210. Begin=
  3211. @GenApiThunk(Wow64SetContextThread)
  3212. End=
  3213. TemplateName=NtCreateThread
  3214. Begin=
  3215. @GenApiThunk(Wow64@ApiName)
  3216. End=
  3217. TemplateName=NtTerminateThread
  3218. Begin=
  3219. @GenApiThunk(Wow64@ApiName)
  3220. End=
  3221. TemplateName=NtRaiseException
  3222. NoType=ExceptionRecord
  3223. NoType=ContextRecord
  3224. PreCall=
  3225. ExceptionRecord = (PEXCEPTION_RECORD)ExceptionRecordHost; @NL
  3226. ContextRecord = (PCONTEXT)ContextRecordHost; @NL
  3227. End=
  3228. Begin=
  3229. @GenApiThunk(Wow64KiRaiseException)
  3230. End=
  3231. TemplateName=NtCallbackReturn
  3232. Begin=
  3233. @GenApiThunk(Wow64@ApiName)
  3234. End=
  3235. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3236. ;;
  3237. ;; Memory-Management
  3238. ;;
  3239. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3240. TemplateName=NtProtectVirtualMemory
  3241. PreCall=
  3242. try { @NL
  3243. CpuFlushInstructionCache ( ProcessHandle, *BaseAddress, *(ULONG *) RegionSize, WOW64_FLUSH_PROTECT ); @NL
  3244. } except (EXCEPTION_EXECUTE_HANDLER) { @NL
  3245. return GetExceptionCode (); @NL
  3246. } @NL
  3247. End=
  3248. TemplateName=NtFreeVirtualMemory
  3249. PreCall=
  3250. try { @NL
  3251. CpuFlushInstructionCache ( ProcessHandle, *BaseAddress, *(ULONG *) RegionSize, WOW64_FLUSH_FREE); @NL
  3252. } except (EXCEPTION_EXECUTE_HANDLER) { @NL
  3253. return GetExceptionCode (); @NL
  3254. } @NL
  3255. End=
  3256. TemplateName=NtAllocateVirtualMemory
  3257. PreCall=
  3258. if ((AllocationType & MEM_COMMIT) != 0) { @NL
  3259. Wow64pSetExecuteProtection (&Protect); @NL
  3260. } @NL
  3261. if (!WOW64_IS_LARGE_PAGES_SUPPORTED ()) { @NL
  3262. if (AllocationType & MEM_LARGE_PAGES) { @NL
  3263. @NL
  3264. // @NL
  3265. // Large pages are not supported on this platform. @NL
  3266. // @NL
  3267. @NL
  3268. return STATUS_NOT_SUPPORTED; @NL
  3269. } @NL
  3270. } @NL
  3271. if (!WOW64_IS_WRITE_WATCH_SUPPORTED ()) { @NL
  3272. if (AllocationType & MEM_WRITE_WATCH) { @NL
  3273. @NL
  3274. // @NL
  3275. // Write-Watch pages are not supported on this platform. @NL
  3276. // @NL
  3277. @NL
  3278. return STATUS_NOT_SUPPORTED; @NL
  3279. } @NL
  3280. } @NL
  3281. try { @NL
  3282. if ((NULL == *BaseAddress) && 0 == (ZeroBits)) { @NL
  3283. // @NL
  3284. // Force the address to be below 2gb, in case the target process @NL
  3285. // is 64-bit. @NL
  3286. ZeroBits = MAX_WOW64_ADDRESS (); @NL
  3287. } @NL
  3288. }
  3289. except (EXCEPTION_EXECUTE_HANDLER) { @NL
  3290. return GetExceptionCode (); @NL
  3291. } @NL
  3292. End=
  3293. PostCall=
  3294. if ( !NT_ERROR(RetVal) ) { @NL
  3295. try { @NL
  3296. CpuFlushInstructionCache ( ProcessHandle, *BaseAddress, *(ULONG *) RegionSize, WOW64_FLUSH_ALLOC ); @NL
  3297. } except (EXCEPTION_EXECUTE_HANDLER) { @NL
  3298. return GetExceptionCode (); @NL
  3299. } @NL
  3300. } @NL
  3301. End=
  3302. TemplateName=NtMapViewOfSection
  3303. Locals=
  3304. PVOID ArbitraryUserPointer; @NL
  3305. PTEB Teb = NtCurrentTeb(); @NL
  3306. PTEB32 Teb32 = NtCurrentTeb32(); @NL
  3307. SECTION_IMAGE_INFORMATION Info; @NL
  3308. WCHAR* DllName;
  3309. UNICODE_STRING NtNameStr = {0, 0, NULL};
  3310. RTL_UNICODE_STRING_BUFFER DosNameStrBuf;
  3311. End=
  3312. PreCall=
  3313. // Copy the 32-bit ArbitraryUserPointer into the 64-bit Teb. It @NL
  3314. // contains a pointer to the unicode filename of the image being @NL
  3315. // mapped. @NL
  3316. ArbitraryUserPointer = Teb->NtTib.ArbitraryUserPointer; @NL
  3317. //
  3318. // Find real (redirected) image name
  3319. //
  3320. RtlInitUnicodeStringBuffer(&DosNameStrBuf, 0, 0);
  3321. DllName = (PVOID)Teb32->NtTib.ArbitraryUserPointer;
  3322. try {
  3323. if (RtlDosPathNameToNtPathName_U(DllName, &NtNameStr, NULL, NULL)) {
  3324. ULONG Len = NtNameStr.Length;
  3325. Wow64RedirectFileName(NtNameStr.Buffer, &Len);
  3326. NtNameStr.Length = Len;
  3327. if ( NT_SUCCESS(RtlAssignUnicodeStringBuffer(&DosNameStrBuf, &NtNameStr)) &&
  3328. NT_SUCCESS(RtlNtPathNameToDosPathName(0, &DosNameStrBuf, NULL, NULL))) {
  3329. DllName = DosNameStrBuf.String.Buffer;
  3330. }
  3331. }
  3332. Teb->NtTib.ArbitraryUserPointer = DllName;
  3333. if ((NULL == *BaseAddress) && (0 == ZeroBits)) { @NL
  3334. @NL
  3335. // @NL
  3336. // Force the address to be below 2gb, in case the target process @NL
  3337. // is 64-bit. @NL
  3338. @NL
  3339. ZeroBits = MAX_WOW64_ADDRESS (); @NL
  3340. } @NL
  3341. } @NL
  3342. except (EXCEPTION_EXECUTE_HANDLER) { @NL
  3343. return GetExceptionCode (); @NL
  3344. } @NL
  3345. End=
  3346. PostCall=
  3347. Teb->NtTib.ArbitraryUserPointer = ArbitraryUserPointer; @NL
  3348. if (!NT_ERROR(RetVal)) { @NL
  3349. if (WOW64IsCurrentProcess(ProcessHandle)) { @NL
  3350. CpuNotifyDllLoad ( DllName, *BaseAddress, *(ULONG *) ViewSize ); @NL
  3351. } @NL
  3352. // For non-x86 images, be sure to return a mismatch warning @NL
  3353. if (!Wow64IsModule32bitHelper(NtCurrentProcess(), @NL
  3354. (ULONG64)(*BaseAddress))) { @NL
  3355. RetVal = STATUS_IMAGE_MACHINE_TYPE_MISMATCH; @NL
  3356. } @NL
  3357. } @NL
  3358. if (NtNameStr.Buffer) RtlFreeHeap(RtlProcessHeap(), 0, NtNameStr.Buffer);
  3359. RtlFreeUnicodeStringBuffer(&DosNameStrBuf);
  3360. End=
  3361. TemplateName=NtUnmapViewOfSection
  3362. PostCall=
  3363. if ( ( !NT_ERROR(RetVal) ) && WOW64IsCurrentProcess ( ProcessHandle ) ) @NL
  3364. CpuNotifyDllUnload ( BaseAddress );
  3365. End=
  3366. TemplateName=NtFlushInstructionCache
  3367. PostCall=
  3368. if ( !NT_ERROR(RetVal) ) {@NL
  3369. CpuFlushInstructionCache ( ProcessHandle, BaseAddress, Length , WOW64_FLUSH_FORCE);
  3370. } @NL
  3371. End=
  3372. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3373. ;;
  3374. ;; NT debugger UI APIs
  3375. ;;
  3376. ;;
  3377. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3378. TemplateName=NtWow64DebuggerCall
  3379. Begin=
  3380. @ApiProlog
  3381. @NoFormat(
  3382. NTSTATUS RetVal = STATUS_SUCCESS;
  3383. // Don't log this one, as our logging competes with the BREAKPOINT_PRINT logging
  3384. //LOGPRINT((TRACELOG, "wh@ApiName(@ApiNum) api thunk: @IfArgs(@ArgList(@ArgName: %x@ArgMore(,)))\n"@IfArgs(, @ArgList((@ArgHostName)@ArgMore(,))))); @NL
  3385. switch (ServiceClassHost) {
  3386. case 0: // BREAKPOINT_BREAK from sdk\inc\nti386.h
  3387. WOWASSERT(FALSE); // This should never be hit from usermode
  3388. break;
  3389. case 1: // BREAKPOINT_PRINT:
  3390. // Arg2Host, Output->Length, is ignored
  3391. DbgPrintEx(Arg3Host, // ComponentId
  3392. Arg4Host, // Level
  3393. "%s",
  3394. (PCHAR)Arg1Host);// String to print
  3395. break;
  3396. case 2: // BREAKPOINT_PROMPT:
  3397. // Arg2Host, Output->Length, is ignored
  3398. RetVal = DbgPrompt((PCHAR)Arg1Host, // Output->Buffer
  3399. (PCHAR)Arg3Host, // Input->Buffer
  3400. Arg4Host); // Input->MaximumLength
  3401. break;
  3402. case 3: // BREAKPOINT_LOAD_SYMBOLS
  3403. case 4: // BREAKPOINT_UNLOAD_SYMBOLS
  3404. WOWASSERT(FALSE); // This should never be hit from usermode
  3405. break;
  3406. default:
  3407. WOWASSERT(FALSE);
  3408. break;
  3409. }
  3410. return RetVal;
  3411. }
  3412. End=
  3413. TemplateName=NtWaitForDebugEvent
  3414. NoType=WaitStateChange
  3415. Locals=
  3416. DBGUI_WAIT_STATE_CHANGE WaitStateChangeCopy; @NL
  3417. NT32DBGUI_WAIT_STATE_CHANGE *WaitStateChangeDest; @NL
  3418. DEBUG_EVENT DebugEvent;
  3419. End=
  3420. PreCall=
  3421. if (ARGUMENT_PRESENT(WaitStateChangeHost)) { @Indent( @NL
  3422. WaitStateChange = &WaitStateChangeCopy; @NL
  3423. WaitStateChangeDest = (NT32DBGUI_WAIT_STATE_CHANGE *)WaitStateChangeHost; @NL
  3424. )} @NL
  3425. else { @Indent( @NL
  3426. WaitStateChange = (DBGUI_WAIT_STATE_CHANGE *)WaitStateChangeHost; @NL
  3427. )} @NL
  3428. wait_again: @NL
  3429. End=
  3430. PostCall=
  3431. if (!NT_ERROR(RetVal) && ARGUMENT_PRESENT(WaitStateChange) && RetVal != STATUS_TIMEOUT && RetVal != STATUS_USER_APC && RetVal != STATUS_ALERTED && RetVal != DBG_NO_STATE_CHANGE) { @Indent( @NL
  3432. //
  3433. // Lets see if the Cpu wants to handle this debug event
  3434. //
  3435. RetVal = DbgUiConvertStateChangeStructure (WaitStateChange, &DebugEvent);
  3436. if (!NT_SUCCESS (RetVal)) {
  3437. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: Failed to convert StateChange structure %lx %lx\n", RetVal, WaitStateChange));@NL
  3438. return RetVal;
  3439. }
  3440. if (CpuProcessDebugEvent (&DebugEvent) == TRUE) {
  3441. RetVal = NtDebugContinue(DebugObjectHandle,
  3442. &WaitStateChange->AppClientId,
  3443. DBG_EXCEPTION_NOT_HANDLED);
  3444. if (NT_SUCCESS (RetVal)) {
  3445. goto wait_again;
  3446. } else {
  3447. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: Couldn't continue debug event %lx-%lx %lx\n",
  3448. WaitStateChange->AppClientId.UniqueProcess, WaitStateChange->AppClientId.UniqueThread , RetVal));@NL
  3449. }
  3450. }
  3451. WaitStateChangeDest->NewState = WaitStateChange->NewState; @NL
  3452. @ForceType(PostCall,(&WaitStateChange->AppClientId),(&WaitStateChangeDest->AppClientId),PCLIENT_ID,OUT) @NL
  3453. switch(WaitStateChange->NewState) { @Indent( @NL
  3454. case DbgIdle: @NL
  3455. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgIdle\n"));@NL
  3456. goto do_nothing; @NL
  3457. case DbgReplyPending: @NL @Indent(
  3458. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgReplyPending\n")); @NL
  3459. do_nothing:
  3460. // Nothing else to do in this case. @NL
  3461. break; @NL
  3462. ) @NL
  3463. case DbgCreateThreadStateChange: @NL @Indent(
  3464. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgCreateThreadWaitStateChange\n"));@NL
  3465. @ForceType(PostCall,(&WaitStateChange->StateInfo.CreateThread),(&WaitStateChangeDest->StateInfo.CreateThread),PDBGUI_CREATE_THREAD,OUT) @NL
  3466. break; @NL
  3467. ) @NL
  3468. case DbgCreateProcessStateChange: @NL @Indent(
  3469. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgCreateProcessWaitStateChange\n"));@NL
  3470. @ForceType(PostCall,(&WaitStateChange->StateInfo.CreateProcessInfo),(&WaitStateChangeDest->StateInfo.CreateProcessInfo),PDBGUI_CREATE_PROCESS,OUT) @NL
  3471. break; @NL
  3472. ) @NL
  3473. case DbgExitThreadStateChange: @NL @Indent(
  3474. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgExitThreadWaitStateChange\n"));@NL
  3475. WOWASSERT(sizeof(NT32DBGKM_EXIT_THREAD) == sizeof(DBGKM_EXIT_THREAD)); @NL
  3476. RtlCopyMemory(&WaitStateChangeDest->StateInfo.ExitThread, &WaitStateChange->StateInfo.ExitThread, sizeof(DBGKM_EXIT_THREAD)); @NL
  3477. break; @NL
  3478. ) @NL
  3479. case DbgExitProcessStateChange: @NL @Indent(
  3480. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgExitProcessWaitStateChange\n")); @NL
  3481. WOWASSERT(sizeof(NT32DBGKM_EXIT_PROCESS) == sizeof(DBGKM_EXIT_PROCESS)); @NL
  3482. RtlCopyMemory(&WaitStateChangeDest->StateInfo.ExitProcess, &WaitStateChange->StateInfo.ExitProcess,sizeof(DBGKM_EXIT_PROCESS)); @NL
  3483. break; @NL
  3484. ) @NL
  3485. case DbgExceptionStateChange: @NL
  3486. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgBreakpointWaitStateChange\n")); @NL
  3487. switch (WaitStateChange->StateInfo.Exception.ExceptionRecord.ExceptionCode)
  3488. {
  3489. case STATUS_WX86_BREAKPOINT:
  3490. WaitStateChangeDest->NewState = DbgBreakpointStateChange;
  3491. break;
  3492. case STATUS_WX86_SINGLE_STEP:
  3493. WaitStateChangeDest->NewState = DbgSingleStepStateChange;
  3494. break;
  3495. }
  3496. goto do_exception; @NL
  3497. case DbgBreakpointStateChange: @NL
  3498. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgBreakpointWaitStateChange\n")); @NL
  3499. //
  3500. // 32-bit x86 debuggers shouldn't expect to receive
  3501. // native hard coded break points, so bypass them
  3502. //
  3503. if ((NT_SUCCESS(Wow64SkipOverBreakPoint(&WaitStateChange->AppClientId,
  3504. &WaitStateChange->StateInfo.Exception.ExceptionRecord))) &&
  3505. (NT_SUCCESS(NtDebugContinue(DebugObjectHandle,
  3506. &WaitStateChange->AppClientId,
  3507. DBG_CONTINUE))))
  3508. {
  3509. LOGPRINT((TRACELOG, "Bypassing native breakpoint at %lx\n",
  3510. WaitStateChange->StateInfo.Exception.ExceptionRecord.ExceptionAddress));
  3511. goto wait_again;
  3512. }
  3513. LOGPRINT((ERRORLOG, "32-bit Debugger couldn't skip native breakpoint at %lx\n",
  3514. WaitStateChange->StateInfo.Exception.ExceptionRecord.ExceptionAddress));
  3515. goto do_exception; @NL
  3516. case DbgSingleStepStateChange: @NL @Indent(
  3517. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgSingleStepWaitStateChange\n")); @NL
  3518. do_exception:
  3519. WaitStateChangeDest->StateInfo.Exception.FirstChance = WaitStateChange->StateInfo.Exception.FirstChance; @NL
  3520. ThunkExceptionRecord64To32((&WaitStateChange->StateInfo.Exception.ExceptionRecord),((PEXCEPTION_RECORD32)(&WaitStateChangeDest->StateInfo.Exception.ExceptionRecord)));@NL
  3521. // BUG, BUG. Do not thunk the entire exception chain at this point. @NL
  3522. // It appears that NTSD does not use the entire chain, so a hack to get it @NL
  3523. // is not worth the risk of bugs that it might introduce. Leave it alone for now. @NL
  3524. break; @NL
  3525. ) @NL
  3526. case DbgLoadDllStateChange: @NL @Indent(
  3527. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgLoadDllWaitStateChange\n")); @NL
  3528. if (!Wow64IsModule32bit(&WaitStateChange->AppClientId,
  3529. (ULONG64)WaitStateChange->StateInfo.LoadDll.BaseOfDll) &&
  3530. (NT_SUCCESS(NtDebugContinue(DebugObjectHandle,
  3531. &WaitStateChange->AppClientId,
  3532. DBG_CONTINUE))))
  3533. {
  3534. LOGPRINT((TRACELOG, "Bypassing 64-bit load Dll messege. \n"));
  3535. goto wait_again;
  3536. }
  3537. @ForceType(PostCall,(&WaitStateChange->StateInfo.LoadDll),(&WaitStateChangeDest->StateInfo.LoadDll),PDBGKM_LOAD_DLL,OUT) @NL
  3538. break; @NL
  3539. ) @NL
  3540. case DbgUnloadDllStateChange: @NL @Indent(
  3541. LOGPRINT((TRACELOG, "DbgUiWaitWaitStateChange: DbgUnloadDllWaitStateChange\n")); @NL
  3542. @ForceType(PostCall,(&WaitStateChange->StateInfo.UnloadDll),(&WaitStateChangeDest->StateInfo.UnloadDll),PDBGKM_UNLOAD_DLL,OUT) @NL
  3543. break; @NL
  3544. ) @NL
  3545. default: @NL @Indent(
  3546. LOGPRINT((ERRORLOG, "Unknown DBGUI_WAIT_STATE_CHANGE of %x\n", WaitStateChange->NewState));
  3547. WOWASSERT(FALSE); @NL
  3548. ) @NL
  3549. )} @NL
  3550. )} @NL
  3551. End=
  3552. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3553. ;;
  3554. ;; A few CSR thunks that are in NTDLL
  3555. ;; Most are placeholders and will be going away very soon
  3556. ;;
  3557. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3558. TemplateName=NtWow64CsrClientConnectToServer
  3559. Locals=
  3560. End=
  3561. PostCall=
  3562. {@NL
  3563. // Copy setting from 64Bit PEB to the 32Bit PEB @NL
  3564. PPEB32 peb32;
  3565. peb32 = (PPEB32)(NtCurrentTeb32()->ProcessEnvironmentBlock); @NL
  3566. peb32->ReadOnlySharedMemoryBase = PtrToUlong(NtCurrentPeb()->ReadOnlySharedMemoryBase); @NL
  3567. peb32->ReadOnlySharedMemoryHeap = PtrToUlong(NtCurrentPeb()->ReadOnlySharedMemoryHeap); @NL
  3568. peb32->ReadOnlyStaticServerData = PtrToUlong(NtCurrentPeb()->ReadOnlyStaticServerData); @NL
  3569. }@NL
  3570. End=
  3571. Begin=
  3572. @GenApiThunk(CsrClientConnectToServer)
  3573. End=
  3574. TemplateName=NtWow64CsrNewThread
  3575. Begin=
  3576. @GenApiThunk(CsrNewThread)
  3577. End=
  3578. TemplateName=NtWow64CsrIdentifyAlertableThread
  3579. Begin=
  3580. @GenApiThunk(CsrNewThread)
  3581. End=
  3582. TemplateName=NtWow64CsrClientCallServer
  3583. Begin=
  3584. @GenPlaceHolderThunk(CsrClientCallServer)
  3585. End=
  3586. TemplateName=NtWow64CsrAllocateCaptureBuffer
  3587. Begin=
  3588. @GenPlaceHolderThunk(CsrAllocateCaptureBuffer)
  3589. End=
  3590. TemplateName=NtWow64CsrFreeCaptureBuffer
  3591. Begin=
  3592. @GenPlaceHolderThunk(CsrFreeCaptureBuffer)
  3593. End=
  3594. TemplateName=NtWow64CsrAllocateMessagePointer
  3595. Begin=
  3596. @GenPlaceHolderThunk(CsrAllocateMessagePointer)
  3597. End=
  3598. TemplateName=NtWow64CsrCaptureMessageBuffer
  3599. Begin=
  3600. @GenPlaceHolderThunk(CsrCaptureMessageBuffer)
  3601. End=
  3602. TemplateName=NtWow64CsrCaptureMessageString
  3603. Begin=
  3604. @GenPlaceHolderThunk(CsrCaptureMessageString)
  3605. End=
  3606. TemplateName=NtWow64CsrSetPriorityClass
  3607. Begin=
  3608. @GenApiThunk(CsrSetPriorityClass)
  3609. End=
  3610. TemplateName=NtWow64CsrAllocateCapturePointer
  3611. Begin=
  3612. @GenPlaceHolderThunk(CsrAllocateCapturePointer)
  3613. End=
  3614. TemplateName=NtWow64CsrGetProcessId
  3615. Begin=
  3616. @GenPlaceHolderThunk(CsrGetProcessId)
  3617. End=
  3618. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3619. ;;
  3620. ;; These APIs are only called by the user mode PNP manager
  3621. ;; which will be in 64bit code in NT64. Since no user apps call
  3622. ;; them and the structures passed across are rather nasty they will
  3623. ;; not be supported here.
  3624. ;;
  3625. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3626. TemplateName=NtGetPlugPlayEvent
  3627. Begin=
  3628. @GenUnsupportedNtApiThunk
  3629. End=
  3630. ; case PlugPlayControlEnumerateDevice:
  3631. ; case PlugPlayControlRegisterNewDevice:
  3632. ; case PlugPlayControlDeregisterDevice:
  3633. ; case PlugPlayControlInitializeDevice:
  3634. ; case PlugPlayControlStartDevice:
  3635. ; case PlugPlayControlEjectDevice:
  3636. ; case PlugPlayControlUnlockDevice: PLUGPLAY_CONTROL_DEVICE_CONTROL_DATA
  3637. ; case PlugPlayControlQueryAndRemoveDevice: PPLUGPLAY_CONTROL_QUERY_AND_REMOVE_DATA
  3638. ; case PlugPlayControlUserResponse: PPLUGPLAY_CONTROL_USER_RESPONSE_DATA
  3639. ; case PlugPlayControlGenerateLegacyDevice PPLUGPLAY_CONTROL_LEGACY_DEVGEN_DATA
  3640. ; case PlugPlayControlDetectResourceConflict PPLUGPLAY_CONTROL_DEVICE_RESOURCE_DATA
  3641. ; case PlugPlayControlQueryConflictList PPLUGPLAY_CONTROL_CONFLICT_DATA
  3642. ; case PlugPlayControlGetInterfaceDeviceList PPLUGPLAY_CONTROL_INTERFACE_LIST_DATA
  3643. ; case PlugPlayControlProperty PPLUGPLAY_CONTROL_PROPERTY_DATA
  3644. ; case PlugPlayControlDeviceClassAssociation PPLUGPLAY_CONTROL_CLASS_ASSOCIATION_DATA
  3645. ; case PlugPlayControlGetRelatedDevice PPLUGPLAY_CONTROL_RELATED_DEVICE_DATA
  3646. ; case PlugPlayControlGetInterfaceDeviceAlias PPLUGPLAY_CONTROL_INTERFACE_ALIAS_DATA
  3647. ; case PlugPlayControlDeviceStatus PPLUGPLAY_CONTROL_STATUS_DATA
  3648. ; case PlugPlayControlGetDeviceDepth PPLUGPLAY_CONTROL_DEPTH_DATA
  3649. ; case PlugPlayControlQueryDeviceRelations PPLUGPLAY_CONTROL_DEVICE_RELATIONS_DATA
  3650. ; case PlugPlayControlTargetDeviceRelation PPLUGPLAY_CONTROL_TARGET_RELATION_DATA
  3651. ; case PlugPlayControlRequestEject PLUGPLAY_CONTROL_REQUEST_EJECT
  3652. TemplateName=NtPlugPlayControl
  3653. Begin=
  3654. @GenUnsupportedNtApiThunk
  3655. End=
  3656. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3657. ;;
  3658. ;; All channel APIs currently return STATUS_NOT_IMPLEMENTED
  3659. ;; They will not be supported here either.
  3660. ;;
  3661. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3662. TemplateName=NtCreateChannel
  3663. Also=NtOpenChannel
  3664. Also=NtListenChannel
  3665. Also=NtSendWaitReplyChannel
  3666. Also=NtReplyWaitSendChannel
  3667. Also=NtSetContextChannel
  3668. Begin=
  3669. @GenUnsupportedNtApiThunk
  3670. End=
  3671. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3672. ;;
  3673. ;; LPC functions are supported, but the caller must be aware
  3674. ;; that the header has changed. See ntlpcapi.h for more info.
  3675. ;;
  3676. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  3677. ;;These APIs are nothing special.
  3678. TemplateName=NtSecureConnectPort
  3679. Locals=
  3680. BOOLEAN LegacyLpcPort = FALSE;
  3681. End=
  3682. Begin=
  3683. @GenApiThunk(@ApiName)
  3684. End=
  3685. ;
  3686. ; These APIs are used to detect legacy Lpc port functions
  3687. ;
  3688. TemplateName=NtConnectPort
  3689. Locals=
  3690. BOOLEAN LegacyLpcPort = FALSE;
  3691. End=
  3692. PostCall=
  3693. if (NT_SUCCESS (RetVal)) {
  3694. if (Wow64pIsLegacyLpcPort (PortName) == TRUE) {
  3695. WOW64_MARK_LEGACY_PORT_HANDLE (PortHandleHost);
  3696. }
  3697. }
  3698. End=
  3699. TemplateName=NtCreatePort
  3700. PostCall=
  3701. if (NT_SUCCESS (RetVal)) {
  3702. if (ARGUMENT_PRESENT (ObjectAttributes->ObjectName)) {
  3703. if (Wow64pIsLegacyLpcPort (ObjectAttributes->ObjectName) == TRUE) {
  3704. WOW64_MARK_LEGACY_PORT_HANDLE (PortHandleHost);
  3705. }
  3706. }
  3707. }
  3708. End=
  3709. TemplateName=NtAcceptConnectPort
  3710. Locals=
  3711. BOOLEAN LegacyLpcPort = FALSE;
  3712. End=
  3713. PreCall=
  3714. if (LegacyLpcPort == TRUE) {
  3715. RetVal = Wow64pThunkLegacyLpcMsgIn (FALSE,
  3716. (PPORT_MESSAGE32)UlongToPtr (ConnectionRequestHost),
  3717. &ConnectionRequest);
  3718. if (!NT_SUCCESS (RetVal)) {
  3719. return RetVal;
  3720. }
  3721. }
  3722. End=
  3723. PostCall=
  3724. if (NT_SUCCESS (RetVal)) {
  3725. if (LegacyLpcPort == TRUE) {
  3726. WOW64_MARK_LEGACY_PORT_HANDLE (PortHandleHost);
  3727. }
  3728. }
  3729. End=
  3730. TemplateName=NtReplyPort
  3731. PreCall=
  3732. if (WOW64_IS_LEGACY_PORT_HANDLE (PortHandle)) {
  3733. WOW64_REMOVE_LEGACY_PORT_HANDLE_MARK (PortHandle);
  3734. RetVal = Wow64pThunkLegacyLpcMsgIn (FALSE,
  3735. (PPORT_MESSAGE32)UlongToPtr (ReplyMessageHost),
  3736. &ReplyMessage);
  3737. if (!NT_SUCCESS (RetVal)) {
  3738. return RetVal;
  3739. }
  3740. }
  3741. End=
  3742. TemplateName=NtReplyWaitReceivePort
  3743. Also=NtReplyWaitReceivePortEx
  3744. Locals=
  3745. BOOLEAN LegacyLpcPort;
  3746. End=
  3747. PreCall=
  3748. if (WOW64_IS_LEGACY_PORT_HANDLE (PortHandle)) {
  3749. WOW64_REMOVE_LEGACY_PORT_HANDLE_MARK (PortHandle);
  3750. LegacyLpcPort = TRUE;
  3751. RetVal = Wow64pThunkLegacyLpcMsgIn (FALSE,
  3752. (PPORT_MESSAGE32)UlongToPtr (ReplyMessageHost),
  3753. &ReplyMessage);
  3754. if (!NT_SUCCESS (RetVal)) {
  3755. return RetVal;
  3756. }
  3757. RetVal = Wow64pThunkLegacyLpcMsgIn (FALSE,
  3758. (PPORT_MESSAGE32)UlongToPtr (ReceiveMessageHost),
  3759. &ReceiveMessage);
  3760. if (!NT_SUCCESS (RetVal)) {
  3761. return RetVal;
  3762. }
  3763. } else {
  3764. LegacyLpcPort = FALSE;
  3765. }
  3766. End=
  3767. PostCall=
  3768. if (NT_SUCCESS (RetVal)) {
  3769. if (LegacyLpcPort == TRUE) {
  3770. RetVal = Wow64pThunkLegacyLpcMsgOut (FALSE,
  3771. ReceiveMessage,
  3772. UlongToPtr (ReceiveMessageHost));
  3773. if (!NT_SUCCESS (RetVal)) {
  3774. return RetVal;
  3775. }
  3776. }
  3777. }
  3778. End=
  3779. ;
  3780. ; These APIs take messages
  3781. ;
  3782. TemplateName=NtListenPort
  3783. Also=NtCompleteConnectPort
  3784. Also=NtRequestPort
  3785. Also=NtReplyWaitReplyPort
  3786. Also=NtImpersonateClientOfPort
  3787. Also=NtReadRequestData
  3788. Also=NtWriteRequestData
  3789. PreCall=
  3790. WOW64_REMOVE_LEGACY_PORT_HANDLE_MARK(PortHandle);
  3791. End=
  3792. Begin=
  3793. @GenApiThunk(@ApiName)
  3794. End=
  3795. TemplateName=NtRequestWaitReplyPort
  3796. Locals=
  3797. PPORT_MESSAGE OriginalRequestMessage;
  3798. PPORT_MESSAGE OriginalReplyMessage;
  3799. UNALIGNED PORT_MESSAGE *UnalignedMessage;
  3800. ULONG RequestTotalLength, ReplyTotalLength;
  3801. BOOLEAN LegacyLpcPort;
  3802. End=
  3803. PreCall=
  3804. if (WOW64_IS_LEGACY_PORT_HANDLE (PortHandle)) {
  3805. WOW64_REMOVE_LEGACY_PORT_HANDLE_MARK (PortHandle);
  3806. LegacyLpcPort = TRUE;
  3807. RetVal = Wow64pThunkLegacyLpcMsgIn (TRUE,
  3808. (PPORT_MESSAGE32)UlongToPtr (RequestMessageHost),
  3809. &RequestMessage);
  3810. if (!NT_SUCCESS (RetVal)) {
  3811. return RetVal;
  3812. }
  3813. RetVal = Wow64pThunkLegacyLpcMsgIn (TRUE,
  3814. (PPORT_MESSAGE32)UlongToPtr (ReplyMessageHost),
  3815. &ReplyMessage);
  3816. if (!NT_SUCCESS (RetVal)) {
  3817. return RetVal;
  3818. }
  3819. } else {
  3820. LegacyLpcPort = FALSE;
  3821. }
  3822. if (LegacyLpcPort == FALSE) {
  3823. OriginalRequestMessage = RequestMessage;
  3824. OriginalReplyMessage = ReplyMessage;
  3825. //
  3826. // Need to thunk PORT_MESSAGE if this is legacy code.
  3827. //
  3828. try {
  3829. if ((RequestMessage != NULL) &&
  3830. (((ULONG_PTR)RequestMessage & ((MAX_NATURAL_ALIGNMENT) - 1)) != 0)) {
  3831. UnalignedMessage = RequestMessage;
  3832. RequestTotalLength = UnalignedMessage->u1.s1.TotalLength;
  3833. RequestMessage = Wow64AllocateTemp (RequestTotalLength);
  3834. if (RequestMessage == NULL) {
  3835. return STATUS_NO_MEMORY;
  3836. }
  3837. RtlCopyMemory (RequestMessage, OriginalRequestMessage, RequestTotalLength);
  3838. }
  3839. if ((ReplyMessage != NULL) &&
  3840. (((ULONG_PTR)ReplyMessage & ((MAX_NATURAL_ALIGNMENT) - 1)) != 0)) {
  3841. if (OriginalReplyMessage == OriginalRequestMessage) {
  3842. ReplyMessage = RequestMessage;
  3843. ReplyTotalLength = RequestTotalLength;
  3844. } else {
  3845. UnalignedMessage = ReplyMessage;
  3846. ReplyTotalLength = sizeof (PORT_MESSAGE) + PORT_MAXIMUM_MESSAGE_LENGTH + sizeof(ULONGLONG);
  3847. ReplyMessage = Wow64AllocateTemp (ReplyTotalLength);
  3848. if (ReplyMessage == NULL) {
  3849. return STATUS_NO_MEMORY;
  3850. }
  3851. ReplyMessage->u1.s1.TotalLength = UnalignedMessage->u1.s1.TotalLength;
  3852. }
  3853. }
  3854. } except (EXCEPTION_EXECUTE_HANDLER) {
  3855. return GetExceptionCode ();
  3856. }
  3857. }
  3858. End=
  3859. Begin=
  3860. @GenApiThunk(@ApiName)
  3861. End=
  3862. PostCall=
  3863. if (NT_SUCCESS (RetVal)) {
  3864. if (LegacyLpcPort == FALSE) {
  3865. try {
  3866. if (OriginalRequestMessage != RequestMessage) {
  3867. RtlCopyMemory (OriginalRequestMessage, RequestMessage, RequestTotalLength);
  3868. }
  3869. if ((OriginalReplyMessage != ReplyMessage) &&
  3870. (ReplyMessage != RequestMessage)) {
  3871. UnalignedMessage = ReplyMessage;
  3872. RtlCopyMemory (OriginalReplyMessage, ReplyMessage, UnalignedMessage->u1.s1.TotalLength);
  3873. }
  3874. } except (EXCEPTION_EXECUTE_HANDLER) {
  3875. return GetExceptionCode ();
  3876. }
  3877. } else {
  3878. //
  3879. // This is a legacy lpc port call
  3880. //
  3881. RetVal = Wow64pThunkLegacyLpcMsgOut (TRUE,
  3882. ReplyMessage,
  3883. UlongToPtr (ReplyMessageHost));
  3884. if (!NT_SUCCESS (RetVal)) {
  3885. return RetVal;
  3886. }
  3887. }
  3888. }
  3889. End=
  3890. ;; This API doesn't have any query fields defined.
  3891. TemplateName=NtQueryInformationPort
  3892. Begin=
  3893. @GenApiThunk(@ApiName)
  3894. End=
  3895. ;; This API has more restrictive alignment checking on Win64 than it
  3896. ;; did on Win32.
  3897. TemplateName=NtQueryFullAttributesFile
  3898. Locals=
  3899. FILE_NETWORK_OPEN_INFORMATION FileInformationLocal;
  3900. End=
  3901. PreCall=
  3902. FileInformation = &FileInformationLocal;
  3903. End=
  3904. PostCall=
  3905. try {
  3906. RtlCopyMemory((PVOID)FileInformationHost, &FileInformationLocal, sizeof(FileInformationLocal));
  3907. } except (EXCEPTION_EXECUTE_HANDLER) {
  3908. return GetExceptionCode ();
  3909. }
  3910. End=
  3911. TemplateName=NtWriteVirtualMemory
  3912. PreCall=
  3913. if (BaseAddress == Buffer && !WOW64IsCurrentProcess(ProcessHandle)) {
  3914. MEMORY_BASIC_INFORMATION mbi;
  3915. MEMORY_BASIC_INFORMATION mbiChild;
  3916. PROCESS_BASIC_INFORMATION pbi;
  3917. PVOID pLdr;
  3918. NTSTATUS st;
  3919. PIMAGE_NT_HEADERS32 NtHeaders;
  3920. PIMAGE_SECTION_HEADER SectionTable, LastSection, FirstSection, Section;
  3921. ULONG_PTR SrcVirtualAddress, DestVirtualAddress;
  3922. ULONG SubSectionSize;
  3923. // From mi\mi.h:
  3924. #define MI_ROUND_TO_SIZE(LENGTH,ALIGNMENT) \
  3925. (((LENGTH) + ((ALIGNMENT) - 1)) & ~((ALIGNMENT) - 1))
  3926. // Attempt to write to some child process, but the address in
  3927. // this process matches the address in the child. If the address
  3928. // is within the exe, then this is probably Cygnus. It creates
  3929. // the child suspended, writes a global var into the child exe,
  3930. // then resumes the child. Unfortunately, Wx86/WOW64 haven't
  3931. // reformatted the image yet, so the write goes to the wrong place.
  3932. st = NtQueryVirtualMemory(NtCurrentProcess(),
  3933. BaseAddress,
  3934. MemoryBasicInformation,
  3935. &mbi,
  3936. sizeof(mbi),
  3937. NULL);
  3938. if (!NT_SUCCESS(st)) {
  3939. // looks bad, the API call is probably going to fail
  3940. goto SkipHack;
  3941. }
  3942. if (mbi.Type != SEC_IMAGE || mbi.AllocationBase != NtCurrentPeb()->ImageBaseAddress) {
  3943. // Address isn't within the exe
  3944. goto SkipHack;
  3945. }
  3946. st = NtQueryVirtualMemory(ProcessHandle,
  3947. BaseAddress,
  3948. MemoryBasicInformation,
  3949. &mbiChild,
  3950. sizeof(mbiChild),
  3951. NULL);
  3952. if (!NT_SUCCESS(st)) {
  3953. goto SkipHack;
  3954. }
  3955. if (mbi.AllocationBase != mbiChild.AllocationBase ||
  3956. mbi.RegionSize != mbiChild.RegionSize ||
  3957. mbi.Type != mbiChild.Type) {
  3958. // Possibly different exes in parent and child
  3959. goto SkipHack;
  3960. }
  3961. st = NtQueryInformationProcess(ProcessHandle,
  3962. ProcessBasicInformation,
  3963. &pbi,
  3964. sizeof(pbi),
  3965. NULL);
  3966. if (!NT_SUCCESS(st)) {
  3967. goto SkipHack;
  3968. }
  3969. st = NtReadVirtualMemory(ProcessHandle,
  3970. (PVOID)((ULONG_PTR)pbi.PebBaseAddress+FIELD_OFFSET(PEB, Ldr)),
  3971. &pLdr,
  3972. sizeof(pLdr),
  3973. NULL);
  3974. if (!NT_SUCCESS(st)) {
  3975. goto SkipHack;
  3976. }
  3977. if (pLdr) {
  3978. // The child process' 64-bit loader sn't initialized.
  3979. // Assume the parent has already resumed it and knows
  3980. // what is going on.
  3981. goto SkipHack;
  3982. }
  3983. // Now... figure out where the write really needs to go
  3984. NtHeaders = (PIMAGE_NT_HEADERS32)RtlImageNtHeader(mbi.AllocationBase);
  3985. SectionTable = IMAGE_FIRST_SECTION(NtHeaders);
  3986. LastSection = SectionTable + NtHeaders->FileHeader.NumberOfSections;
  3987. if (SectionTable->PointerToRawData == SectionTable->VirtualAddress) {
  3988. // If the first section does not need to be moved then we exclude it
  3989. // from condideration in passes 1 and 2
  3990. FirstSection = SectionTable + 1;
  3991. } else {
  3992. FirstSection = SectionTable;
  3993. }
  3994. for (Section = FirstSection; Section < LastSection; Section++) {
  3995. SrcVirtualAddress = (ULONG_PTR)mbi.AllocationBase + Section->PointerToRawData;
  3996. DestVirtualAddress = (ULONG_PTR)mbi.AllocationBase + (ULONG_PTR)Section->VirtualAddress;
  3997. // Compute the subsection size
  3998. SubSectionSize = Section->SizeOfRawData;
  3999. if (Section->Misc.VirtualSize &&
  4000. SubSectionSize > MI_ROUND_TO_SIZE(Section->Misc.VirtualSize, PAGE_SIZE_X86NT)) {
  4001. SubSectionSize = MI_ROUND_TO_SIZE(Section->Misc.VirtualSize, PAGE_SIZE_X86NT);
  4002. }
  4003. if (SubSectionSize != 0 && Section->PointerToRawData != 0) {
  4004. // subsection has some meaning
  4005. if ((ULONG_PTR)BaseAddress >= DestVirtualAddress &&
  4006. (ULONG_PTR)BaseAddress < DestVirtualAddress+SubSectionSize) {
  4007. // the pointer points to within this Destination
  4008. // range for this subsection. Adjust it to point
  4009. // into the source range.
  4010. BaseAddress = (PVOID)((ULONG_PTR)BaseAddress - DestVirtualAddress + SrcVirtualAddress);
  4011. LOGPRINT((TRACELOG, "whNtWriteVirtualMemory: Adjusted BaseAddress is %p\n", BaseAddress));
  4012. break;
  4013. }
  4014. }
  4015. }
  4016. SkipHack:;
  4017. }
  4018. End=
  4019. TemplateName=NtGetWriteWatch
  4020. NoType=UserAddressArray
  4021. Locals=
  4022. ULONG_PTR NumberOfPages;
  4023. ULONG_PTR Counter;
  4024. End=
  4025. PreCall=
  4026. if (!WOW64_IS_WRITE_WATCH_SUPPORTED ()) {
  4027. return STATUS_NOT_SUPPORTED;
  4028. }
  4029. UserAddressArray = UlongToPtr (UserAddressArrayHost);
  4030. try {
  4031. NumberOfPages = *EntriesInUserAddressArray;
  4032. if (NumberOfPages > 0) {
  4033. if (ARGUMENT_PRESENT (UserAddressArray)) {
  4034. UserAddressArray = Wow64AllocateTemp (sizeof (PVOID) * NumberOfPages);
  4035. if (UserAddressArray == NULL) {
  4036. return STATUS_NO_MEMORY;
  4037. }
  4038. for (Counter = 0 ; Counter < NumberOfPages ; Counter++) {
  4039. UserAddressArray [Counter] = UlongToPtr (((PULONG)UserAddressArrayHost)[Counter]);
  4040. }
  4041. } else {
  4042. NumberOfPages = 0;
  4043. }
  4044. }
  4045. } except (EXCEPTION_EXECUTE_HANDLER) {
  4046. return GetExceptionCode ();
  4047. }
  4048. End=
  4049. PostCall=
  4050. if (NT_SUCCESS (RetVal)) {
  4051. if (NumberOfPages > 0) {
  4052. for (Counter = 0 ; Counter < NumberOfPages ; Counter++) {
  4053. (((PULONG)UserAddressArrayHost)[Counter]) = PtrToUlong (UserAddressArray [Counter]);
  4054. }
  4055. }
  4056. }
  4057. End=
  4058. Begin=
  4059. @GenApiThunk(@ApiName)
  4060. End=
  4061. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4062. ;;
  4063. ;; Some platforms don't support AWE
  4064. ;;
  4065. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4066. TemplateName=NtMapUserPhysicalPages
  4067. NoType=UserPfnArray
  4068. Locals=
  4069. ULONG_PTR Counter;
  4070. End=
  4071. PreCall=
  4072. if (!WOW64_IS_AWE_SUPPORTED ()) {
  4073. return STATUS_NOT_SUPPORTED;
  4074. }
  4075. if (ARGUMENT_PRESENT (UserPfnArrayHost)) {
  4076. if (NumberOfPages > 0) {
  4077. UserPfnArray = Wow64AllocateTemp (NumberOfPages * sizeof (ULONG_PTR));
  4078. if (UserPfnArray == NULL) {
  4079. return STATUS_NO_MEMORY;
  4080. }
  4081. try {
  4082. for (Counter = 0 ; Counter < NumberOfPages ; Counter++) {
  4083. UserPfnArray [Counter] = UlongToPtr (((PULONG)UserPfnArrayHost) [Counter]);
  4084. }
  4085. } except (EXCEPTION_EXECUTE_HANDLER) {
  4086. return GetExceptionCode ();
  4087. }
  4088. }
  4089. } else {
  4090. UserPfnArray = UlongToPtr (UserPfnArrayHost);
  4091. }
  4092. End=
  4093. Begin=
  4094. @GenApiThunk(@ApiName)
  4095. End=
  4096. TemplateName=NtMapUserPhysicalPagesScatter
  4097. NoType=UserPfnArray
  4098. Locals=
  4099. ULONG_PTR Counter;
  4100. End=
  4101. PreCall=
  4102. if (!WOW64_IS_AWE_SUPPORTED ()) {
  4103. return STATUS_NOT_SUPPORTED;
  4104. }
  4105. if (ARGUMENT_PRESENT (UserPfnArrayHost)) {
  4106. if (NumberOfPages > 0) {
  4107. UserPfnArray = Wow64AllocateTemp (NumberOfPages * sizeof (ULONG_PTR));
  4108. if (UserPfnArray == NULL) {
  4109. return STATUS_NO_MEMORY;
  4110. }
  4111. try {
  4112. for (Counter = 0 ; Counter < NumberOfPages ; Counter++) {
  4113. UserPfnArray [Counter] = UlongToPtr (((PULONG)UserPfnArrayHost) [Counter]);
  4114. }
  4115. } except (EXCEPTION_EXECUTE_HANDLER) {
  4116. return GetExceptionCode ();
  4117. }
  4118. }
  4119. } else {
  4120. UserPfnArray = UlongToPtr (UserPfnArrayHost);
  4121. }
  4122. End=
  4123. Begin=
  4124. @GenApiThunk(@ApiName)
  4125. End=
  4126. TemplateName=NtAllocateUserPhysicalPages
  4127. NoType=UserPfnArray
  4128. Locals=
  4129. ULONG_PTR Counter;
  4130. End=
  4131. PreCall=
  4132. if (!WOW64_IS_AWE_SUPPORTED ()) {
  4133. return STATUS_NOT_SUPPORTED;
  4134. }
  4135. UserPfnArray = NULL;
  4136. try {
  4137. if (*NumberOfPages > 0) {
  4138. UserPfnArray = Wow64AllocateTemp (*NumberOfPages * sizeof (ULONG_PTR));
  4139. if (UserPfnArray == NULL) {
  4140. return STATUS_NO_MEMORY;
  4141. }
  4142. }
  4143. } except (EXCEPTION_EXECUTE_HANDLER) {
  4144. return GetExceptionCode ();
  4145. }
  4146. End=
  4147. PostCall=
  4148. if (NT_SUCCESS (RetVal)) {
  4149. if (*NumberOfPages > 0) {
  4150. for (Counter = 0 ; Counter < *NumberOfPages ; Counter++) {
  4151. ((PULONG)UserPfnArrayHost) [Counter] = (ULONG)UserPfnArray [Counter];
  4152. }
  4153. }
  4154. }
  4155. End=
  4156. Begin=
  4157. @GenApiThunk(@ApiName)
  4158. End=
  4159. TemplateName=NtFreeUserPhysicalPages
  4160. NoType=UserPfnArray
  4161. Locals=
  4162. ULONG_PTR Counter;
  4163. End=
  4164. PreCall=
  4165. if (!WOW64_IS_AWE_SUPPORTED ()) {
  4166. return STATUS_NOT_SUPPORTED;
  4167. }
  4168. UserPfnArray = NULL;
  4169. try {
  4170. if (*NumberOfPages > 0) {
  4171. UserPfnArray = Wow64AllocateTemp (*NumberOfPages * sizeof (ULONG_PTR));
  4172. if (UserPfnArray == NULL) {
  4173. return STATUS_NO_MEMORY;
  4174. }
  4175. for (Counter = 0 ; Counter < *NumberOfPages ; Counter++) {
  4176. UserPfnArray [Counter] = UlongToPtr (((PULONG)UserPfnArrayHost) [Counter]);
  4177. }
  4178. }
  4179. } except (EXCEPTION_EXECUTE_HANDLER) {
  4180. return GetExceptionCode ();
  4181. }
  4182. End=
  4183. Begin=
  4184. @GenApiThunk(@ApiName)
  4185. End=
  4186. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4187. ;;
  4188. ;; VDM is not supported on NT64
  4189. ;;
  4190. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4191. TemplateName=NtVdmControl
  4192. Begin=
  4193. @GenUnsupportedNtApiThunk
  4194. End=
  4195. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4196. ;;
  4197. ;; Debugging the kernel from a 32bit app is unsupported.
  4198. ;;
  4199. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4200. TemplateName=NtSystemDebugControl
  4201. Begin=
  4202. @GenUnsupportedNtApiThunk
  4203. End=
  4204. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4205. ;;
  4206. ;; Application compatibility cache support
  4207. ;;
  4208. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4209. TemplateName=NtApphelpCacheControl
  4210. NoType=ServiceData
  4211. Locals=
  4212. AHCACHESERVICEDATA ServiceData64;
  4213. End=
  4214. PreCall=
  4215. if (ARGUMENT_PRESENT(ServiceDataHost) != 0) {
  4216. @ForceType(PreCall,ServiceData64,(*(NT32AHCACHESERVICEDATA *)ServiceDataHost),AHCACHESERVICEDATA,IN) @NL
  4217. ServiceData = (PVOID)&ServiceData64;
  4218. }
  4219. End=
  4220. Begin=
  4221. @GenApiThunk(@ApiName)
  4222. End=
  4223. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4224. ;;
  4225. ;; File header
  4226. ;;
  4227. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  4228. [Code]
  4229. TemplateName=whnt32
  4230. CGenBegin=
  4231. @NoFormat(
  4232. /*
  4233. * genthunk generated code: Do Not Modify
  4234. * PlaceHolderThunk for kernel transitions from ntdll.dll
  4235. *
  4236. */
  4237. #define _WOW64DLLAPI_
  4238. #define SECURITY_USERMODE // needed when including spmlpc.h
  4239. // For alpha 64 we emulate 4k pages for compatibility w/ intel
  4240. #define _WHNT32_C_
  4241. #include "nt32.h"
  4242. #include "cgenhdr.h"
  4243. #include <stdio.h>
  4244. #include <stdlib.h>
  4245. #include <malloc.h>
  4246. #include <windef.h>
  4247. #include <ntosdef.h>
  4248. #include <procpowr.h>
  4249. #if defined(_X86_)
  4250. #include <v86emul.h>
  4251. #include <i386.h>
  4252. #elif defined(_AMD64_)
  4253. #include <amd64.h>
  4254. #elif defined(_IA64_)
  4255. #include <v86emul.h>
  4256. #include <ia64.h>
  4257. #else
  4258. #error "No Target Architecture"
  4259. #endif
  4260. #include <arc.h>
  4261. #include <ke.h>
  4262. #include "wow64.h"
  4263. #include "wow64p.h"
  4264. #include "wow64cpu.h"
  4265. #include "thnkhlpr.h"
  4266. #include "wow64warn.h"
  4267. ASSERTNAME;
  4268. #if defined(WOW64DOPROFILE)
  4269. #define APIPROFILE(apinum) (ptewhnt32[(apinum)].HitCount++)
  4270. #else
  4271. #define APIPROFILE(apinum)
  4272. #endif
  4273. #define _NTBASE_API_ 1 // Return NTSTATUS exception codes for the NtBase APIs
  4274. #define ROUND_UP(n,size) (((ULONG)(n) + (size - 1)) & ~(size - 1))
  4275. #pragma warning(disable : 4311) //Disable 'type cast' pointer truncation warning
  4276. #pragma warning(disable : 4244)
  4277. #pragma warning(disable : 4242)
  4278. #pragma warning(disable : 4047)
  4279. #if defined(WOW64DOPROFILE)
  4280. WOW64SERVICE_PROFILE_TABLE_ELEMENT ptewhnt32[];
  4281. #endif
  4282. )
  4283. #if defined(WOW64DOPROFILE) @NL
  4284. @ApiList(#define @ApiName_PROFILE_SUBLIST NULL @NL)
  4285. #endif @NL
  4286. #define IS_IOCTL_REALIGNMENT_REQUIRED(Ioctl) ((DEVICE_TYPE_FROM_CTL_CODE(Ioctl) == FILE_DEVICE_FILE_SYSTEM) && ((Ioctl & 3) == METHOD_NEITHER)) @NL
  4287. @NoFormat(
  4288. ULONG
  4289. whNT32DeepThunkSidAndAttributesArray64TO32Length(
  4290. IN ULONG ArrayLength,
  4291. IN PSID_AND_ATTRIBUTES Source
  4292. )
  4293. {
  4294. ULONG RequiredLength = 0;
  4295. if (!ArrayLength) return RequiredLength;
  4296. while(ArrayLength-- > 0) {
  4297. RequiredLength += sizeof(NT32SID_AND_ATTRIBUTES);
  4298. RequiredLength += RtlLengthSid(Source->Sid);
  4299. Source++;
  4300. }
  4301. return RequiredLength;
  4302. }
  4303. ULONG
  4304. whNT32DeepThunkSidAndAttributesArray32TO64Length(
  4305. IN ULONG ArrayLength,
  4306. IN NT32SID_AND_ATTRIBUTES *Source
  4307. )
  4308. {
  4309. ULONG RequiredLength = 0;
  4310. if (!ArrayLength) return RequiredLength;
  4311. while(ArrayLength-- > 0) {
  4312. RequiredLength += sizeof(SID_AND_ATTRIBUTES);
  4313. RequiredLength += RtlLengthSid((PSID)Source->Sid);
  4314. Source++;
  4315. }
  4316. return RequiredLength;
  4317. }
  4318. NT32SID_AND_ATTRIBUTES *
  4319. whNT32DeepThunkSidAndAttributesArray64TO32(
  4320. IN ULONG ArrayLength,
  4321. OUT NT32SID_AND_ATTRIBUTES *Dest,
  4322. IN PSID_AND_ATTRIBUTES Source
  4323. )
  4324. {
  4325. PSID SidDest;
  4326. NT32SID_AND_ATTRIBUTES *OriginalDest = Dest;
  4327. if (!ArrayLength) return (NT32SID_AND_ATTRIBUTES *)NULL;
  4328. SidDest = (PSID)(Dest + ArrayLength);
  4329. while(ArrayLength-- > 0) {
  4330. ULONG SidLength;
  4331. SidLength = RtlLengthSid(Source->Sid);
  4332. RtlCopySid(SidLength,
  4333. SidDest,
  4334. Source->Sid);
  4335. Dest->Sid = (NT32PSID)SidDest;
  4336. Dest->Attributes = Source->Attributes;
  4337. Dest++;
  4338. Source++;
  4339. SidDest = (PSID)((PBYTE)SidDest + SidLength);
  4340. }
  4341. return OriginalDest;
  4342. }
  4343. PSID_AND_ATTRIBUTES
  4344. whNT32DeepThunkSidAndAttributesArray32TO64(
  4345. IN ULONG ArrayLength,
  4346. OUT PSID_AND_ATTRIBUTES Dest,
  4347. IN NT32SID_AND_ATTRIBUTES *Source
  4348. )
  4349. {
  4350. PSID SidDest;
  4351. PSID_AND_ATTRIBUTES OriginalDest = Dest;
  4352. if (!ArrayLength) return NULL;
  4353. SidDest = (PSID)(Dest + ArrayLength);
  4354. while(ArrayLength-- > 0) {
  4355. ULONG SidLength;
  4356. SidLength = RtlLengthSid((PSID)Source->Sid);
  4357. RtlCopySid(SidLength,
  4358. SidDest,
  4359. (PSID)Source->Sid);
  4360. Dest->Sid = (PSID)SidDest;
  4361. Dest->Attributes = Source->Attributes;
  4362. Dest++;
  4363. Source++;
  4364. SidDest = (PSID)((PBYTE)SidDest + SidLength);
  4365. }
  4366. return OriginalDest;
  4367. }
  4368. ULONG
  4369. whNT32DeepThunkTokenGroups64TO32Length(
  4370. IN PTOKEN_GROUPS Src
  4371. )
  4372. {
  4373. if (!Src) return 0;
  4374. return sizeof(ULONG) +
  4375. whNT32DeepThunkSidAndAttributesArray64TO32Length(Src->GroupCount, Src->Groups);
  4376. }
  4377. ULONG
  4378. whNT32DeepThunkTokenGroups32TO64Length(
  4379. IN NT32TOKEN_GROUPS *Src
  4380. )
  4381. {
  4382. if (!Src) return 0;
  4383. return sizeof(ULONG) +
  4384. whNT32DeepThunkSidAndAttributesArray32TO64Length(Src->GroupCount, (NT32SID_AND_ATTRIBUTES*)Src->Groups);
  4385. }
  4386. NT32TOKEN_GROUPS *
  4387. whNT32DeepThunkTokenGroups64TO32(
  4388. OUT NT32TOKEN_GROUPS *Dst,
  4389. IN PTOKEN_GROUPS Src
  4390. )
  4391. {
  4392. if (!Src) return (NT32TOKEN_GROUPS *)Src;
  4393. Dst->GroupCount = Src->GroupCount;
  4394. whNT32DeepThunkSidAndAttributesArray64TO32(Src->GroupCount, (NT32SID_AND_ATTRIBUTES*)Dst->Groups, Src->Groups);
  4395. return Dst;
  4396. }
  4397. PTOKEN_GROUPS
  4398. whNT32DeepThunkTokenGroups32TO64(
  4399. OUT PTOKEN_GROUPS Dst,
  4400. IN NT32TOKEN_GROUPS *Src
  4401. )
  4402. {
  4403. if (!Src) return (PTOKEN_GROUPS)Src;
  4404. Dst->GroupCount = Src->GroupCount;
  4405. whNT32DeepThunkSidAndAttributesArray32TO64(Src->GroupCount, Dst->Groups, (NT32SID_AND_ATTRIBUTES*)Src->Groups);
  4406. return Dst;
  4407. }
  4408. PTOKEN_GROUPS
  4409. whNT32ShallowThunkAllocTokenGroups32TO64(
  4410. IN NT32TOKEN_GROUPS *Src
  4411. )
  4412. {
  4413. PTOKEN_GROUPS Dest;
  4414. ULONG GroupCount;
  4415. UINT c;
  4416. if(!Src) {
  4417. return (PTOKEN_GROUPS)Src;
  4418. }
  4419. GroupCount = Src->GroupCount;
  4420. Dest = Wow64AllocateTemp(sizeof(ULONG) + sizeof(SID_AND_ATTRIBUTES) * GroupCount);
  4421. Dest->GroupCount = GroupCount;
  4422. for(c=0; c<GroupCount; c++) {
  4423. Dest->Groups[c].Sid = (PSID)Src->Groups[c].Sid;
  4424. Dest->Groups[c].Attributes = Src->Groups[c].Attributes;
  4425. }
  4426. return Dest;
  4427. }
  4428. POBJECT_TYPE_LIST
  4429. whNT32ShallowThunkAllocObjectTypeList32TO64(
  4430. IN NT32OBJECT_TYPE_LIST *Src,
  4431. ULONG Elements
  4432. )
  4433. {
  4434. POBJECT_TYPE_LIST Dest;
  4435. SIZE_T c;
  4436. if (0 == Elements || !Src) {
  4437. return NULL;
  4438. }
  4439. Dest = Wow64AllocateTemp(sizeof(OBJECT_TYPE_LIST)*Elements);
  4440. for(c=0;c<Elements; c++) {
  4441. Dest[c].Level = Src[c].Level;
  4442. Dest[c].Sbz = Src[c].Sbz;
  4443. Dest[c].ObjectType = (GUID *)Src[c].ObjectType;
  4444. }
  4445. return Dest;
  4446. }
  4447. RTL_CRITICAL_SECTION HandleDataCriticalSection;
  4448. @Template(Thunks)
  4449. @NL
  4450. // All of the native NT APIs return an error code as the return parameter. @NL
  4451. // Thus, all that is needed is to return the exception code in the return value. @NL
  4452. @NL
  4453. // Exception code in return value. @NL
  4454. #define WOW64_DEFAULT_ERROR_ACTION ApiErrorNTSTATUS @NL
  4455. @NL
  4456. // This parameter is unused. @NL
  4457. #define WOW64_DEFAULT_ERROR_PARAM 0 @NL
  4458. @NL
  4459. // A case list is not needed for these APIs. @NL
  4460. #define WOW64_API_ERROR_CASES NULL @NL
  4461. @NL
  4462. @GenDispatchTable(sdwhnt32)
  4463. @NL
  4464. #if defined(WOW64DOPROFILE) @NL
  4465. @NL
  4466. WOW64SERVICE_PROFILE_TABLE_ELEMENT ptewhnt32[] = { @Indent( @NL
  4467. @ApiList({L"@ApiName", 0, @ApiName_PROFILE_SUBLIST, TRUE}, @NL)
  4468. {NULL, 0, NULL, TRUE} //For debugging @NL
  4469. )};@NL
  4470. @NL
  4471. @NL
  4472. WOW64SERVICE_PROFILE_TABLE ptwhnt32 = {L"WHNT32", L"NT Executive Thunks", ptewhnt32,
  4473. (sizeof(ptewhnt32)/sizeof(WOW64SERVICE_PROFILE_TABLE_ELEMENT))-1}; @NL
  4474. @NL
  4475. #endif @NL
  4476. CGenEnd=