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.

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