Reactos
1/*
2 * PROJECT: ReactOS DiskPart
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/diskpart/misc.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/* FUNCTIONS ******************************************************************/
12
13BOOL
14IsDecString(
15 _In_ PWSTR pszDecString)
16{
17 PWSTR ptr;
18
19 if ((pszDecString == NULL) || (*pszDecString == UNICODE_NULL))
20 return FALSE;
21
22 ptr = pszDecString;
23 while (*ptr != UNICODE_NULL)
24 {
25 if (!iswdigit(*ptr))
26 return FALSE;
27
28 ptr++;
29 }
30
31 return TRUE;
32}
33
34
35BOOL
36IsHexString(
37 _In_ PWSTR pszHexString)
38{
39 PWSTR ptr;
40
41 if ((pszHexString == NULL) || (*pszHexString == UNICODE_NULL))
42 return FALSE;
43
44 ptr = pszHexString;
45 while (*ptr != UNICODE_NULL)
46 {
47 if (!iswxdigit(*ptr))
48 return FALSE;
49
50 ptr++;
51 }
52
53 return TRUE;
54}
55
56
57BOOL
58HasPrefix(
59 _In_ PWSTR pszString,
60 _In_ PWSTR pszPrefix,
61 _Out_opt_ PWSTR *ppszSuffix)
62{
63 INT nPrefixLength, ret;
64
65 nPrefixLength = wcslen(pszPrefix);
66 ret = _wcsnicmp(pszString, pszPrefix, nPrefixLength);
67 if ((ret == 0) && (ppszSuffix != NULL))
68 *ppszSuffix = &pszString[nPrefixLength];
69
70 return (ret == 0);
71}
72
73
74ULONGLONG
75RoundingDivide(
76 _In_ ULONGLONG Dividend,
77 _In_ ULONGLONG Divisor)
78{
79 return (Dividend + Divisor / 2) / Divisor;
80}
81
82
83PWSTR
84DuplicateQuotedString(
85 _In_ PWSTR pszInString)
86{
87 PWSTR pszOutString = NULL;
88 PWSTR pStart, pEnd;
89 INT nLength;
90
91 if ((pszInString == NULL) || (pszInString[0] == UNICODE_NULL))
92 return NULL;
93
94 if (pszInString[0] == L'"')
95 {
96 if (pszInString[1] == UNICODE_NULL)
97 return NULL;
98
99 pStart = &pszInString[1];
100 pEnd = wcschr(pStart, '"');
101 if (pEnd == NULL)
102 {
103 nLength = wcslen(pStart);
104 }
105 else
106 {
107 nLength = (pEnd - pStart);
108 }
109 }
110 else
111 {
112 pStart = pszInString;
113 nLength = wcslen(pStart);
114 }
115
116 pszOutString = RtlAllocateHeap(RtlGetProcessHeap(),
117 HEAP_ZERO_MEMORY,
118 (nLength + 1) * sizeof(WCHAR));
119 if (pszOutString == NULL)
120 return NULL;
121
122 wcsncpy(pszOutString, pStart, nLength);
123
124 return pszOutString;
125}
126
127
128PWSTR
129DuplicateString(
130 _In_ PWSTR pszInString)
131{
132 PWSTR pszOutString = NULL;
133 INT nLength;
134
135 if ((pszInString == NULL) || (pszInString[0] == UNICODE_NULL))
136 return NULL;
137
138 nLength = wcslen(pszInString);
139 pszOutString = RtlAllocateHeap(RtlGetProcessHeap(),
140 HEAP_ZERO_MEMORY,
141 (nLength + 1) * sizeof(WCHAR));
142 if (pszOutString == NULL)
143 return NULL;
144
145 wcscpy(pszOutString, pszInString);
146
147 return pszOutString;
148}
149
150
151VOID
152CreateGUID(
153 _Out_ GUID *pGuid)
154{
155 RtlGenRandom(pGuid, sizeof(*pGuid));
156 /* Clear the version bits and set the version (4) */
157 pGuid->Data3 &= 0x0fff;
158 pGuid->Data3 |= (4 << 12);
159 /* Set the topmost bits of Data4 (clock_seq_hi_and_reserved) as
160 * specified in RFC 4122, section 4.4.
161 */
162 pGuid->Data4[0] &= 0x3f;
163 pGuid->Data4[0] |= 0x80;
164}
165
166
167VOID
168CreateSignature(
169 _Out_ PDWORD pSignature)
170{
171 LARGE_INTEGER SystemTime;
172 TIME_FIELDS TimeFields;
173 PUCHAR Buffer;
174
175 NtQuerySystemTime(&SystemTime);
176 RtlTimeToTimeFields(&SystemTime, &TimeFields);
177
178 Buffer = (PUCHAR)pSignature;
179 Buffer[0] = (UCHAR)(TimeFields.Year & 0xFF) + (UCHAR)(TimeFields.Hour & 0xFF);
180 Buffer[1] = (UCHAR)(TimeFields.Year >> 8) + (UCHAR)(TimeFields.Minute & 0xFF);
181 Buffer[2] = (UCHAR)(TimeFields.Month & 0xFF) + (UCHAR)(TimeFields.Second & 0xFF);
182 Buffer[3] = (UCHAR)(TimeFields.Day & 0xFF) + (UCHAR)(TimeFields.Milliseconds & 0xFF);
183}
184
185
186VOID
187PrintGUID(
188 _Out_ PWSTR pszBuffer,
189 _In_ GUID *pGuid)
190{
191 swprintf(pszBuffer,
192 L"%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
193 pGuid->Data1,
194 pGuid->Data2,
195 pGuid->Data3,
196 pGuid->Data4[0],
197 pGuid->Data4[1],
198 pGuid->Data4[2],
199 pGuid->Data4[3],
200 pGuid->Data4[4],
201 pGuid->Data4[5],
202 pGuid->Data4[6],
203 pGuid->Data4[7]);
204}
205
206static
207BYTE
208CharToByte(
209 WCHAR Char)
210{
211 if (iswdigit(Char))
212 {
213 return (BYTE)((INT)Char - (INT)'0');
214 }
215 else if (iswalpha(Char))
216 {
217 if (iswupper(Char))
218 return (INT)Char - ((INT)'A' - 10);
219 else
220 return (INT)Char - ((INT)'a' - 10);
221 }
222 return 0;
223}
224
225
226BOOL
227StringToGUID(
228 _Out_ GUID *pGuid,
229 _In_ PWSTR pszString)
230{
231 INT i;
232
233 if (pszString == NULL)
234 return FALSE;
235
236 pGuid->Data1 = 0;
237 for (i = 0; i < 8; i++)
238 {
239 if (!iswxdigit(pszString[i]))
240 return FALSE;
241
242 pGuid->Data1 = (pGuid->Data1 << 4) | CharToByte(pszString[i]);
243 }
244
245 if (pszString[8] != L'-')
246 return FALSE;
247
248 pGuid->Data2 = 0;
249 for (i = 9; i < 13; i++)
250 {
251 if (!iswxdigit(pszString[i]))
252 return FALSE;
253
254 pGuid->Data2 = (pGuid->Data2 << 4) | CharToByte(pszString[i]);
255 }
256
257 if (pszString[13] != L'-')
258 return FALSE;
259
260 pGuid->Data3 = 0;
261 for (i = 14; i < 18; i++)
262 {
263 if (!iswxdigit(pszString[i]))
264 return FALSE;
265
266 pGuid->Data3 = (pGuid->Data3 << 4) | CharToByte(pszString[i]);
267 }
268
269 if (pszString[18] != L'-')
270 return FALSE;
271
272 for (i = 19; i < 36; i += 2)
273 {
274 if (i == 23)
275 {
276 if (pszString[i] != L'-')
277 return FALSE;
278 i++;
279 }
280
281 if (!iswxdigit(pszString[i]) || !iswxdigit(pszString[i + 1]))
282 return FALSE;
283
284 pGuid->Data4[(i - 19) / 2] = CharToByte(pszString[i]) << 4 | CharToByte(pszString[i + 1]);
285 }
286
287 if (pszString[36] == L'\0')
288 return TRUE;
289
290 return FALSE;
291}
292
293
294VOID
295PrintBusType(
296 _Out_ PWSTR pszBuffer,
297 _In_ INT cchBufferMax,
298 _In_ STORAGE_BUS_TYPE BusType)
299{
300 if (BusType <= BusTypeMax)
301 LoadStringW(GetModuleHandle(NULL),
302 IDS_BUSTYPE_UNKNOWN + BusType,
303 pszBuffer,
304 cchBufferMax);
305 else
306 LoadStringW(GetModuleHandle(NULL),
307 IDS_BUSTYPE_OTHER,
308 pszBuffer,
309 cchBufferMax);
310}