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.

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