1 /*
2  * PROJECT:     ReactOS API Tests
3  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:     Utility functions
5  * COPYRIGHT:   Copyright 2025 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
6  */
7 
8 #include "precomp.h"
9 
10 LPCSTR wine_dbgstr_us(const UNICODE_STRING *us)
11 {
12     if (!us) return "(null)";
13     return wine_dbgstr_wn(us->Buffer, us->Length / sizeof(WCHAR));
14 }
15 
16 /**
17  * @brief
18  * Retrieves a handle to the MountMgr controlling device.
19  * The handle should be closed with NtClose() once it is no longer in use.
20  **/
21 HANDLE
22 GetMountMgrHandle(VOID)
23 {
24     NTSTATUS Status;
25     UNICODE_STRING MountMgrDevice;
26     OBJECT_ATTRIBUTES ObjectAttributes;
27     IO_STATUS_BLOCK IoStatusBlock;
28     HANDLE MountMgrHandle = NULL;
29 
30     RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
31     InitializeObjectAttributes(&ObjectAttributes,
32                                &MountMgrDevice,
33                                OBJ_CASE_INSENSITIVE,
34                                NULL,
35                                NULL);
36     Status = NtOpenFile(&MountMgrHandle,
37                         FILE_READ_ATTRIBUTES | SYNCHRONIZE,
38                         &ObjectAttributes,
39                         &IoStatusBlock,
40                         FILE_SHARE_READ | FILE_SHARE_WRITE,
41                         FILE_SYNCHRONOUS_IO_NONALERT);
42     if (!NT_SUCCESS(Status))
43     {
44         winetest_print("NtOpenFile(%s) failed, Status 0x%08lx\n",
45                        wine_dbgstr_us(&MountMgrDevice), Status);
46     }
47 
48     return MountMgrHandle;
49 }
50 
51 VOID
52 DumpBuffer(
53     _In_ PVOID Buffer,
54     _In_ ULONG Length)
55 {
56 #define LINE_SIZE   (75 + 2)
57     ULONG i;
58     PBYTE Ptr1, Ptr2;
59     CHAR  LineBuffer[LINE_SIZE];
60     PCHAR Line;
61     ULONG LineSize;
62 
63     Ptr1 = Ptr2 = Buffer;
64     while ((ULONG_PTR)Buffer + Length - (ULONG_PTR)Ptr1 > 0)
65     {
66         Ptr1 = Ptr2;
67         Line = LineBuffer;
68 
69         /* Print the address */
70         Line += _snprintf(Line, LINE_SIZE + LineBuffer - Line, "%08Ix ", (ULONG_PTR)Ptr1);
71 
72         /* Print up to 16 bytes... */
73 
74         /* ... in hexadecimal form first... */
75         i = 0;
76         while (i++ <= 0x0F && ((ULONG_PTR)Buffer + Length - (ULONG_PTR)Ptr1 > 0))
77         {
78             Line += _snprintf(Line, LINE_SIZE + LineBuffer - Line, " %02x", *Ptr1);
79             ++Ptr1;
80         }
81 
82         /* ... align with spaces if needed... */
83         RtlFillMemory(Line, (0x0F + 2 - i) * 3 + 2, ' ');
84         Line += (0x0F + 2 - i) * 3 + 2;
85 
86         /* ... then in character form. */
87         i = 0;
88         while (i++ <= 0x0F && ((ULONG_PTR)Buffer + Length - (ULONG_PTR)Ptr2 > 0))
89         {
90             *Line++ = ((*Ptr2 >= 0x20 && *Ptr2 <= 0x7E) || (*Ptr2 >= 0x80 && *Ptr2 < 0xFF) ? *Ptr2 : '.');
91             ++Ptr2;
92         }
93 
94         /* Newline */
95         *Line++ = '\r';
96         *Line++ = '\n';
97 
98         /* Finally display the line */
99         LineSize = Line - LineBuffer;
100         printf("%.*s", (int)LineSize, LineBuffer);
101     }
102 }
103