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(
23     _In_ ACCESS_MASK DesiredAccess)
24 {
25     NTSTATUS Status;
26     UNICODE_STRING MountMgrDevice;
27     OBJECT_ATTRIBUTES ObjectAttributes;
28     IO_STATUS_BLOCK IoStatusBlock;
29     HANDLE MountMgrHandle = NULL;
30 
31     RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
32     InitializeObjectAttributes(&ObjectAttributes,
33                                &MountMgrDevice,
34                                OBJ_CASE_INSENSITIVE,
35                                NULL,
36                                NULL);
37     Status = NtOpenFile(&MountMgrHandle,
38                         DesiredAccess | SYNCHRONIZE,
39                         &ObjectAttributes,
40                         &IoStatusBlock,
41                         FILE_SHARE_READ | FILE_SHARE_WRITE,
42                         FILE_SYNCHRONOUS_IO_NONALERT);
43     if (!NT_SUCCESS(Status))
44     {
45         winetest_print("NtOpenFile(%s) failed, Status 0x%08lx\n",
46                        wine_dbgstr_us(&MountMgrDevice), Status);
47     }
48 
49     return MountMgrHandle;
50 }
51 
52 VOID
53 DumpBuffer(
54     _In_ PVOID Buffer,
55     _In_ ULONG Length)
56 {
57 #define LINE_SIZE   (75 + 2)
58     ULONG i;
59     PBYTE Ptr1, Ptr2;
60     CHAR  LineBuffer[LINE_SIZE];
61     PCHAR Line;
62     ULONG LineSize;
63 
64     Ptr1 = Ptr2 = Buffer;
65     while ((ULONG_PTR)Buffer + Length - (ULONG_PTR)Ptr1 > 0)
66     {
67         Ptr1 = Ptr2;
68         Line = LineBuffer;
69 
70         /* Print the address */
71         Line += _snprintf(Line, LINE_SIZE + LineBuffer - Line, "%08Ix ", (ULONG_PTR)Ptr1);
72 
73         /* Print up to 16 bytes... */
74 
75         /* ... in hexadecimal form first... */
76         i = 0;
77         while (i++ <= 0x0F && ((ULONG_PTR)Buffer + Length - (ULONG_PTR)Ptr1 > 0))
78         {
79             Line += _snprintf(Line, LINE_SIZE + LineBuffer - Line, " %02x", *Ptr1);
80             ++Ptr1;
81         }
82 
83         /* ... align with spaces if needed... */
84         RtlFillMemory(Line, (0x0F + 2 - i) * 3 + 2, ' ');
85         Line += (0x0F + 2 - i) * 3 + 2;
86 
87         /* ... then in character form. */
88         i = 0;
89         while (i++ <= 0x0F && ((ULONG_PTR)Buffer + Length - (ULONG_PTR)Ptr2 > 0))
90         {
91             *Line++ = ((*Ptr2 >= 0x20 && *Ptr2 <= 0x7E) || (*Ptr2 >= 0x80 && *Ptr2 < 0xFF) ? *Ptr2 : '.');
92             ++Ptr2;
93         }
94 
95         /* Newline */
96         *Line++ = '\r';
97         *Line++ = '\n';
98 
99         /* Finally display the line */
100         LineSize = Line - LineBuffer;
101         printf("%.*s", (int)LineSize, LineBuffer);
102     }
103 }
104