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

1061 lines
23 KiB

  1. /*++
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. wow64log.c
  5. Abstract:
  6. Main entrypoints for wow64log.dll. To add a data type handler :
  7. 1- Define a LOGDATATYPE for the data to log in w64logp.h
  8. 2- Implement the data type handler using the standard interface
  9. NTSTATUS
  10. LogDataType(IN OUT PLOGINFO LogInfo,
  11. IN ULONG_PTR Data,
  12. IN PSZ FieldName,
  13. IN BOOLEAN ServiceReturn);
  14. 3- Insert the handler into LogDataType[] below.
  15. Author:
  16. 03-Oct-1999 SamerA
  17. Revision History:
  18. --*/
  19. #include "w64logp.h"
  20. /// Public
  21. //
  22. // Control logging flags
  23. //
  24. UINT_PTR Wow64LogFlags;
  25. HANDLE Wow64LogFileHandle;
  26. /// Private
  27. //
  28. // Hold an array of pointers to each system service DebugThunkInfo
  29. //
  30. PULONG_PTR *LogNtBase;
  31. PULONG_PTR *LogWin32;
  32. PULONG_PTR *LogConsole;
  33. PULONG_PTR *LogBase;
  34. //
  35. // NOTE : The order entries in this table should match the LOGTYPE enum in
  36. // w64logp.h.
  37. //
  38. LOGDATATYPE LogDataType[] =
  39. {
  40. {LogTypeValue}, // TypeHex
  41. {LogTypePULongInOut}, // TypePULongPtrInOut
  42. {LogTypePULongOut}, // TypePULONGOut
  43. {LogTypePULongOut}, // TypePHandleOut
  44. {LogTypeUnicodeString}, // TypeUnicodeStringIn
  45. {LogTypeObjectAttrbiutes}, // TypeObjectAttributesIn
  46. {LogTypeIoStatusBlock}, // TypeIoStatusBlockOut
  47. {LogTypePWStr}, // TypePwstrIn
  48. {LogTypePRectIn}, // TypePRectIn
  49. {LogTypePLargeIntegerIn}, // TypePLargeIntegerIn
  50. };
  51. WOW64LOGAPI
  52. NTSTATUS
  53. Wow64LogInitialize(
  54. VOID)
  55. /*++
  56. Routine Description:
  57. This function is called by wow64.dll to initialize wow64 logging
  58. subsystem.
  59. Arguments:
  60. None
  61. Return Value:
  62. NTSTATUS
  63. --*/
  64. {
  65. ULONG NtBaseTableSize, Win32TableSize, ConsoleTableSize, BaseTableSize;
  66. PULONG_PTR *Win32ThunkDebugInfo;
  67. PULONG_PTR *ConsoleThunkDebugInfo;
  68. UNICODE_STRING Log2Name;
  69. PVOID Log2Handle;
  70. NTSTATUS st;
  71. //
  72. // Initialize the logging file handle
  73. //
  74. Wow64LogFileHandle = INVALID_HANDLE_VALUE;
  75. //
  76. // Initialize the logging flags
  77. //
  78. LogInitializeFlags(&Wow64LogFlags);
  79. WOW64LOGOUTPUT((LF_TRACE, "Wow64LogInitialize - Wow64LogFlags = %I64x\n", Wow64LogFlags));
  80. //
  81. // Load the Win32 logging DLL if available.
  82. //
  83. RtlInitUnicodeString(&Log2Name, L"wow64lg2.dll");
  84. st = LdrLoadDll(NULL, NULL, &Log2Name, &Log2Handle);
  85. if (NT_SUCCESS(st)) {
  86. ANSI_STRING ExportName;
  87. RtlInitAnsiString(&ExportName, "Win32ThunkDebugInfo");
  88. st = LdrGetProcedureAddress(Log2Handle, &ExportName, 0, &(PVOID)Win32ThunkDebugInfo);
  89. if (NT_SUCCESS(st)) {
  90. RtlInitAnsiString(&ExportName, "ConsoleThunkDebugInfo");
  91. st = LdrGetProcedureAddress(Log2Handle, &ExportName, 0, &(PVOID)ConsoleThunkDebugInfo);
  92. }
  93. }
  94. if (!NT_SUCCESS(st)) {
  95. Log2Handle = NULL;
  96. Win32ThunkDebugInfo = NULL;
  97. ConsoleThunkDebugInfo = NULL;
  98. }
  99. //
  100. // Build pointers to the debug thunk info for each
  101. // system service
  102. //
  103. NtBaseTableSize = GetThunkDebugTableSize(
  104. (PTHUNK_DEBUG_INFO)NtThunkDebugInfo);
  105. BaseTableSize = GetThunkDebugTableSize(
  106. (PTHUNK_DEBUG_INFO)BaseThunkDebugInfo);
  107. if (Log2Handle) {
  108. Win32TableSize = GetThunkDebugTableSize(
  109. (PTHUNK_DEBUG_INFO)Win32ThunkDebugInfo);
  110. ConsoleTableSize = GetThunkDebugTableSize(
  111. (PTHUNK_DEBUG_INFO)ConsoleThunkDebugInfo);
  112. } else {
  113. Win32TableSize = 0;
  114. ConsoleTableSize = 0;
  115. }
  116. LogNtBase = (PULONG_PTR *)Wow64AllocateHeap((NtBaseTableSize + Win32TableSize + ConsoleTableSize + BaseTableSize) *
  117. sizeof(PULONG_PTR) );
  118. if (!LogNtBase)
  119. {
  120. WOW64LOGOUTPUT((LF_ERROR, "Wow64LogInitialize - Wow64AllocateHeap failed\n"));
  121. return STATUS_UNSUCCESSFUL;
  122. }
  123. LogWin32 = LogNtBase + NtBaseTableSize;
  124. LogConsole = LogWin32 + Win32TableSize;
  125. LogBase = LogConsole + ConsoleTableSize;
  126. BuildDebugThunkInfo((PTHUNK_DEBUG_INFO)NtThunkDebugInfo, LogNtBase);
  127. BuildDebugThunkInfo((PTHUNK_DEBUG_INFO)BaseThunkDebugInfo, LogBase);
  128. if (Log2Handle) {
  129. BuildDebugThunkInfo((PTHUNK_DEBUG_INFO)Win32ThunkDebugInfo, LogWin32);
  130. BuildDebugThunkInfo((PTHUNK_DEBUG_INFO)ConsoleThunkDebugInfo, LogConsole);
  131. }
  132. return STATUS_SUCCESS;
  133. }
  134. WOW64LOGAPI
  135. NTSTATUS
  136. Wow64LogTerminate(
  137. VOID)
  138. /*++
  139. Routine Description:
  140. This function is called by wow64.dll when the process is exiting.
  141. Arguments:
  142. None
  143. Return Value:
  144. NTSTATUS
  145. --*/
  146. {
  147. IO_STATUS_BLOCK IoStatusBlock;
  148. if (Wow64LogFileHandle != INVALID_HANDLE_VALUE)
  149. {
  150. NtFlushBuffersFile(Wow64LogFileHandle, &IoStatusBlock);
  151. NtClose(Wow64LogFileHandle);
  152. }
  153. return STATUS_SUCCESS;
  154. }
  155. NTSTATUS
  156. LogInitializeFlags(
  157. IN OUT PUINT_PTR Flags)
  158. /*++
  159. Routine Description:
  160. Reads the logging flags from the registry
  161. Arguments:
  162. Flags - Pointer to receive logging flags
  163. Return Value:
  164. NTSTATUS
  165. --*/
  166. {
  167. HANDLE Key;
  168. UNICODE_STRING KeyName, ValueName, ResultValue;
  169. OBJECT_ATTRIBUTES ObjectAttributes;
  170. WCHAR KeyValueBuffer[ 128 ];
  171. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
  172. ULONG ResultLength, RegFlags;
  173. NTSTATUS NtStatus;
  174. //
  175. // Punch in the default
  176. //
  177. *Flags = LF_DEFAULT;
  178. KeyValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)KeyValueBuffer;
  179. RtlInitUnicodeString(&KeyName,
  180. L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager");
  181. InitializeObjectAttributes(&ObjectAttributes,
  182. &KeyName,
  183. OBJ_CASE_INSENSITIVE,
  184. NULL,
  185. NULL);
  186. NtStatus = NtOpenKey(&Key, KEY_READ, &ObjectAttributes);
  187. if (NT_SUCCESS(NtStatus))
  188. {
  189. RtlInitUnicodeString(&ValueName, L"WOW64LOGFLAGS");
  190. NtStatus = NtQueryValueKey(Key,
  191. &ValueName,
  192. KeyValuePartialInformation,
  193. KeyValueInformation,
  194. sizeof(KeyValueBuffer),
  195. &ResultLength);
  196. if (NT_SUCCESS(NtStatus))
  197. {
  198. if ((KeyValueInformation->Type == REG_DWORD) &&
  199. (KeyValueInformation->DataLength == sizeof(DWORD)))
  200. {
  201. *Flags = *((PULONG)KeyValueInformation->Data);
  202. }
  203. }
  204. }
  205. return NtStatus;
  206. }
  207. ULONG
  208. GetThunkDebugTableSize(
  209. IN PTHUNK_DEBUG_INFO DebugInfoTable)
  210. /*++
  211. Routine Description:
  212. This routine retreives the number of DebugThunkInfo entries
  213. in the passed table.
  214. Arguments:
  215. DebugInfoTable - Pointer to services debug info
  216. Return Value:
  217. Number of entries
  218. --*/
  219. {
  220. ULONG Count = 0;
  221. while (DebugInfoTable && DebugInfoTable->ApiName)
  222. {
  223. Count++;
  224. DebugInfoTable = (PTHUNK_DEBUG_INFO)
  225. &DebugInfoTable->Arg[DebugInfoTable->NumberOfArg];
  226. }
  227. return Count;
  228. }
  229. NTSTATUS
  230. BuildDebugThunkInfo(
  231. IN PTHUNK_DEBUG_INFO DebugInfoTable,
  232. OUT PULONG_PTR *LogTable)
  233. /*++
  234. Routine Description:
  235. This routine fills a service-table-indexed with pointers
  236. to the corresponding DebugThunkInfo
  237. Arguments:
  238. DebugInfoTable - Services debug info
  239. LogTable - Table of pointers to fill
  240. Return Value:
  241. NTSTATUS
  242. --*/
  243. {
  244. ULONG i=0;
  245. while (DebugInfoTable && DebugInfoTable->ApiName)
  246. {
  247. LogTable[i++] = (PULONG_PTR) DebugInfoTable;
  248. DebugInfoTable = (PTHUNK_DEBUG_INFO)
  249. &DebugInfoTable->Arg[DebugInfoTable->NumberOfArg];
  250. }
  251. return STATUS_SUCCESS;
  252. }
  253. NTSTATUS
  254. LogApiHeader(
  255. PTHUNK_DEBUG_INFO ThunkDebugInfo,
  256. PLOGINFO LogInfo,
  257. BOOLEAN ServiceReturn,
  258. ULONG_PTR ReturnResult,
  259. ULONG_PTR ReturnAddress)
  260. /*++
  261. Routine Description:
  262. Log the Thunked API header
  263. Arguments:
  264. ThunkDebugInfo - Pointer to service log info
  265. LogInfo - Logging Info
  266. ServiceReturn - TRUE if called after the thunk API has executed
  267. ReturnResult - Result code returned from the API
  268. ReturnAddress - Return address of for this thunked call
  269. Return Value:
  270. NTSTATUS
  271. --*/
  272. {
  273. if (ServiceReturn)
  274. {
  275. return LogFormat(LogInfo,
  276. "wh%s: Ret=%lx-%lx: ",
  277. ThunkDebugInfo->ApiName,
  278. ReturnResult,
  279. ReturnAddress);
  280. }
  281. return LogFormat(LogInfo,
  282. "%8.8X-wh%s: ",
  283. PtrToUlong(NtCurrentTeb()->ClientId.UniqueThread),
  284. ThunkDebugInfo->ApiName);
  285. }
  286. NTSTATUS
  287. LogApiParameters(
  288. IN OUT PLOGINFO LogInfo,
  289. IN PULONG Stack32,
  290. IN PTHUNK_DEBUG_INFO ThunkDebugInfo,
  291. IN BOOLEAN ServiceReturn)
  292. /*++
  293. Routine Description:
  294. Log the Thunked API Parameters
  295. Arguments:
  296. LogInfo - Output log buffer
  297. Stack32 - Pointer to 32-bit arg stack
  298. ThunkDebugInfo - Pointer to service log info for the API
  299. ServiceReturn - TRUE if called after the Thunk API has executed
  300. Return Value:
  301. NTSTATUS
  302. --*/
  303. {
  304. UINT_PTR i=0;
  305. //
  306. // Loops thru the parameters
  307. //
  308. while (i < ThunkDebugInfo->NumberOfArg)
  309. {
  310. _try
  311. {
  312. LogDataType[ThunkDebugInfo->Arg[i].Type].Handler(
  313. LogInfo,
  314. Stack32[i],
  315. ThunkDebugInfo->Arg[i].Name,
  316. ServiceReturn);
  317. }
  318. _except(EXCEPTION_EXECUTE_HANDLER)
  319. {
  320. //
  321. // Log the bad parameters
  322. //
  323. LogFormat(LogInfo,
  324. "%s=%lx-%ws ",
  325. ThunkDebugInfo->Arg[i].Name,
  326. Stack32[i],
  327. L"(BAD)");
  328. }
  329. i++;
  330. }
  331. return STATUS_SUCCESS;
  332. }
  333. NTSTATUS
  334. LogThunkApi(
  335. IN PTHUNK_LOG_CONTEXT ThunkLogContext,
  336. IN PTHUNK_DEBUG_INFO ThunkDebugInfo,
  337. IN UINT_PTR LogFullInfo)
  338. /*++
  339. Routine Description:
  340. Log the Thunked API
  341. Arguments:
  342. ThunkLogContext - Thunk API log context
  343. ThunkDebugInfo - Pointer to service log info for the API
  344. LogFullInfo - Flag whther to log all the API info or just the name
  345. Return Value:
  346. NTSTATUS
  347. --*/
  348. {
  349. NTSTATUS NtStatus;
  350. CHAR szBuf[ MAX_LOG_BUFFER ];
  351. LOGINFO LogInfo;
  352. PULONG Stack32 = ThunkLogContext->Stack32;
  353. BOOLEAN ServiceReturn = ThunkLogContext->ServiceReturn;
  354. //
  355. // Initialize the log buffer
  356. //
  357. LogInfo.OutputBuffer = szBuf;
  358. LogInfo.BufferSize = MAX_LOG_BUFFER - 1;
  359. //
  360. // Log API header
  361. //
  362. NtStatus = LogApiHeader(ThunkDebugInfo,
  363. &LogInfo,
  364. ServiceReturn,
  365. ThunkLogContext->ReturnResult,
  366. *(Stack32-1));
  367. if (!NT_SUCCESS(NtStatus))
  368. {
  369. return NtStatus;
  370. }
  371. // Log Parameters
  372. if (LogFullInfo)
  373. {
  374. NtStatus = LogApiParameters(&LogInfo,
  375. Stack32,
  376. ThunkDebugInfo,
  377. ServiceReturn);
  378. if (!NT_SUCCESS(NtStatus))
  379. {
  380. return NtStatus;
  381. }
  382. }
  383. //
  384. // Do actual output
  385. //
  386. LogInfo.OutputBuffer[0] = '\0';
  387. LogOut(szBuf, Wow64LogFlags);
  388. LogOut("\r\n", Wow64LogFlags);
  389. return NtStatus;
  390. }
  391. WOW64LOGAPI
  392. NTSTATUS
  393. Wow64LogSystemService(
  394. IN PTHUNK_LOG_CONTEXT ThunkLogContext)
  395. /*++
  396. Routine Description:
  397. Logs information for the specified system service.
  398. Arguments:
  399. LogContext - Thunk API log context
  400. Return Value:
  401. NTSTATUS
  402. --*/
  403. {
  404. NTSTATUS NtStatus;
  405. PTHUNK_DEBUG_INFO ThunkDebugInfo;
  406. ULONG_PTR TableNumber = ThunkLogContext->TableNumber;
  407. ULONG_PTR ServiceNumber = ThunkLogContext->ServiceNumber;
  408. UINT_PTR LogFullInfo;
  409. //
  410. // Use try except !!
  411. //
  412. _try
  413. {
  414. switch(TableNumber)
  415. {
  416. case WHNT32_INDEX:
  417. if (!LF_NTBASE_ENABLED(Wow64LogFlags))
  418. {
  419. return STATUS_SUCCESS;
  420. }
  421. LogFullInfo = (Wow64LogFlags & LF_NTBASE_FULL);
  422. ThunkDebugInfo = (PTHUNK_DEBUG_INFO)LogNtBase[ServiceNumber];
  423. break;
  424. case WHCON_INDEX:
  425. if (!LF_NTCON_ENABLED(Wow64LogFlags) || LogConsole == NULL)
  426. {
  427. return STATUS_SUCCESS;
  428. }
  429. LogFullInfo = (Wow64LogFlags & LF_NTCON_FULL);
  430. ThunkDebugInfo = (PTHUNK_DEBUG_INFO)LogConsole[ServiceNumber];
  431. break;
  432. case WHWIN32_INDEX:
  433. if (!LF_WIN32_ENABLED(Wow64LogFlags) || LogWin32 == NULL)
  434. {
  435. return STATUS_SUCCESS;
  436. }
  437. LogFullInfo = (Wow64LogFlags & LF_WIN32_FULL);
  438. ThunkDebugInfo = (PTHUNK_DEBUG_INFO)LogWin32[ServiceNumber];
  439. break;
  440. case WHBASE_INDEX:
  441. if (!LF_BASE_ENABLED(Wow64LogFlags))
  442. {
  443. return STATUS_SUCCESS;
  444. }
  445. LogFullInfo = (Wow64LogFlags & LF_BASE_FULL);
  446. ThunkDebugInfo = (PTHUNK_DEBUG_INFO)LogBase[ServiceNumber];
  447. break;
  448. default: // invalid service table
  449. WOW64LOGOUTPUT((LF_ERROR, "Wow64LogSystemService: Not supported table number - %lx\n", TableNumber));
  450. return STATUS_UNSUCCESSFUL;
  451. break;
  452. }
  453. NtStatus = LogThunkApi(ThunkLogContext,
  454. ThunkDebugInfo,
  455. LogFullInfo);
  456. }
  457. _except(EXCEPTION_EXECUTE_HANDLER)
  458. {
  459. WOW64LOGOUTPUT((LF_EXCEPTION, "Wow64LogSystemService : Invalid Service ServiceTable = %lx, ServiceNumber = %lx. Status=%lx\n",
  460. TableNumber, ServiceNumber, GetExceptionCode()));
  461. NtStatus = GetExceptionCode();
  462. }
  463. return NtStatus;
  464. }
  465. //////////////////////////////////////////////////////////////////////////
  466. //
  467. // DATA TYPE LOGGING ROUTINES
  468. //
  469. ///////////////////////////////////////////////////////////////////////////
  470. NTSTATUS
  471. LogTypeValue(
  472. IN OUT PLOGINFO LogInfo,
  473. IN ULONG_PTR Data,
  474. IN PSZ FieldName,
  475. IN BOOLEAN ServiceReturn)
  476. /*++
  477. Routine Description:
  478. Log Data as ULONG
  479. Arguments:
  480. LogInfo - Output log buffer
  481. Data - Value to log
  482. FieldName - Descriptive name of value to log
  483. ServiceReturn - TRUE if called after the thunk API has executed
  484. Return Value:
  485. NTSTATUS
  486. --*/
  487. {
  488. if (ServiceReturn)
  489. {
  490. return STATUS_SUCCESS;
  491. }
  492. return LogFormat(LogInfo,
  493. "%s=%lx ",
  494. FieldName,
  495. (ULONG)Data);
  496. }
  497. NTSTATUS
  498. LogTypeUnicodeString(
  499. IN OUT PLOGINFO LogInfo,
  500. IN ULONG_PTR Data,
  501. IN PSZ FieldName,
  502. IN BOOLEAN ServiceReturn)
  503. /*++
  504. Routine Description:
  505. Log Data as UNICODE_STRING32
  506. Arguments:
  507. LogInfo - Output log buffer
  508. Data - Value to log
  509. FieldName - Descriptive name of value to log
  510. ServiceReturn - TRUE if called after the thunk API has executed
  511. Return Value:
  512. NTSTATUS
  513. --*/
  514. {
  515. UNICODE_STRING32 *Name32;
  516. PWCHAR Buffer = L" ";
  517. if (ServiceReturn)
  518. {
  519. return STATUS_SUCCESS;
  520. }
  521. Name32 = (UNICODE_STRING32 *)Data;
  522. if (Data > 0xffff)
  523. {
  524. if (Name32->Buffer)
  525. {
  526. Buffer = (PWCHAR)Name32->Buffer;
  527. }
  528. if (Name32->Length && Name32->Buffer > 0xffff) {
  529. return LogFormat(LogInfo,
  530. "%s=%ws ",
  531. FieldName,
  532. Buffer);
  533. } else {
  534. return LogFormat(LogInfo,
  535. "%s={L=%x,M=%x,B=%x}",
  536. FieldName,
  537. Name32->Length,
  538. Name32->MaximumLength,
  539. Name32->Buffer);
  540. }
  541. }
  542. return LogFormat(LogInfo,
  543. "%s=%x",
  544. FieldName,
  545. Name32);
  546. }
  547. NTSTATUS
  548. LogTypePULongInOut(
  549. IN OUT PLOGINFO LogInfo,
  550. IN ULONG_PTR Data,
  551. IN PSZ FieldName,
  552. IN BOOLEAN ServiceReturn)
  553. /*++
  554. Routine Description:
  555. Log Data as PULONG
  556. Arguments:
  557. LogInfo - Output log buffer
  558. Data - Value to log
  559. FieldName - Descriptive name of value to log
  560. ServiceReturn - TRUE if called after the thunk API has executed
  561. Return Value:
  562. NTSTATUS
  563. --*/
  564. {
  565. return LogFormat(LogInfo,
  566. "[%s-%lx]=%lx ",
  567. FieldName,
  568. (ULONG)Data,
  569. ((PULONG)Data ? *((PULONG)Data) : 0));
  570. }
  571. NTSTATUS
  572. LogTypePULongOut(
  573. IN OUT PLOGINFO LogInfo,
  574. IN ULONG_PTR Data,
  575. IN PSZ FieldName,
  576. IN BOOLEAN ServiceReturn)
  577. /*++
  578. Routine Description:
  579. Log Data as PULONG (Out field)
  580. Arguments:
  581. LogInfo - Output log buffer
  582. Data - Value to log
  583. FieldName - Descriptive name of value to log
  584. ServiceReturn - TRUE if called after the thunk API has executed
  585. Return Value:
  586. NTSTATUS
  587. --*/
  588. {
  589. if (ServiceReturn)
  590. {
  591. return LogFormat(LogInfo,
  592. "[%s-%lx]=%lx ",
  593. FieldName,
  594. (PULONG)Data,
  595. ((PULONG)Data ? *(PULONG)Data : 0));
  596. }
  597. return LogFormat(LogInfo,
  598. "%s=%lx ",
  599. FieldName,
  600. (PULONG)Data);
  601. }
  602. NTSTATUS
  603. LogTypeObjectAttrbiutes(
  604. IN OUT PLOGINFO LogInfo,
  605. IN ULONG_PTR Data,
  606. IN PSZ FieldName,
  607. IN BOOLEAN ServiceReturn)
  608. /*++
  609. Routine Description:
  610. Log Data as POBJECT_ATTRIBUTES
  611. Arguments:
  612. LogInfo - Output log buffer
  613. Data - Value to log
  614. FieldName - Descriptive name of value to log
  615. ServiceReturn - TRUE if called after the thunk API has executed
  616. Return Value:
  617. NTSTATUS
  618. --*/
  619. {
  620. NT32OBJECT_ATTRIBUTES *ObjA32;
  621. UNICODE_STRING32 *ObjectName = NULL;
  622. PWCHAR Buffer = L"";
  623. if (ServiceReturn)
  624. {
  625. return STATUS_SUCCESS;
  626. }
  627. ObjA32 = (NT32OBJECT_ATTRIBUTES *)Data;
  628. if (ObjA32)
  629. {
  630. ObjectName = (UNICODE_STRING32 *)ObjA32->ObjectName;
  631. if (ObjectName)
  632. {
  633. if (ObjectName->Buffer)
  634. {
  635. Buffer = (PWCHAR)ObjectName->Buffer;
  636. }
  637. }
  638. }
  639. return LogFormat(LogInfo,
  640. "%s=%lx {N=%ws,A=%lx} ",
  641. FieldName,
  642. (PULONG)Data,
  643. Buffer,
  644. (ObjA32 ? ObjA32->Attributes : 0));
  645. }
  646. NTSTATUS
  647. LogTypeIoStatusBlock(
  648. IN OUT PLOGINFO LogInfo,
  649. IN ULONG_PTR Data,
  650. IN PSZ FieldName,
  651. IN BOOLEAN ServiceReturn)
  652. /*++
  653. Routine Description:
  654. Log Data as IO_STATUS_BLOCK
  655. Arguments:
  656. LogInfo - Output log buffer
  657. Data - Value to log
  658. FieldName - Descriptive name of value to log
  659. ServiceReturn - TRUE if called after the thunk API has executed
  660. Return Value:
  661. NTSTATUS
  662. --*/
  663. {
  664. if (ServiceReturn)
  665. {
  666. PIO_STATUS_BLOCK32 StatusBlock32 = (PIO_STATUS_BLOCK32)Data;
  667. return LogFormat(LogInfo,
  668. "%s={S=%lx,I=%lx} ",
  669. FieldName,
  670. (PULONG)Data,
  671. (StatusBlock32 ? StatusBlock32->Status : 0),
  672. (StatusBlock32 ? StatusBlock32->Information : 0));
  673. }
  674. return LogFormat(LogInfo,
  675. "%s=%lx ",
  676. FieldName,
  677. (PULONG)Data);
  678. }
  679. NTSTATUS
  680. LogTypePWStr(
  681. IN OUT PLOGINFO LogInfo,
  682. IN ULONG_PTR Data,
  683. IN PSZ FieldName,
  684. IN BOOLEAN ServiceReturn)
  685. /*++
  686. Routine Description:
  687. Log Data as PWSTR
  688. Arguments:
  689. LogInfo - Output log buffer
  690. Data - Value to log
  691. FieldName - Descriptive name of value to log
  692. ServiceReturn - TRUE if called after the thunk API has executed
  693. Return Value:
  694. NTSTATUS
  695. --*/
  696. {
  697. ULONG_PTR i;
  698. WCHAR Buffer[ 14 ];
  699. PWSTR String = (PWSTR) Data;
  700. if (ServiceReturn)
  701. {
  702. return STATUS_SUCCESS;
  703. }
  704. //
  705. // Sometime this type is treated as a pointer
  706. // to WCHARs without NULL terminating it, like
  707. // how it's used in NtGdiExtTextOutW, so let's dump
  708. // a minimal string
  709. //
  710. if (Data)
  711. {
  712. i = 0;
  713. while((i < ((sizeof(Buffer) / sizeof(WCHAR)) - 4)) && (String[i]))
  714. {
  715. Buffer[i] = String[i];
  716. i++;
  717. }
  718. if (i == ((sizeof(Buffer) / sizeof(WCHAR)) - 4))
  719. {
  720. Buffer[i++] = L'.';
  721. Buffer[i++] = L'.';
  722. Buffer[i++] = L'.';
  723. }
  724. Buffer[i++] = UNICODE_NULL;
  725. }
  726. return LogFormat(LogInfo,
  727. "%s=%ws ",
  728. FieldName,
  729. (Data > 0xffff) ? Buffer : L"");
  730. }
  731. NTSTATUS
  732. LogTypePRectIn(
  733. IN OUT PLOGINFO LogInfo,
  734. IN ULONG_PTR Data,
  735. IN PSZ FieldName,
  736. IN BOOLEAN ServiceReturn)
  737. /*++
  738. Routine Description:
  739. Log Data as PWSTR
  740. Arguments:
  741. LogInfo - Output log buffer
  742. Data - Value to log
  743. FieldName - Descriptive name of value to log
  744. ServiceReturn - TRUE if called after the thunk API has executed
  745. Return Value:
  746. NTSTATUS
  747. --*/
  748. {
  749. if (ServiceReturn)
  750. {
  751. return STATUS_SUCCESS;
  752. }
  753. if (Data)
  754. {
  755. PRECT Rect = (PRECT)Data;
  756. return LogFormat(LogInfo,
  757. "%s={%lx,%lx,%lx,%lx} ",
  758. FieldName,
  759. Rect->left, Rect->top, Rect->right, Rect->bottom);
  760. }
  761. return LogTypeValue(LogInfo,
  762. Data,
  763. FieldName,
  764. ServiceReturn);
  765. }
  766. NTSTATUS
  767. LogTypePLargeIntegerIn(
  768. IN OUT PLOGINFO LogInfo,
  769. IN ULONG_PTR Data,
  770. IN PSZ FieldName,
  771. IN BOOLEAN ServiceReturn)
  772. /*++
  773. Routine Description:
  774. Log Data as PLARGE_INTEGER
  775. Arguments:
  776. LogInfo - Output log buffer
  777. Data - Value to log
  778. FieldName - Descriptive name of value to log
  779. ServiceReturn - TRUE if called after the thunk API has executed
  780. Return Value:
  781. NTSTATUS
  782. --*/
  783. {
  784. if (ServiceReturn)
  785. {
  786. return STATUS_SUCCESS;
  787. }
  788. if (Data)
  789. {
  790. NT32ULARGE_INTEGER *ULargeInt = (NT32ULARGE_INTEGER *)Data;
  791. return LogFormat(LogInfo,
  792. "%s={H=%lx,L=%lx} ",
  793. FieldName,
  794. ULargeInt->HighPart, ULargeInt->LowPart);
  795. }
  796. return LogTypeValue(LogInfo,
  797. Data,
  798. FieldName,
  799. ServiceReturn);
  800. }