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.

804 lines
20 KiB

  1. /*++
  2. Copyright (c) 1989-2000 Microsoft Corporation
  3. Module Name:
  4. ntKMode.c
  5. Abstract:
  6. This module implements low level primitives for kernel mode implementation.
  7. Author:
  8. VadimB created sometime in 2000
  9. Revision History:
  10. --*/
  11. #include "sdbp.h"
  12. #ifdef KERNEL_MODE
  13. extern TAG g_rgDirectoryTags[];
  14. #ifdef ALLOC_PRAGMA
  15. #pragma alloc_text(PAGE, SdbTagIDToTagRef)
  16. #pragma alloc_text(PAGE, SdbTagRefToTagID)
  17. #pragma alloc_text(PAGE, SdbInitDatabaseInMemory)
  18. #pragma alloc_text(PAGE, SdbpOpenAndMapFile)
  19. #pragma alloc_text(PAGE, SdbpUnmapAndCloseFile)
  20. #pragma alloc_text(PAGE, SdbpUpcaseUnicodeStringToMultiByteN)
  21. #pragma alloc_text(PAGE, SdbpQueryFileDirectoryAttributesNT)
  22. #pragma alloc_text(PAGE, SdbpDoesFileExists_U)
  23. #pragma alloc_text(PAGE, SdbGetFileInfo)
  24. #pragma alloc_text(PAGE, DuplicateUnicodeString)
  25. #pragma alloc_text(PAGE, SdbpCreateUnicodeString)
  26. #pragma alloc_text(PAGE, SdbpGetFileDirectoryAttributesNT)
  27. #endif
  28. BOOL
  29. SdbTagIDToTagRef(
  30. IN HSDB hSDB,
  31. IN PDB pdb, // PDB the TAGID is from
  32. IN TAGID tiWhich, // TAGID to convert
  33. OUT TAGREF* ptrWhich // converted TAGREF
  34. )
  35. /*++
  36. Return: TRUE if a TAGREF was found, FALSE otherwise.
  37. Desc: Converts a PDB and TAGID into a TAGREF, by packing the high bits of the
  38. TAGREF with a constant that tells us which PDB, and the low bits with
  39. the TAGID.
  40. --*/
  41. {
  42. PSDBCONTEXT pSdbContext = (PSDBCONTEXT)hSDB;
  43. BOOL bReturn = FALSE;
  44. //
  45. // In kernel mode we only support sysmain db
  46. //
  47. *ptrWhich = tiWhich | PDB_MAIN;
  48. bReturn = TRUE;
  49. if (!bReturn) {
  50. DBGPRINT((sdlError, "SdbTagIDToTagRef", "Bad PDB.\n"));
  51. *ptrWhich = TAGREF_NULL;
  52. }
  53. return bReturn;
  54. }
  55. BOOL
  56. SdbTagRefToTagID(
  57. IN HSDB hSDB,
  58. IN TAGREF trWhich, // TAGREF to convert
  59. OUT PDB* ppdb, // PDB the TAGREF is from
  60. OUT TAGID* ptiWhich // TAGID within that PDB
  61. )
  62. /*++
  63. Return: TRUE if the TAGREF is valid and was converted, FALSE otherwise.
  64. Desc: Converts a TAGREF type to a TAGID and a PDB. This manages the interface
  65. between NTDLL, which knows nothing of PDBs, and the shimdb, which manages
  66. three separate PDBs. The TAGREF incorporates the TAGID and a constant
  67. that tells us which PDB the TAGID is from. In this way, the NTDLL client
  68. doesn't need to know which DB the info is coming from.
  69. --*/
  70. {
  71. PSDBCONTEXT pSdbContext = (PSDBCONTEXT)hSDB;
  72. BOOL bReturn = TRUE;
  73. TAGID tiWhich = TAGID_NULL;
  74. PDB pdb = NULL;
  75. DWORD dwMask;
  76. dwMask = trWhich & TAGREF_STRIP_PDB;
  77. if (dwMask != PDB_MAIN) {
  78. goto cleanup;
  79. }
  80. tiWhich = trWhich & TAGREF_STRIP_TAGID;
  81. pdb = pSdbContext->pdbMain;
  82. //
  83. // See that we double-check here
  84. //
  85. if (pdb == NULL && tiWhich != TAGID_NULL) {
  86. DBGPRINT((sdlError, "SdbTagRefToTagID", "PDB dereferenced by this TAGREF is NULL\n"));
  87. bReturn = FALSE;
  88. }
  89. cleanup:
  90. if (ppdb != NULL) {
  91. *ppdb = pdb;
  92. }
  93. if (ptiWhich != NULL) {
  94. *ptiWhich = tiWhich;
  95. }
  96. return bReturn;
  97. }
  98. HSDB
  99. SdbInitDatabaseInMemory(
  100. IN LPVOID pDatabaseImage,
  101. IN DWORD dwImageSize
  102. )
  103. /*++
  104. Return: BUGBUG: ?
  105. Desc: BUGBUG: ?
  106. --*/
  107. {
  108. PSDBCONTEXT pContext;
  109. //
  110. // Initialize the context.
  111. //
  112. pContext = (PSDBCONTEXT)SdbAlloc(sizeof(SDBCONTEXT));
  113. if (pContext == NULL) {
  114. DBGPRINT((sdlError,
  115. "SdbInitDatabaseInMemory",
  116. "Failed to allocate %d bytes for HSDB\n",
  117. sizeof(SDBCONTEXT)));
  118. return NULL;
  119. }
  120. //
  121. // Now open the database.
  122. //
  123. pContext->pdbMain = SdbpOpenDatabaseInMemory(pDatabaseImage, dwImageSize);
  124. if (pContext->pdbMain == NULL) {
  125. DBGPRINT((sdlError,
  126. "SdbInitDatabaseInMemory",
  127. "Unable to open main database at 0x%x size 0x%x\n",
  128. pDatabaseImage,
  129. dwImageSize));
  130. goto ErrHandle;
  131. }
  132. return (HSDB)pContext;
  133. ErrHandle:
  134. if (pContext != NULL) {
  135. if (pContext->pdbMain != NULL) {
  136. SdbCloseDatabaseRead(pContext->pdbMain);
  137. }
  138. SdbFree(pContext);
  139. }
  140. return NULL;
  141. }
  142. //
  143. // Open and map File
  144. //
  145. BOOL
  146. SdbpOpenAndMapFile(
  147. IN LPCWSTR szPath, // pointer to the fully-qualified filename
  148. OUT PIMAGEFILEDATA pImageData, // pointer to IMAGEFILEDATA that receives
  149. // image-related information
  150. IN PATH_TYPE ePathType // ignored
  151. )
  152. /*++
  153. Return: TRUE on success, FALSE otherwise.
  154. Desc: Opens a file and maps it into memory.
  155. --*/
  156. {
  157. NTSTATUS Status;
  158. OBJECT_ATTRIBUTES ObjectAttributes;
  159. UNICODE_STRING ustrFileName;
  160. HANDLE hSection = NULL;
  161. HANDLE hFile = INVALID_HANDLE_VALUE;
  162. IO_STATUS_BLOCK IoStatusBlock;
  163. SIZE_T ViewSize = 0;
  164. PVOID pBase = NULL;
  165. DWORD dwFlags = 0;
  166. FILE_STANDARD_INFORMATION StandardInfo;
  167. if (pImageData->dwFlags & IMAGEFILEDATA_PBASEVALID) {
  168. //
  169. // special case, only headers are valid in our assumption
  170. //
  171. return TRUE;
  172. }
  173. //
  174. // Initialize return data
  175. //
  176. if (pImageData->dwFlags & IMAGEFILEDATA_HANDLEVALID) {
  177. hFile = pImageData->hFile;
  178. if (hFile != INVALID_HANDLE_VALUE) {
  179. dwFlags |= IMAGEFILEDATA_NOFILECLOSE;
  180. }
  181. }
  182. RtlZeroMemory(pImageData, sizeof(*pImageData));
  183. pImageData->hFile = INVALID_HANDLE_VALUE;
  184. if (hFile == INVALID_HANDLE_VALUE) {
  185. //
  186. // Open the file
  187. //
  188. RtlInitUnicodeString(&ustrFileName, szPath);
  189. InitializeObjectAttributes(&ObjectAttributes,
  190. &ustrFileName,
  191. OBJ_CASE_INSENSITIVE,
  192. NULL,
  193. NULL);
  194. Status = ZwCreateFile(&hFile,
  195. GENERIC_READ,
  196. &ObjectAttributes,
  197. &IoStatusBlock,
  198. NULL,
  199. FILE_ATTRIBUTE_NORMAL,
  200. FILE_SHARE_READ,
  201. FILE_OPEN,
  202. FILE_SYNCHRONOUS_IO_NONALERT|FILE_NON_DIRECTORY_FILE,
  203. NULL,
  204. 0);
  205. if (!NT_SUCCESS(Status)) {
  206. DBGPRINT((sdlError,
  207. "SdbpOpenAndMapFile",
  208. "ZwCreateFile failed status 0x%x\n",
  209. Status));
  210. return FALSE;
  211. }
  212. }
  213. //
  214. // Query file size
  215. //
  216. Status = ZwQueryInformationFile(hFile,
  217. &IoStatusBlock,
  218. &StandardInfo,
  219. sizeof(StandardInfo),
  220. FileStandardInformation);
  221. if (!NT_SUCCESS(Status)) {
  222. DBGPRINT((sdlError,
  223. "SdbpOpenAndMapFile",
  224. "ZwQueryInformationFile (EOF) failed Status 0x%x\n",
  225. Status));
  226. if (!(dwFlags & IMAGEFILEDATA_NOFILECLOSE)) {
  227. ZwClose(hFile);
  228. }
  229. return FALSE;
  230. }
  231. InitializeObjectAttributes(&ObjectAttributes,
  232. NULL,
  233. OBJ_CASE_INSENSITIVE,
  234. NULL,
  235. NULL);
  236. Status = ZwCreateSection(&hSection,
  237. STANDARD_RIGHTS_REQUIRED |
  238. SECTION_QUERY |
  239. SECTION_MAP_READ,
  240. &ObjectAttributes,
  241. NULL,
  242. PAGE_READONLY,
  243. SEC_COMMIT,
  244. hFile);
  245. if (!NT_SUCCESS(Status)) {
  246. DBGPRINT((sdlError,
  247. "SdbpOpenAndMapFile",
  248. "ZwOpenSectionFailed status 0x%x\n",
  249. Status));
  250. if (!(dwFlags & IMAGEFILEDATA_NOFILECLOSE)) {
  251. ZwClose(hFile);
  252. }
  253. return FALSE;
  254. }
  255. Status = ZwMapViewOfSection(hSection,
  256. NtCurrentProcess(),
  257. &pBase,
  258. 0L,
  259. 0L,
  260. NULL,
  261. &ViewSize,
  262. ViewUnmap,
  263. 0L,
  264. PAGE_READONLY);
  265. if (!NT_SUCCESS(Status)) {
  266. DBGPRINT((sdlError,
  267. "SdbpMapFile",
  268. "NtMapViewOfSection failed Status 0x%x\n",
  269. Status));
  270. ZwClose(hSection);
  271. if (!(dwFlags & IMAGEFILEDATA_NOFILECLOSE)) {
  272. ZwClose(hFile);
  273. }
  274. return FALSE;
  275. }
  276. pImageData->hFile = hFile;
  277. pImageData->dwFlags = dwFlags;
  278. pImageData->hSection = hSection;
  279. pImageData->pBase = pBase;
  280. pImageData->ViewSize = ViewSize;
  281. pImageData->FileSize = StandardInfo.EndOfFile.QuadPart;
  282. return TRUE;
  283. }
  284. BOOL
  285. SdbpUnmapAndCloseFile(
  286. IN PIMAGEFILEDATA pImageData // pointer to IMAGEFILEDATE - image-related information
  287. )
  288. /*++
  289. Return: TRUE on success, FALSE otherwise.
  290. Desc: Closes and unmaps an opened file.
  291. --*/
  292. {
  293. BOOL bSuccess = TRUE;
  294. NTSTATUS Status;
  295. if (pImageData->dwFlags & IMAGEFILEDATA_PBASEVALID) { // externally supplied pointer
  296. RtlZeroMemory(pImageData, sizeof(*pImageData));
  297. return TRUE;
  298. }
  299. if (pImageData->pBase != NULL) {
  300. Status = ZwUnmapViewOfSection(NtCurrentProcess(), pImageData->pBase);
  301. if (!NT_SUCCESS(Status)) {
  302. bSuccess = FALSE;
  303. DBGPRINT((sdlError,
  304. "SdbpCloseAndUnmapFile",
  305. "ZwUnmapViewOfSection failed Status 0x%x\n",
  306. Status));
  307. }
  308. pImageData->pBase = NULL;
  309. }
  310. if (pImageData->hSection != NULL) {
  311. Status = ZwClose(pImageData->hSection);
  312. if (!NT_SUCCESS(Status)) {
  313. bSuccess = FALSE;
  314. DBGPRINT((sdlError,
  315. "SdbpCloseAndUnmapFile",
  316. "ZwClose on section failed Status 0x%x\n",
  317. Status));
  318. }
  319. pImageData->hSection = NULL;
  320. }
  321. if (pImageData->dwFlags & IMAGEFILEDATA_NOFILECLOSE) {
  322. pImageData->hFile = INVALID_HANDLE_VALUE;
  323. } else {
  324. if (pImageData->hFile != INVALID_HANDLE_VALUE) {
  325. Status = ZwClose(pImageData->hFile);
  326. if (!NT_SUCCESS(Status)) {
  327. bSuccess = FALSE;
  328. DBGPRINT((sdlError,
  329. "SdbpCloseAndUnmapFile",
  330. "ZwClose on file failed Status 0x%x\n",
  331. Status));
  332. }
  333. pImageData->hFile = INVALID_HANDLE_VALUE;
  334. }
  335. }
  336. return bSuccess;
  337. }
  338. NTSTATUS
  339. SdbpUpcaseUnicodeStringToMultiByteN(
  340. OUT LPSTR lpszDest, // dest buffer
  341. IN DWORD dwSize, // size in characters, excluding unicode_null
  342. IN LPCWSTR lpszSrc // source
  343. )
  344. /*++
  345. Return: TRUE on success, FALSE otherwise.
  346. Desc: Convert up to dwSize characters from Unicode to ANSI.
  347. --*/
  348. {
  349. ANSI_STRING strDest;
  350. UNICODE_STRING ustrSource;
  351. NTSTATUS Status;
  352. UNICODE_STRING ustrUpcaseSource = { 0 };
  353. USHORT DestBufSize = (USHORT)dwSize * sizeof(WCHAR);
  354. RtlInitUnicodeString(&ustrSource, lpszSrc);
  355. STACK_ALLOC(ustrUpcaseSource.Buffer, ustrSource.MaximumLength);
  356. if (ustrUpcaseSource.Buffer == NULL) {
  357. DBGPRINT((sdlError,
  358. "SdbpUnicodeToMultiByteN",
  359. "Failed to allocate %d bytes on the stack\n",
  360. (DWORD)ustrSource.MaximumLength));
  361. return STATUS_NO_MEMORY;
  362. }
  363. ustrUpcaseSource.MaximumLength = ustrSource.MaximumLength;
  364. ustrUpcaseSource.Length = 0;
  365. Status = RtlUpcaseUnicodeString(&ustrUpcaseSource, &ustrSource, FALSE);
  366. if (!NT_SUCCESS(Status)) {
  367. DBGPRINT((sdlError,
  368. "SdbpUnicodeToMultiByteN",
  369. "RtlUpcaseUnicodeString failed Status 0x%x\n",
  370. Status));
  371. goto Done;
  372. }
  373. if (ustrUpcaseSource.Length > DestBufSize) {
  374. ustrUpcaseSource.Length = DestBufSize;
  375. }
  376. strDest.Buffer = lpszDest;
  377. strDest.MaximumLength = DestBufSize + sizeof(UNICODE_NULL);
  378. strDest.Length = 0;
  379. Status = RtlUnicodeStringToAnsiString(&strDest, &ustrUpcaseSource, FALSE);
  380. if (!NT_SUCCESS(Status)) {
  381. DBGPRINT((sdlError,
  382. "SdbpUnicodeToMultiByteN",
  383. "RtlUnicodeStringToAnsiString failed Status 0x%x\n",
  384. Status));
  385. }
  386. Done:
  387. if (ustrUpcaseSource.Buffer != NULL) {
  388. STACK_FREE(ustrUpcaseSource.Buffer);
  389. }
  390. return Status;
  391. }
  392. BOOL
  393. SdbpQueryFileDirectoryAttributesNT(
  394. PIMAGEFILEDATA pImageData,
  395. PFILEDIRECTORYATTRIBUTES pFileDirectoryAttributes
  396. )
  397. /*++
  398. Return: TRUE on success, FALSE otherwise.
  399. Desc: BUGBUG: ?
  400. --*/
  401. {
  402. LARGE_INTEGER liFileSize;
  403. liFileSize.QuadPart = pImageData->FileSize;
  404. pFileDirectoryAttributes->dwFlags |= FDA_FILESIZE;
  405. pFileDirectoryAttributes->dwFileSizeHigh = liFileSize.HighPart;
  406. pFileDirectoryAttributes->dwFileSizeLow = liFileSize.LowPart;
  407. return TRUE;
  408. }
  409. BOOL
  410. SdbpDoesFileExists_U(
  411. LPCWSTR pwszPath
  412. )
  413. /*++
  414. Return: TRUE on success, FALSE otherwise.
  415. Desc: BUGBUG: ?
  416. --*/
  417. {
  418. OBJECT_ATTRIBUTES ObjectAttributes;
  419. UNICODE_STRING ustrFileName;
  420. HANDLE hFile;
  421. NTSTATUS Status;
  422. IO_STATUS_BLOCK IoStatusBlock;
  423. RtlInitUnicodeString(&ustrFileName, pwszPath);
  424. InitializeObjectAttributes(&ObjectAttributes,
  425. &ustrFileName,
  426. OBJ_CASE_INSENSITIVE,
  427. NULL,
  428. NULL);
  429. Status = ZwCreateFile(&hFile,
  430. STANDARD_RIGHTS_REQUIRED |
  431. FILE_READ_ATTRIBUTES,
  432. &ObjectAttributes,
  433. &IoStatusBlock,
  434. NULL, // AllocationSize
  435. FILE_ATTRIBUTE_NORMAL, // FileAttributes
  436. FILE_SHARE_READ, // Share Access
  437. FILE_OPEN, // Create Disposition
  438. FILE_NON_DIRECTORY_FILE | // Create Options
  439. FILE_SYNCHRONOUS_IO_NONALERT,
  440. NULL, // EaBuffer
  441. 0); // EaLength
  442. if (!NT_SUCCESS(Status)) {
  443. DBGPRINT((sdlError,
  444. "SdbpDoesFileExists_U",
  445. "Failed to create file. Status 0x%x\n",
  446. Status));
  447. return FALSE;
  448. }
  449. ZwClose(hFile);
  450. return TRUE;
  451. }
  452. PVOID
  453. SdbGetFileInfo(
  454. IN HSDB hSDB,
  455. IN LPCWSTR pwszFilePath,
  456. IN HANDLE hFile, // handle for the file in question
  457. IN LPVOID pImageBase, // image base for this file
  458. IN DWORD dwImageSize,
  459. IN BOOL bNoCache
  460. )
  461. /*++
  462. Return: BUGBUG: ?
  463. Desc: Create and link a new entry in a file attribute cache.
  464. --*/
  465. {
  466. PSDBCONTEXT pContext = (PSDBCONTEXT)hSDB;
  467. LPCWSTR FullPath = pwszFilePath;
  468. NTSTATUS Status;
  469. PFILEINFO pFileInfo = NULL;
  470. UNICODE_STRING FullPathU;
  471. if (!bNoCache) {
  472. pFileInfo = FindFileInfo(pContext, FullPath);
  473. }
  474. if (pFileInfo == NULL) {
  475. if (hFile != INVALID_HANDLE_VALUE || pImageBase != NULL || SdbpDoesFileExists_U(FullPath)) {
  476. RtlInitUnicodeString(&FullPathU, FullPath);
  477. pFileInfo = CreateFileInfo(pContext,
  478. FullPathU.Buffer,
  479. FullPathU.Length / sizeof(WCHAR),
  480. hFile,
  481. pImageBase,
  482. dwImageSize,
  483. bNoCache);
  484. }
  485. }
  486. return (PVOID)pFileInfo;
  487. }
  488. WCHAR*
  489. DuplicateUnicodeString(
  490. PUNICODE_STRING pStr,
  491. PUSHORT pLength // pLength is an allocated length
  492. )
  493. /*++
  494. Return: BUGBUG: ?
  495. Desc: BUGBUG: ?
  496. --*/
  497. {
  498. WCHAR* pBuffer = NULL;
  499. USHORT Length = 0;
  500. if (pStr != NULL && pStr->Length > 0) {
  501. Length = pStr->Length + sizeof(UNICODE_NULL);
  502. pBuffer = (WCHAR*)SdbAlloc(Length);
  503. if (pBuffer == NULL) {
  504. DBGPRINT((sdlError,
  505. "DuplicateUnicodeString",
  506. "Failed to allocate %d bytes\n",
  507. Length));
  508. return NULL;
  509. }
  510. RtlMoveMemory(pBuffer, pStr->Buffer, pStr->Length);
  511. pBuffer[pStr->Length/sizeof(WCHAR)] = UNICODE_NULL;
  512. }
  513. if (pLength != NULL) {
  514. *pLength = Length;
  515. }
  516. return pBuffer;
  517. }
  518. BOOL
  519. SdbpCreateUnicodeString(
  520. PUNICODE_STRING pStr,
  521. LPCWSTR lpwsz
  522. )
  523. /*++
  524. Return: BUGBUG: ?
  525. Desc: BUGBUG: ?
  526. --*/
  527. {
  528. USHORT Length;
  529. UNICODE_STRING ustrSrc;
  530. RtlZeroMemory(pStr, sizeof(*pStr));
  531. RtlInitUnicodeString(&ustrSrc, lpwsz);
  532. pStr->Buffer = DuplicateUnicodeString(&ustrSrc, &Length);
  533. pStr->Length = ustrSrc.Length;
  534. pStr->MaximumLength = Length;
  535. return pStr->Buffer != NULL;
  536. }
  537. BOOL
  538. SdbpGetFileDirectoryAttributesNT(
  539. OUT PFILEINFO pFileInfo,
  540. IN PIMAGEFILEDATA pImageData
  541. )
  542. /*++
  543. Return: TRUE on success, FALSE otherwise.
  544. Desc: This function retrieves the header attributes for the
  545. specified file.
  546. --*/
  547. {
  548. BOOL bSuccess = FALSE;
  549. FILEDIRECTORYATTRIBUTES fda;
  550. int i;
  551. bSuccess = SdbpQueryFileDirectoryAttributesNT(pImageData, &fda);
  552. if (!bSuccess) {
  553. DBGPRINT((sdlInfo,
  554. "SdbpGetFileDirectoryAttributesNT",
  555. "No file directory attributes available.\n"));
  556. goto Done;
  557. }
  558. if (fda.dwFlags & FDA_FILESIZE) {
  559. assert(fda.dwFileSizeHigh == 0);
  560. SdbpSetAttribute(pFileInfo, TAG_SIZE, &fda.dwFileSizeLow);
  561. }
  562. Done:
  563. if (!bSuccess) {
  564. for (i = 0; g_rgDirectoryTags[i] != 0; ++i) {
  565. SdbpSetAttribute(pFileInfo, g_rgDirectoryTags[i], NULL);
  566. }
  567. }
  568. return bSuccess;
  569. }
  570. #ifdef _DEBUG_SPEW
  571. extern DBGLEVELINFO g_rgDbgLevelInfo[];
  572. extern PCH g_szDbgLevelUser;
  573. #endif // _DEBUG_SPEW
  574. int __cdecl
  575. ShimDbgPrint(
  576. int iLevel,
  577. PCH pszFunctionName,
  578. PCH Format,
  579. ...
  580. )
  581. {
  582. int nch = 0;
  583. #ifdef _DEBUG_SPEW
  584. PCH pszFormat = NULL;
  585. va_list arglist;
  586. ULONG Level = 0;
  587. int i;
  588. CHAR szPrefix[64];
  589. PCH pchBuffer = szPrefix;
  590. PCH pchLevel = NULL;
  591. PREPARE_FORMAT(pszFormat, Format);
  592. if (pszFormat == NULL) {
  593. //
  594. // Can't convert format for debug output
  595. //
  596. return 0;
  597. }
  598. //
  599. // Do we have a comment for this debug level? if so, print it
  600. //
  601. for (i = 0; i < DEBUG_LEVELS; ++i) {
  602. if (g_rgDbgLevelInfo[i].iLevel == iLevel) {
  603. pchLevel = (PCH)g_rgDbgLevelInfo[i].szStrTag;
  604. break;
  605. }
  606. }
  607. if (pchLevel == NULL) {
  608. pchLevel = g_szDbgLevelUser;
  609. }
  610. nch = sprintf(pchBuffer, "[%-4hs]", pchLevel);
  611. pchBuffer += nch;
  612. if (pszFunctionName) {
  613. //
  614. // Single-byte char going into UNICODE buffer
  615. //
  616. nch = sprintf(pchBuffer, "[%-30hs] ", pszFunctionName);
  617. pchBuffer += nch;
  618. }
  619. switch (iLevel) {
  620. case sdlError:
  621. Level = (1 << DPFLTR_ERROR_LEVEL) | DPFLTR_MASK;
  622. break;
  623. case sdlWarning:
  624. Level = (1 << DPFLTR_WARNING_LEVEL) | DPFLTR_MASK;
  625. break;
  626. case sdlInfo:
  627. Level = (1 << DPFLTR_TRACE_LEVEL) | DPFLTR_MASK;
  628. break;
  629. }
  630. va_start(arglist, Format);
  631. nch = (int)vDbgPrintExWithPrefix(szPrefix,
  632. DPFLTR_NTOSPNP_ID,
  633. Level,
  634. pszFormat,
  635. arglist);
  636. va_end(arglist);
  637. STACK_FREE(pszFormat);
  638. #endif // _DEBUG_SPEW
  639. return nch;
  640. }
  641. #endif // KERNEL_MODE