xref: /reactos/base/system/diskpart/dump.c (revision f59c58d8)
1 /*
2  * PROJECT:         ReactOS DiskPart
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * FILE:            base/system/diskpart/dump.c
5  * PURPOSE:         Manages all the partitions of the OS in an interactive way.
6  * PROGRAMMERS:     Eric Kohl
7  */
8 
9 #include "diskpart.h"
10 
11 #define NDEBUG
12 #include <debug.h>
13 
14 /* FUNCTIONS ******************************************************************/
15 
16 static
17 VOID
18 HexDump(
19     _In_ UCHAR *addr,
20     _In_ int len)
21 {
22     WCHAR Buffer[17];
23     UCHAR *pc;
24     int i;
25 
26     Buffer[16] = L'\0';
27 
28     pc = addr;
29     for (i = 0; i < len; i++)
30     {
31         if ((i % 16) == 0)
32             ConPrintf(StdOut, L" %04x ", i);
33 
34         ConPrintf(StdOut, L" %02x", pc[i]);
35 
36         if ((pc[i] < 0x20) || (pc[i] > 0x7e))
37             Buffer[i % 16] = L'.';
38         else
39             Buffer[i % 16] = (WCHAR)(USHORT)pc[i];
40 
41         if ((i % 16) == (16 - 1))
42             ConPrintf(StdOut, L"  %s\n", Buffer);
43     }
44 }
45 
46 
47 static
48 VOID
49 DumpDisk(
50     _In_ INT argc,
51     _In_ LPWSTR *argv)
52 {
53     OBJECT_ATTRIBUTES ObjectAttributes;
54     IO_STATUS_BLOCK Iosb;
55     NTSTATUS Status;
56     WCHAR Buffer[MAX_PATH];
57     UNICODE_STRING Name;
58     HANDLE FileHandle = NULL;
59     PUCHAR pSectorBuffer = NULL;
60     LARGE_INTEGER FileOffset;
61     LONGLONG Sector;
62     LPWSTR endptr = NULL;
63 
64 #if 0
65     if (argc == 2)
66     {
67         ConResPuts(StdOut, IDS_HELP_CMD_DUMP_DISK);
68         return TRUE;
69     }
70 #endif
71 
72     if (CurrentDisk == NULL)
73     {
74         ConResPuts(StdOut, IDS_SELECT_NO_DISK);
75         return;
76     }
77 
78     Sector = _wcstoi64(argv[2], &endptr, 0);
79     if (((Sector == 0) && (endptr == argv[2])) ||
80         (Sector < 0))
81     {
82         ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
83         return;
84     }
85 
86     pSectorBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CurrentDisk->BytesPerSector);
87     if (pSectorBuffer == NULL)
88     {
89         DPRINT1("\n");
90         /* Error message */
91         goto done;
92     }
93 
94     swprintf(Buffer,
95              L"\\Device\\Harddisk%d\\Partition0",
96              CurrentDisk->DiskNumber);
97     RtlInitUnicodeString(&Name,
98                         Buffer);
99 
100     InitializeObjectAttributes(&ObjectAttributes,
101                                &Name,
102                                0,
103                                NULL,
104                                NULL);
105 
106     Status = NtOpenFile(&FileHandle,
107                         FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
108                         &ObjectAttributes,
109                         &Iosb,
110                         FILE_SHARE_READ,
111                         FILE_SYNCHRONOUS_IO_NONALERT);
112     if (!NT_SUCCESS(Status))
113     {
114         DPRINT1("\n");
115         goto done;
116     }
117 
118     FileOffset.QuadPart = Sector * CurrentDisk->BytesPerSector;
119     Status = NtReadFile(FileHandle,
120                         NULL,
121                         NULL,
122                         NULL,
123                         &Iosb,
124                         (PVOID)pSectorBuffer,
125                         CurrentDisk->BytesPerSector,
126                         &FileOffset,
127                         NULL);
128     if (!NT_SUCCESS(Status))
129     {
130         DPRINT1("NtReadFile failed, status=%x\n", Status);
131         goto done;
132     }
133 
134     HexDump(pSectorBuffer, CurrentDisk->BytesPerSector);
135 
136 done:
137     if (FileHandle)
138         NtClose(FileHandle);
139 
140     RtlFreeHeap(RtlGetProcessHeap(), 0, pSectorBuffer);
141 
142     return;
143 }
144 
145 
146 static
147 VOID
148 DumpPartition(
149     _In_ INT argc,
150     _In_ LPWSTR *argv)
151 {
152     OBJECT_ATTRIBUTES ObjectAttributes;
153     IO_STATUS_BLOCK Iosb;
154     NTSTATUS Status;
155     WCHAR Buffer[MAX_PATH];
156     UNICODE_STRING Name;
157     HANDLE FileHandle = NULL;
158     PUCHAR pSectorBuffer = NULL;
159     LARGE_INTEGER FileOffset;
160     LONGLONG Sector;
161     LPWSTR endptr = NULL;
162 
163 
164 #if 0
165     if (argc == 2)
166     {
167         ConResPuts(StdOut, IDS_HELP_CMD_DUMP_DISK);
168         return TRUE;
169     }
170 #endif
171 
172     if (CurrentDisk == NULL)
173     {
174         ConResPuts(StdOut, IDS_SELECT_NO_DISK);
175         return;
176     }
177 
178     if (CurrentPartition == NULL)
179     {
180         ConResPuts(StdOut, IDS_SELECT_NO_PARTITION);
181         return;
182     }
183 
184     Sector = _wcstoi64(argv[2], &endptr, 0);
185     if (((Sector == 0) && (endptr == argv[2])) ||
186         (Sector < 0))
187     {
188         ConResPuts(StdErr, IDS_ERROR_INVALID_ARGS);
189         return;
190     }
191 
192     pSectorBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CurrentDisk->BytesPerSector);
193     if (pSectorBuffer == NULL)
194     {
195         DPRINT1("\n");
196         /* Error message */
197         goto done;
198     }
199 
200     swprintf(Buffer,
201              L"\\Device\\Harddisk%d\\Partition%d",
202              CurrentDisk->DiskNumber,
203              CurrentPartition->PartitionNumber);
204     RtlInitUnicodeString(&Name,
205                         Buffer);
206 
207     InitializeObjectAttributes(&ObjectAttributes,
208                                &Name,
209                                0,
210                                NULL,
211                                NULL);
212 
213     Status = NtOpenFile(&FileHandle,
214                         FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
215                         &ObjectAttributes,
216                         &Iosb,
217                         FILE_SHARE_READ,
218                         FILE_SYNCHRONOUS_IO_NONALERT);
219     if (!NT_SUCCESS(Status))
220     {
221         DPRINT1("\n");
222         goto done;
223     }
224 
225     FileOffset.QuadPart = Sector * CurrentDisk->BytesPerSector;
226     Status = NtReadFile(FileHandle,
227                         NULL,
228                         NULL,
229                         NULL,
230                         &Iosb,
231                         (PVOID)pSectorBuffer,
232                         CurrentDisk->BytesPerSector,
233                         &FileOffset,
234                         NULL);
235     if (!NT_SUCCESS(Status))
236     {
237         DPRINT1("NtReadFile failed, status=%x\n", Status);
238         goto done;
239     }
240 
241     HexDump(pSectorBuffer, CurrentDisk->BytesPerSector);
242 
243 done:
244     if (FileHandle)
245         NtClose(FileHandle);
246 
247     RtlFreeHeap(RtlGetProcessHeap(), 0, pSectorBuffer);
248 
249     return;
250 }
251 
252 
253 BOOL
254 dump_main(
255     _In_ INT argc,
256     _In_ LPWSTR *argv)
257 {
258     /* gets the first word from the string */
259 #if 0
260     if (argc == 1)
261     {
262         ConResPuts(StdOut, IDS_HELP_CMD_LIST);
263         return TRUE;
264     }
265 #endif
266 
267     /* determines which to list (disk, partition, etc.) */
268     if (!wcsicmp(argv[1], L"disk"))
269         DumpDisk(argc, argv);
270     else if (!wcsicmp(argv[1], L"partition"))
271         DumpPartition(argc, argv);
272 #if 0
273     else
274         ConResPuts(StdOut, IDS_HELP_CMD_LIST);
275 #endif
276 
277     return TRUE;
278 }
279