1c2c66affSColin Finck /*
2c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3c2c66affSColin Finck * PROJECT: ReactOS VFAT filesystem library
4c2c66affSColin Finck * FILE: fat12.c
5c2c66affSColin Finck * PURPOSE: Fat12 support
6c2c66affSColin Finck * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7c2c66affSColin Finck * Eric Kohl
8c2c66affSColin Finck */
9c2c66affSColin Finck
10c2c66affSColin Finck /* INCLUDES *******************************************************************/
11c2c66affSColin Finck
12c2c66affSColin Finck #include "vfatlib.h"
13c2c66affSColin Finck
14c2c66affSColin Finck #define NDEBUG
15c2c66affSColin Finck #include <debug.h>
16c2c66affSColin Finck
17c2c66affSColin Finck
18c2c66affSColin Finck /* FUNCTIONS ******************************************************************/
19c2c66affSColin Finck
20c2c66affSColin Finck static NTSTATUS
Fat12WriteBootSector(IN HANDLE FileHandle,IN PFAT16_BOOT_SECTOR BootSector,IN OUT PFORMAT_CONTEXT Context)21c2c66affSColin Finck Fat12WriteBootSector(IN HANDLE FileHandle,
22c2c66affSColin Finck IN PFAT16_BOOT_SECTOR BootSector,
23c2c66affSColin Finck IN OUT PFORMAT_CONTEXT Context)
24c2c66affSColin Finck {
25c2c66affSColin Finck IO_STATUS_BLOCK IoStatusBlock;
26c2c66affSColin Finck NTSTATUS Status;
27c2c66affSColin Finck PFAT16_BOOT_SECTOR NewBootSector;
28c2c66affSColin Finck LARGE_INTEGER FileOffset;
29c2c66affSColin Finck
30c2c66affSColin Finck /* Allocate buffer for new bootsector */
31c2c66affSColin Finck NewBootSector = (PFAT16_BOOT_SECTOR)RtlAllocateHeap(RtlGetProcessHeap (),
32c2c66affSColin Finck 0,
33c2c66affSColin Finck BootSector->BytesPerSector);
34c2c66affSColin Finck if (NewBootSector == NULL)
35c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
36c2c66affSColin Finck
37c2c66affSColin Finck /* Zero the new bootsector */
38c2c66affSColin Finck RtlZeroMemory(NewBootSector, BootSector->BytesPerSector);
39c2c66affSColin Finck
40c2c66affSColin Finck /* Copy FAT16 BPB to new bootsector */
41*38791299SPierre Schweitzer memcpy(NewBootSector, BootSector,
426ff94017SPierre Schweitzer FIELD_OFFSET(FAT16_BOOT_SECTOR, Res2) - FIELD_OFFSET(FAT16_BOOT_SECTOR, Jump));
43c2c66affSColin Finck /* FAT16 BPB length (up to (not including) Res2) */
44c2c66affSColin Finck
45c2c66affSColin Finck /* Write the boot sector signature */
46c2c66affSColin Finck NewBootSector->Signature1 = 0xAA550000;
47c2c66affSColin Finck
48c2c66affSColin Finck /* Write sector 0 */
49c2c66affSColin Finck FileOffset.QuadPart = 0ULL;
50c2c66affSColin Finck Status = NtWriteFile(FileHandle,
51c2c66affSColin Finck NULL,
52c2c66affSColin Finck NULL,
53c2c66affSColin Finck NULL,
54c2c66affSColin Finck &IoStatusBlock,
55c2c66affSColin Finck NewBootSector,
56c2c66affSColin Finck BootSector->BytesPerSector,
57c2c66affSColin Finck &FileOffset,
58c2c66affSColin Finck NULL);
59c2c66affSColin Finck if (!NT_SUCCESS(Status))
60c2c66affSColin Finck {
61c2c66affSColin Finck DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
62c2c66affSColin Finck goto done;
63c2c66affSColin Finck }
64c2c66affSColin Finck
65c2c66affSColin Finck UpdateProgress(Context, 1);
66c2c66affSColin Finck
67c2c66affSColin Finck done:
68c2c66affSColin Finck /* Free the buffer */
69c2c66affSColin Finck RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
70c2c66affSColin Finck return Status;
71c2c66affSColin Finck }
72c2c66affSColin Finck
73c2c66affSColin Finck
74c2c66affSColin Finck static NTSTATUS
Fat12WriteFAT(IN HANDLE FileHandle,IN ULONG SectorOffset,IN PFAT16_BOOT_SECTOR BootSector,IN OUT PFORMAT_CONTEXT Context)75c2c66affSColin Finck Fat12WriteFAT(IN HANDLE FileHandle,
76c2c66affSColin Finck IN ULONG SectorOffset,
77c2c66affSColin Finck IN PFAT16_BOOT_SECTOR BootSector,
78c2c66affSColin Finck IN OUT PFORMAT_CONTEXT Context)
79c2c66affSColin Finck {
80c2c66affSColin Finck IO_STATUS_BLOCK IoStatusBlock;
81c2c66affSColin Finck NTSTATUS Status;
82c2c66affSColin Finck PUCHAR Buffer;
83c2c66affSColin Finck LARGE_INTEGER FileOffset;
84c2c66affSColin Finck ULONG i;
85c2c66affSColin Finck ULONG Size;
86c2c66affSColin Finck ULONG Sectors;
87c2c66affSColin Finck
88c2c66affSColin Finck /* Allocate buffer */
89c2c66affSColin Finck Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
90c2c66affSColin Finck 0,
91c2c66affSColin Finck 32 * 1024);
92c2c66affSColin Finck if (Buffer == NULL)
93c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
94c2c66affSColin Finck
95c2c66affSColin Finck /* Zero the buffer */
96c2c66affSColin Finck RtlZeroMemory(Buffer, 32 * 1024);
97c2c66affSColin Finck
98c2c66affSColin Finck /* FAT cluster 0 & 1*/
99c2c66affSColin Finck Buffer[0] = 0xf8; /* Media type */
100c2c66affSColin Finck Buffer[1] = 0xff;
101c2c66affSColin Finck Buffer[2] = 0xff;
102c2c66affSColin Finck
103c2c66affSColin Finck /* Write first sector of the FAT */
104c2c66affSColin Finck FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors) * BootSector->BytesPerSector;
105c2c66affSColin Finck Status = NtWriteFile(FileHandle,
106c2c66affSColin Finck NULL,
107c2c66affSColin Finck NULL,
108c2c66affSColin Finck NULL,
109c2c66affSColin Finck &IoStatusBlock,
110c2c66affSColin Finck Buffer,
111c2c66affSColin Finck BootSector->BytesPerSector,
112c2c66affSColin Finck &FileOffset,
113c2c66affSColin Finck NULL);
114c2c66affSColin Finck if (!NT_SUCCESS(Status))
115c2c66affSColin Finck {
116c2c66affSColin Finck DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
117c2c66affSColin Finck goto done;
118c2c66affSColin Finck }
119c2c66affSColin Finck
120c2c66affSColin Finck UpdateProgress(Context, 1);
121c2c66affSColin Finck
122c2c66affSColin Finck /* Zero the begin of the buffer */
123c2c66affSColin Finck RtlZeroMemory(Buffer, 3);
124c2c66affSColin Finck
125c2c66affSColin Finck /* Zero the rest of the FAT */
126c2c66affSColin Finck Sectors = 32 * 1024 / BootSector->BytesPerSector;
127c2c66affSColin Finck for (i = 1; i < (ULONG)BootSector->FATSectors; i += Sectors)
128c2c66affSColin Finck {
129c2c66affSColin Finck /* Zero some sectors of the FAT */
130c2c66affSColin Finck FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
131c2c66affSColin Finck if (((ULONG)BootSector->FATSectors - i) <= Sectors)
132c2c66affSColin Finck {
133c2c66affSColin Finck Sectors = (ULONG)BootSector->FATSectors - i;
134c2c66affSColin Finck }
135c2c66affSColin Finck
136c2c66affSColin Finck Size = Sectors * BootSector->BytesPerSector;
137c2c66affSColin Finck Status = NtWriteFile(FileHandle,
138c2c66affSColin Finck NULL,
139c2c66affSColin Finck NULL,
140c2c66affSColin Finck NULL,
141c2c66affSColin Finck &IoStatusBlock,
142c2c66affSColin Finck Buffer,
143c2c66affSColin Finck Size,
144c2c66affSColin Finck &FileOffset,
145c2c66affSColin Finck NULL);
146c2c66affSColin Finck if (!NT_SUCCESS(Status))
147c2c66affSColin Finck {
148c2c66affSColin Finck DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
149c2c66affSColin Finck goto done;
150c2c66affSColin Finck }
151c2c66affSColin Finck
152c2c66affSColin Finck UpdateProgress(Context, Sectors);
153c2c66affSColin Finck }
154c2c66affSColin Finck
155c2c66affSColin Finck done:
156c2c66affSColin Finck /* Free the buffer */
157c2c66affSColin Finck RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
158c2c66affSColin Finck return Status;
159c2c66affSColin Finck }
160c2c66affSColin Finck
161c2c66affSColin Finck
162c2c66affSColin Finck static NTSTATUS
Fat12WriteRootDirectory(IN HANDLE FileHandle,IN PFAT16_BOOT_SECTOR BootSector,IN OUT PFORMAT_CONTEXT Context)163c2c66affSColin Finck Fat12WriteRootDirectory(IN HANDLE FileHandle,
164c2c66affSColin Finck IN PFAT16_BOOT_SECTOR BootSector,
165c2c66affSColin Finck IN OUT PFORMAT_CONTEXT Context)
166c2c66affSColin Finck {
167c2c66affSColin Finck IO_STATUS_BLOCK IoStatusBlock;
168c2c66affSColin Finck NTSTATUS Status = STATUS_SUCCESS;
169c2c66affSColin Finck PUCHAR Buffer;
170c2c66affSColin Finck LARGE_INTEGER FileOffset;
171c2c66affSColin Finck ULONG FirstRootDirSector;
172c2c66affSColin Finck ULONG RootDirSectors;
173c2c66affSColin Finck ULONG Sectors;
174c2c66affSColin Finck ULONG Size;
175c2c66affSColin Finck ULONG i;
176c2c66affSColin Finck
177c2c66affSColin Finck DPRINT("BootSector->ReservedSectors = %hu\n", BootSector->ReservedSectors);
178c2c66affSColin Finck DPRINT("BootSector->FATSectors = %hu\n", BootSector->FATSectors);
179c2c66affSColin Finck DPRINT("BootSector->SectorsPerCluster = %u\n", BootSector->SectorsPerCluster);
180c2c66affSColin Finck
181c2c66affSColin Finck /* Write cluster */
182c2c66affSColin Finck RootDirSectors = ((BootSector->RootEntries * 32) +
183c2c66affSColin Finck (BootSector->BytesPerSector - 1)) / BootSector->BytesPerSector;
184c2c66affSColin Finck FirstRootDirSector =
185c2c66affSColin Finck BootSector->ReservedSectors + (BootSector->FATCount * BootSector->FATSectors);
186c2c66affSColin Finck
187c2c66affSColin Finck DPRINT("RootDirSectors = %lu\n", RootDirSectors);
188c2c66affSColin Finck DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
189c2c66affSColin Finck
190c2c66affSColin Finck /* Allocate buffer for the cluster */
191c2c66affSColin Finck Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
192c2c66affSColin Finck 0,
193c2c66affSColin Finck 32 * 1024);
194c2c66affSColin Finck if (Buffer == NULL)
195c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
196c2c66affSColin Finck
197c2c66affSColin Finck /* Zero the buffer */
198c2c66affSColin Finck RtlZeroMemory(Buffer, 32 * 1024);
199c2c66affSColin Finck
200c2c66affSColin Finck Sectors = 32 * 1024 / BootSector->BytesPerSector;
201c2c66affSColin Finck for (i = 0; i < RootDirSectors; i += Sectors)
202c2c66affSColin Finck {
203c2c66affSColin Finck /* Zero some sectors of the root directory */
204c2c66affSColin Finck FileOffset.QuadPart = (FirstRootDirSector + i) * BootSector->BytesPerSector;
205c2c66affSColin Finck
206c2c66affSColin Finck if ((RootDirSectors - i) <= Sectors)
207c2c66affSColin Finck {
208c2c66affSColin Finck Sectors = RootDirSectors - i;
209c2c66affSColin Finck }
210c2c66affSColin Finck
211c2c66affSColin Finck Size = Sectors * BootSector->BytesPerSector;
212c2c66affSColin Finck
213c2c66affSColin Finck Status = NtWriteFile(FileHandle,
214c2c66affSColin Finck NULL,
215c2c66affSColin Finck NULL,
216c2c66affSColin Finck NULL,
217c2c66affSColin Finck &IoStatusBlock,
218c2c66affSColin Finck Buffer,
219c2c66affSColin Finck Size,
220c2c66affSColin Finck &FileOffset,
221c2c66affSColin Finck NULL);
222c2c66affSColin Finck if (!NT_SUCCESS(Status))
223c2c66affSColin Finck {
224c2c66affSColin Finck DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
225c2c66affSColin Finck goto done;
226c2c66affSColin Finck }
227c2c66affSColin Finck
228c2c66affSColin Finck UpdateProgress(Context, Sectors);
229c2c66affSColin Finck }
230c2c66affSColin Finck
231c2c66affSColin Finck done:
232c2c66affSColin Finck /* Free the buffer */
233c2c66affSColin Finck RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
234c2c66affSColin Finck return Status;
235c2c66affSColin Finck }
236c2c66affSColin Finck
237c2c66affSColin Finck
238c2c66affSColin Finck NTSTATUS
Fat12Format(IN HANDLE FileHandle,IN PPARTITION_INFORMATION PartitionInfo,IN PDISK_GEOMETRY DiskGeometry,IN PUNICODE_STRING Label,IN BOOLEAN QuickFormat,IN ULONG ClusterSize,IN OUT PFORMAT_CONTEXT Context)239c2c66affSColin Finck Fat12Format(IN HANDLE FileHandle,
240c2c66affSColin Finck IN PPARTITION_INFORMATION PartitionInfo,
241c2c66affSColin Finck IN PDISK_GEOMETRY DiskGeometry,
242c2c66affSColin Finck IN PUNICODE_STRING Label,
243c2c66affSColin Finck IN BOOLEAN QuickFormat,
244c2c66affSColin Finck IN ULONG ClusterSize,
245c2c66affSColin Finck IN OUT PFORMAT_CONTEXT Context)
246c2c66affSColin Finck {
247c2c66affSColin Finck FAT16_BOOT_SECTOR BootSector;
248c2c66affSColin Finck OEM_STRING VolumeLabel;
249c2c66affSColin Finck ULONG SectorCount;
250c2c66affSColin Finck ULONG RootDirSectors;
251c2c66affSColin Finck ULONG TmpVal1;
252c2c66affSColin Finck ULONG TmpVal2;
253c2c66affSColin Finck ULONG TmpVal3;
254c2c66affSColin Finck NTSTATUS Status;
255c2c66affSColin Finck
256c2c66affSColin Finck /* Calculate cluster size */
257c2c66affSColin Finck if (ClusterSize == 0)
258c2c66affSColin Finck {
259c2c66affSColin Finck if (DiskGeometry->MediaType == FixedMedia)
260c2c66affSColin Finck {
261c2c66affSColin Finck /* 4KB Cluster (Harddisk only) */
262c2c66affSColin Finck ClusterSize = 4096;
263c2c66affSColin Finck }
264c2c66affSColin Finck else
265c2c66affSColin Finck {
266c2c66affSColin Finck /* 512 byte cluster (floppy) */
267c2c66affSColin Finck ClusterSize = 512;
268c2c66affSColin Finck }
269c2c66affSColin Finck }
270c2c66affSColin Finck
271c2c66affSColin Finck SectorCount = PartitionInfo->PartitionLength.QuadPart >>
272c2c66affSColin Finck GetShiftCount(DiskGeometry->BytesPerSector); /* Use shifting to avoid 64-bit division */
273c2c66affSColin Finck
274c2c66affSColin Finck DPRINT("SectorCount = %lu\n", SectorCount);
275c2c66affSColin Finck
276c2c66affSColin Finck RtlZeroMemory(&BootSector, sizeof(FAT16_BOOT_SECTOR));
277c2c66affSColin Finck memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
2786ff94017SPierre Schweitzer /* FIXME: Add dummy bootloader for real */
2796ff94017SPierre Schweitzer BootSector.Jump[0] = 0xeb;
2806ff94017SPierre Schweitzer BootSector.Jump[1] = 0x3c;
2816ff94017SPierre Schweitzer BootSector.Jump[2] = 0x90;
282c2c66affSColin Finck BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
283c2c66affSColin Finck BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
284c2c66affSColin Finck BootSector.ReservedSectors = 1;
285c2c66affSColin Finck BootSector.FATCount = 2;
286c2c66affSColin Finck BootSector.RootEntries = 512;
287c2c66affSColin Finck BootSector.Sectors = (SectorCount < 0x10000) ? (unsigned short)SectorCount : 0;
288c2c66affSColin Finck BootSector.Media = 0xf8;
289c2c66affSColin Finck BootSector.FATSectors = 0; /* Set later. See below. */
290c2c66affSColin Finck BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
291c2c66affSColin Finck BootSector.Heads = DiskGeometry->TracksPerCylinder;
292c2c66affSColin Finck BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
293c2c66affSColin Finck BootSector.SectorsHuge = (SectorCount >= 0x10000) ? (unsigned long)SectorCount : 0;
294c2c66affSColin Finck BootSector.Drive = (DiskGeometry->MediaType == FixedMedia) ? 0x80 : 0x00;
295c2c66affSColin Finck BootSector.ExtBootSignature = 0x29;
296c2c66affSColin Finck BootSector.VolumeID = CalcVolumeSerialNumber();
297c2c66affSColin Finck if ((Label == NULL) || (Label->Buffer == NULL))
298c2c66affSColin Finck {
299c2c66affSColin Finck memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
300c2c66affSColin Finck }
301c2c66affSColin Finck else
302c2c66affSColin Finck {
303c2c66affSColin Finck RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
304c2c66affSColin Finck RtlFillMemory(&BootSector.VolumeLabel[0], 11, ' ');
305c2c66affSColin Finck memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
306c2c66affSColin Finck VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
307c2c66affSColin Finck RtlFreeOemString(&VolumeLabel);
308c2c66affSColin Finck }
309c2c66affSColin Finck
310c2c66affSColin Finck memcpy(&BootSector.SysType[0], "FAT12 ", 8);
311c2c66affSColin Finck
312c2c66affSColin Finck RootDirSectors = ((BootSector.RootEntries * 32) +
313c2c66affSColin Finck (BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
314c2c66affSColin Finck
315c2c66affSColin Finck /* Calculate number of FAT sectors */
316c2c66affSColin Finck /* ((BootSector.BytesPerSector * 2) / 3) FAT entries (12bit) fit into one sector */
317c2c66affSColin Finck TmpVal1 = SectorCount - (BootSector.ReservedSectors + RootDirSectors);
318c2c66affSColin Finck TmpVal2 = (((BootSector.BytesPerSector * 2) / 3) * BootSector.SectorsPerCluster) + BootSector.FATCount;
319c2c66affSColin Finck TmpVal3 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
320c2c66affSColin Finck BootSector.FATSectors = (unsigned short)(TmpVal3 & 0xffff);
321c2c66affSColin Finck
322c2c66affSColin Finck DPRINT("BootSector.FATSectors = %hx\n", BootSector.FATSectors);
323c2c66affSColin Finck
324c2c66affSColin Finck /* Init context data */
325c2c66affSColin Finck Context->TotalSectorCount =
326c2c66affSColin Finck 1 + (BootSector.FATSectors * 2) + RootDirSectors;
327c2c66affSColin Finck
328c2c66affSColin Finck if (!QuickFormat)
329c2c66affSColin Finck {
330c2c66affSColin Finck Context->TotalSectorCount += SectorCount;
331c2c66affSColin Finck
332c2c66affSColin Finck Status = FatWipeSectors(FileHandle,
333c2c66affSColin Finck SectorCount,
334c2c66affSColin Finck (ULONG)BootSector.SectorsPerCluster,
335c2c66affSColin Finck (ULONG)BootSector.BytesPerSector,
336c2c66affSColin Finck Context);
337c2c66affSColin Finck if (!NT_SUCCESS(Status))
338c2c66affSColin Finck {
339c2c66affSColin Finck DPRINT("FatWipeSectors() failed with status 0x%.08x\n", Status);
340c2c66affSColin Finck return Status;
341c2c66affSColin Finck }
342c2c66affSColin Finck }
343c2c66affSColin Finck
344c2c66affSColin Finck Status = Fat12WriteBootSector(FileHandle,
345c2c66affSColin Finck &BootSector,
346c2c66affSColin Finck Context);
347c2c66affSColin Finck if (!NT_SUCCESS(Status))
348c2c66affSColin Finck {
349c2c66affSColin Finck DPRINT("Fat12WriteBootSector() failed with status 0x%.08x\n", Status);
350c2c66affSColin Finck return Status;
351c2c66affSColin Finck }
352c2c66affSColin Finck
353c2c66affSColin Finck /* Write first FAT copy */
354c2c66affSColin Finck Status = Fat12WriteFAT(FileHandle,
355c2c66affSColin Finck 0,
356c2c66affSColin Finck &BootSector,
357c2c66affSColin Finck Context);
358c2c66affSColin Finck if (!NT_SUCCESS(Status))
359c2c66affSColin Finck {
360c2c66affSColin Finck DPRINT("Fat12WriteFAT() failed with status 0x%.08x\n", Status);
361c2c66affSColin Finck return Status;
362c2c66affSColin Finck }
363c2c66affSColin Finck
364c2c66affSColin Finck /* Write second FAT copy */
365c2c66affSColin Finck Status = Fat12WriteFAT(FileHandle,
366c2c66affSColin Finck (ULONG)BootSector.FATSectors,
367c2c66affSColin Finck &BootSector,
368c2c66affSColin Finck Context);
369c2c66affSColin Finck if (!NT_SUCCESS(Status))
370c2c66affSColin Finck {
371c2c66affSColin Finck DPRINT("Fat12WriteFAT() failed with status 0x%.08x.\n", Status);
372c2c66affSColin Finck return Status;
373c2c66affSColin Finck }
374c2c66affSColin Finck
375c2c66affSColin Finck Status = Fat12WriteRootDirectory(FileHandle,
376c2c66affSColin Finck &BootSector,
377c2c66affSColin Finck Context);
378c2c66affSColin Finck if (!NT_SUCCESS(Status))
379c2c66affSColin Finck {
380c2c66affSColin Finck DPRINT("Fat12WriteRootDirectory() failed with status 0x%.08x\n", Status);
381c2c66affSColin Finck }
382c2c66affSColin Finck
383c2c66affSColin Finck return Status;
384c2c66affSColin Finck }
385