- In Win32 DBG is defined to 0 for a non-debug build and to 1 for a debug build....
[reactos.git] / reactos / base / setup / usetup / bootsup.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: subsys/system/usetup/bootsup.c
23 * PURPOSE: Bootloader support functions
24 * PROGRAMMER: Eric Kohl
25 */
26
27 #include "usetup.h"
28
29 #define NDEBUG
30 #include <debug.h>
31
32 #define SECTORSIZE 512
33
34 /* FUNCTIONS ****************************************************************/
35
36
37 static VOID
38 CreateCommonFreeLoaderSections(PINICACHE IniCache)
39 {
40 PINICACHESECTION IniSection;
41
42 /* Create "FREELOADER" section */
43 IniSection = IniCacheAppendSection(IniCache,
44 L"FREELOADER");
45
46 #if DBG
47 if (IsUnattendedSetup)
48 {
49 /* DefaultOS=ReactOS */
50 IniCacheInsertKey(IniSection,
51 NULL,
52 INSERT_LAST,
53 L"DefaultOS",
54 L"ReactOS_KdSerial");
55 }
56 else
57 #endif
58 {
59 /* DefaultOS=ReactOS */
60 IniCacheInsertKey(IniSection,
61 NULL,
62 INSERT_LAST,
63 L"DefaultOS",
64 L"ReactOS");
65 }
66
67 #if DBG
68 if (IsUnattendedSetup)
69 #endif
70 {
71 /* Timeout=0 for unattended or non debug*/
72 IniCacheInsertKey(IniSection,
73 NULL,
74 INSERT_LAST,
75 L"TimeOut",
76 L"0");
77 }
78 #if DBG
79 else
80 {
81 /* Timeout=0 or 10 */
82 IniCacheInsertKey(IniSection,
83 NULL,
84 INSERT_LAST,
85 L"TimeOut",
86 L"10");
87 }
88 #endif
89
90 /* Create "Display" section */
91 IniSection = IniCacheAppendSection(IniCache,
92 L"Display");
93
94 /* TitleText=ReactOS Boot Manager */
95 IniCacheInsertKey(IniSection,
96 NULL,
97 INSERT_LAST,
98 L"TitleText",
99 L"ReactOS Boot Manager");
100
101 /* StatusBarColor=Cyan */
102 IniCacheInsertKey(IniSection,
103 NULL,
104 INSERT_LAST,
105 L"StatusBarColor",
106 L"Cyan");
107
108 /* StatusBarTextColor=Black */
109 IniCacheInsertKey(IniSection,
110 NULL,
111 INSERT_LAST,
112 L"StatusBarTextColor",
113 L"Black");
114
115 /* BackdropTextColor=White */
116 IniCacheInsertKey(IniSection,
117 NULL,
118 INSERT_LAST,
119 L"BackdropTextColor",
120 L"White");
121
122 /* BackdropColor=Blue */
123 IniCacheInsertKey(IniSection,
124 NULL,
125 INSERT_LAST,
126 L"BackdropColor",
127 L"Blue");
128
129 /* BackdropFillStyle=Medium */
130 IniCacheInsertKey(IniSection,
131 NULL,
132 INSERT_LAST,
133 L"BackdropFillStyle",
134 L"Medium");
135
136 /* TitleBoxTextColor=White */
137 IniCacheInsertKey(IniSection,
138 NULL,
139 INSERT_LAST,
140 L"TitleBoxTextColor",
141 L"White");
142
143 /* TitleBoxColor=Red */
144 IniCacheInsertKey(IniSection,
145 NULL,
146 INSERT_LAST,
147 L"TitleBoxColor",
148 L"Red");
149
150 /* MessageBoxTextColor=White */
151 IniCacheInsertKey(IniSection,
152 NULL,
153 INSERT_LAST,
154 L"MessageBoxTextColor",
155 L"White");
156
157 /* MessageBoxColor=Blue */
158 IniCacheInsertKey(IniSection,
159 NULL,
160 INSERT_LAST,
161 L"MessageBoxColor",
162 L"Blue");
163
164 /* MenuTextColor=White */
165 IniCacheInsertKey(IniSection,
166 NULL,
167 INSERT_LAST,
168 L"MenuTextColor",
169 L"Gray");
170
171 /* MenuColor=Blue */
172 IniCacheInsertKey(IniSection,
173 NULL,
174 INSERT_LAST,
175 L"MenuColor",
176 L"Black");
177
178 /* TextColor=Yellow */
179 IniCacheInsertKey(IniSection,
180 NULL,
181 INSERT_LAST,
182 L"TextColor",
183 L"Gray");
184
185 /* SelectedTextColor=Black */
186 IniCacheInsertKey(IniSection,
187 NULL,
188 INSERT_LAST,
189 L"SelectedTextColor",
190 L"Black");
191
192 /* SelectedColor=Gray */
193 IniCacheInsertKey(IniSection,
194 NULL,
195 INSERT_LAST,
196 L"SelectedColor",
197 L"Gray");
198
199 /* SelectedColor=Gray */
200 IniCacheInsertKey(IniSection,
201 NULL,
202 INSERT_LAST,
203 L"ShowTime",
204 L"No");
205
206 /* SelectedColor=Gray */
207 IniCacheInsertKey(IniSection,
208 NULL,
209 INSERT_LAST,
210 L"MenuBox",
211 L"No");
212
213 /* SelectedColor=Gray */
214 IniCacheInsertKey(IniSection,
215 NULL,
216 INSERT_LAST,
217 L"CenterMenu",
218 L"No");
219
220 /* SelectedColor=Gray */
221 IniCacheInsertKey(IniSection,
222 NULL,
223 INSERT_LAST,
224 L"MinimalUI",
225 L"Yes");
226
227 /* SelectedColor=Gray */
228 IniCacheInsertKey(IniSection,
229 NULL,
230 INSERT_LAST,
231 L"TimeText",
232 L"Seconds until highlighted choice will be started automatically: ");
233 }
234
235
236 NTSTATUS
237 CreateFreeLoaderIniForDos(PWCHAR IniPath,
238 PWCHAR ArcPath)
239 {
240 PINICACHE IniCache;
241 PINICACHESECTION IniSection;
242
243 IniCache = IniCacheCreate();
244
245 CreateCommonFreeLoaderSections(IniCache);
246
247 /* Create "Operating Systems" section */
248 IniSection = IniCacheAppendSection(IniCache,
249 L"Operating Systems");
250
251 /* REACTOS=ReactOS */
252 IniCacheInsertKey(IniSection,
253 NULL,
254 INSERT_LAST,
255 L"ReactOS",
256 L"\"ReactOS\"");
257
258 /* ReactOS_Debug="ReactOS (Debug)" */
259 IniCacheInsertKey(IniSection,
260 NULL,
261 INSERT_LAST,
262 L"ReactOS_Debug",
263 L"\"ReactOS (Debug)\"");
264
265 /* DOS=Dos/Windows */
266 IniCacheInsertKey(IniSection,
267 NULL,
268 INSERT_LAST,
269 L"DOS",
270 L"\"DOS/Windows\"");
271
272 /* Create "ReactOS" section */
273 IniSection = IniCacheAppendSection(IniCache,
274 L"ReactOS");
275
276 /* BootType=ReactOS */
277 IniCacheInsertKey(IniSection,
278 NULL,
279 INSERT_LAST,
280 L"BootType",
281 L"ReactOS");
282
283 /* SystemPath=<ArcPath> */
284 IniCacheInsertKey(IniSection,
285 NULL,
286 INSERT_LAST,
287 L"SystemPath",
288 ArcPath);
289
290 /* Create "ReactOS_Debug" section */
291 IniSection = IniCacheAppendSection(IniCache,
292 L"ReactOS_Debug");
293
294 /* BootType=ReactOS */
295 IniCacheInsertKey(IniSection,
296 NULL,
297 INSERT_LAST,
298 L"BootType",
299 L"ReactOS");
300
301 /* SystemPath=<ArcPath> */
302 IniCacheInsertKey(IniSection,
303 NULL,
304 INSERT_LAST,
305 L"SystemPath",
306 ArcPath);
307
308 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS*/
309 IniCacheInsertKey(IniSection,
310 NULL,
311 INSERT_LAST,
312 L"Options",
313 L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
314
315 /* Create "DOS" section */
316 IniSection = IniCacheAppendSection(IniCache,
317 L"DOS");
318
319 /* BootType=BootSector */
320 IniCacheInsertKey(IniSection,
321 NULL,
322 INSERT_LAST,
323 L"BootType",
324 L"BootSector");
325
326 /* BootDrive=hd0 */
327 IniCacheInsertKey(IniSection,
328 NULL,
329 INSERT_LAST,
330 L"BootDrive",
331 L"hd0");
332
333 /* BootPartition=1 */
334 IniCacheInsertKey(IniSection,
335 NULL,
336 INSERT_LAST,
337 L"BootPartition",
338 L"1");
339
340 /* BootSector=BOOTSECT.DOS */
341 IniCacheInsertKey(IniSection,
342 NULL,
343 INSERT_LAST,
344 L"BootSectorFile",
345 L"BOOTSECT.DOS");
346
347 IniCacheSave(IniCache, IniPath);
348 IniCacheDestroy(IniCache);
349
350 return(STATUS_SUCCESS);
351 }
352
353
354 NTSTATUS
355 CreateFreeLoaderIniForReactos(PWCHAR IniPath,
356 PWCHAR ArcPath)
357 {
358 PINICACHE IniCache;
359 PINICACHESECTION IniSection;
360
361 IniCache = IniCacheCreate();
362
363 CreateCommonFreeLoaderSections(IniCache);
364
365 /* Create "Operating Systems" section */
366 IniSection = IniCacheAppendSection(IniCache,
367 L"Operating Systems");
368
369 /* ReactOS="ReactOS" */
370 IniCacheInsertKey(IniSection,
371 NULL,
372 INSERT_LAST,
373 L"ReactOS",
374 L"\"ReactOS\"");
375
376 /* ReactOS_Debug="ReactOS (Debug)" */
377 IniCacheInsertKey(IniSection,
378 NULL,
379 INSERT_LAST,
380 L"ReactOS_Debug",
381 L"\"ReactOS (Debug)\"");
382
383 #if DBG
384 /* ReactOS_KdSerial="ReactOS (RosDbg)" */
385 IniCacheInsertKey(IniSection,
386 NULL,
387 INSERT_LAST,
388 L"ReactOS_KdSerial",
389 L"\"ReactOS (RosDbg)\"");
390
391 /* ReactOS_WinLdr="ReactOS (WinLdr)" */
392 IniCacheInsertKey(IniSection,
393 NULL,
394 INSERT_LAST,
395 L"ReactOS_WinLdr",
396 L"\"ReactOS (WinLdr)\"");
397
398 /* ReactOS_Ram="ReactOS (RAM Disk)" */
399 IniCacheInsertKey(IniSection,
400 NULL,
401 INSERT_LAST,
402 L"ReactOS_Ram",
403 L"\"ReactOS (RAM Disk)\"");
404 #endif
405
406 /* Create "ReactOS" section */
407 IniSection = IniCacheAppendSection(IniCache,
408 L"ReactOS");
409
410 /* BootType=ReactOS */
411 IniCacheInsertKey(IniSection,
412 NULL,
413 INSERT_LAST,
414 L"BootType",
415 L"ReactOS");
416
417 /* SystemPath=<ArcPath> */
418 IniCacheInsertKey(IniSection,
419 NULL,
420 INSERT_LAST,
421 L"SystemPath",
422 ArcPath);
423
424 /* Options=*/
425 IniCacheInsertKey(IniSection,
426 NULL,
427 INSERT_LAST,
428 L"Options",
429 L"");
430
431 /* Create "ReactOS_Debug" section */
432 IniSection = IniCacheAppendSection(IniCache,
433 L"ReactOS_Debug");
434
435 /* BootType=ReactOS */
436 IniCacheInsertKey(IniSection,
437 NULL,
438 INSERT_LAST,
439 L"BootType",
440 L"ReactOS");
441
442 /* SystemPath=<ArcPath> */
443 IniCacheInsertKey(IniSection,
444 NULL,
445 INSERT_LAST,
446 L"SystemPath",
447 ArcPath);
448
449 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS*/
450 IniCacheInsertKey(IniSection,
451 NULL,
452 INSERT_LAST,
453 L"Options",
454 L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
455
456 #if DBG
457
458 /* Create "ReactOS_KdSerial" section */
459 IniSection = IniCacheAppendSection(IniCache,
460 L"ReactOS_KdSerial");
461
462 /* BootType=ReactOS */
463 IniCacheInsertKey(IniSection,
464 NULL,
465 INSERT_LAST,
466 L"BootType",
467 L"ReactOS");
468
469 /* SystemPath=<ArcPath> */
470 IniCacheInsertKey(IniSection,
471 NULL,
472 INSERT_LAST,
473 L"SystemPath",
474 ArcPath);
475
476 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS*/
477 IniCacheInsertKey(IniSection,
478 NULL,
479 INSERT_LAST,
480 L"Options",
481 L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /KDSERIAL");
482
483 /* ------------------------------------------------------------------------------ */
484
485 /* Create "ReactOS_WinLdr" section */
486 IniSection = IniCacheAppendSection(IniCache,
487 L"ReactOS_WinLdr");
488
489 /* BootType=Windows2003 */
490 IniCacheInsertKey(IniSection,
491 NULL,
492 INSERT_LAST,
493 L"BootType",
494 L"Windows2003");
495
496 /* SystemPath=<ArcPath> */
497 IniCacheInsertKey(IniSection,
498 NULL,
499 INSERT_LAST,
500 L"SystemPath",
501 ArcPath);
502
503 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS*/
504 IniCacheInsertKey(IniSection,
505 NULL,
506 INSERT_LAST,
507 L"Options",
508 L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS");
509
510 /* Create "ReactOS_Ram" section */
511 IniSection = IniCacheAppendSection(IniCache,
512 L"ReactOS_Ram");
513
514 /* BootType=ReactOS */
515 IniCacheInsertKey(IniSection,
516 NULL,
517 INSERT_LAST,
518 L"BootType",
519 L"ReactOS");
520
521 /* SystemPath=ramdisk(0)\\ReactOS */
522 IniCacheInsertKey(IniSection,
523 NULL,
524 INSERT_LAST,
525 L"SystemPath",
526 L"ramdisk(0)\\ReactOS");
527
528 /* Options=/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256*/
529 IniCacheInsertKey(IniSection,
530 NULL,
531 INSERT_LAST,
532 L"Options",
533 L"/DEBUG /DEBUGPORT=COM1 /BAUDRATE=115200 /SOS /RDIMAGEPATH=reactos.img /RDIMAGEOFFSET=32256");
534
535 #endif
536
537 /* Save the ini file */
538 IniCacheSave(IniCache, IniPath);
539 IniCacheDestroy(IniCache);
540
541 return(STATUS_SUCCESS);
542 }
543
544
545 NTSTATUS
546 UpdateFreeLoaderIni(PWCHAR IniPath,
547 PWCHAR ArcPath)
548 {
549 UNICODE_STRING Name;
550 PINICACHE IniCache;
551 PINICACHESECTION IniSection;
552 PINICACHESECTION OsIniSection;
553 WCHAR SectionName[80];
554 WCHAR OsName[80];
555 WCHAR SystemPath[200];
556 WCHAR SectionName2[200];
557 PWCHAR KeyData;
558 ULONG i,j;
559 NTSTATUS Status;
560
561 RtlInitUnicodeString(&Name,
562 IniPath);
563
564 Status = IniCacheLoad(&IniCache,
565 &Name,
566 FALSE);
567 if (!NT_SUCCESS(Status))
568 return(Status);
569
570 /* Get "Operating Systems" section */
571 IniSection = IniCacheGetSection(IniCache,
572 L"Operating Systems");
573 if (IniSection == NULL)
574 {
575 IniCacheDestroy(IniCache);
576 return(STATUS_UNSUCCESSFUL);
577 }
578
579 /* Find an existing usable or an unused section name */
580 i = 1;
581 wcscpy(SectionName, L"ReactOS");
582 wcscpy(OsName, L"\"ReactOS\"");
583 while(TRUE)
584 {
585 Status = IniCacheGetKey(IniSection,
586 SectionName,
587 &KeyData);
588 if (!NT_SUCCESS(Status))
589 break;
590
591 /* Get operation system section */
592 if (KeyData[0] == '"')
593 {
594 wcscpy(SectionName2, &KeyData[1]);
595 j = wcslen(SectionName2);
596 if (j > 0)
597 {
598 SectionName2[j-1] = 0;
599 }
600 }
601 else
602 {
603 wcscpy(SectionName2, KeyData);
604 }
605
606 OsIniSection = IniCacheGetSection(IniCache,
607 SectionName2);
608 if (OsIniSection != NULL)
609 {
610 BOOLEAN UseExistingEntry = TRUE;
611
612 /* Check BootType */
613 Status = IniCacheGetKey(OsIniSection,
614 L"BootType",
615 &KeyData);
616 if (NT_SUCCESS(Status))
617 {
618 if (KeyData == NULL
619 || (_wcsicmp(KeyData, L"ReactOS") != 0
620 && _wcsicmp(KeyData, L"\"ReactOS\"") != 0))
621 {
622 /* This is not a ReactOS entry */
623 UseExistingEntry = FALSE;
624 }
625 }
626 else
627 {
628 UseExistingEntry = FALSE;
629 }
630
631 if (UseExistingEntry)
632 {
633 /* BootType is ReactOS. Now check SystemPath */
634 Status = IniCacheGetKey(OsIniSection,
635 L"SystemPath",
636 &KeyData);
637 if (NT_SUCCESS(Status))
638 {
639 swprintf(SystemPath, L"\"%S\"", ArcPath);
640 if (KeyData == NULL
641 || (_wcsicmp(KeyData, ArcPath) != 0
642 && _wcsicmp(KeyData, SystemPath) != 0))
643 {
644 /* This entry is a ReactOS entry, but the SystemRoot does not
645 match the one we are looking for */
646 UseExistingEntry = FALSE;
647 }
648 }
649 else
650 {
651 UseExistingEntry = FALSE;
652 }
653 }
654
655 if (UseExistingEntry)
656 {
657 IniCacheDestroy(IniCache);
658 return(STATUS_SUCCESS);
659 }
660 }
661
662 swprintf(SectionName, L"ReactOS_%lu", i);
663 swprintf(OsName, L"\"ReactOS %lu\"", i);
664 i++;
665 }
666
667 /* <SectionName>=<OsName> */
668 IniCacheInsertKey(IniSection,
669 NULL,
670 INSERT_LAST,
671 SectionName,
672 OsName);
673
674 /* Create <SectionName> section */
675 IniSection = IniCacheAppendSection(IniCache,
676 SectionName);
677
678 /* BootType=ReactOS */
679 IniCacheInsertKey(IniSection,
680 NULL,
681 INSERT_LAST,
682 L"BootType",
683 L"ReactOS");
684
685 /* SystemPath=<ArcPath> */
686 IniCacheInsertKey(IniSection,
687 NULL,
688 INSERT_LAST,
689 L"SystemPath",
690 ArcPath);
691
692 IniCacheSave(IniCache, IniPath);
693 IniCacheDestroy(IniCache);
694
695 return(STATUS_SUCCESS);
696 }
697
698
699 NTSTATUS
700 SaveCurrentBootSector(PWSTR RootPath,
701 PWSTR DstPath)
702 {
703 OBJECT_ATTRIBUTES ObjectAttributes;
704 IO_STATUS_BLOCK IoStatusBlock;
705 UNICODE_STRING Name;
706 HANDLE FileHandle;
707 NTSTATUS Status;
708 PUCHAR BootSector;
709
710 /* Allocate buffer for bootsector */
711 BootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
712 0,
713 SECTORSIZE);
714 if (BootSector == NULL)
715 return(STATUS_INSUFFICIENT_RESOURCES);
716
717 /* Read current boot sector into buffer */
718 RtlInitUnicodeString(&Name,
719 RootPath);
720
721 InitializeObjectAttributes(&ObjectAttributes,
722 &Name,
723 OBJ_CASE_INSENSITIVE,
724 NULL,
725 NULL);
726
727 Status = NtOpenFile(&FileHandle,
728 GENERIC_READ,
729 &ObjectAttributes,
730 &IoStatusBlock,
731 0,
732 FILE_SYNCHRONOUS_IO_NONALERT);
733 if (!NT_SUCCESS(Status))
734 {
735 RtlFreeHeap(ProcessHeap, 0, BootSector);
736 return(Status);
737 }
738
739 Status = NtReadFile(FileHandle,
740 NULL,
741 NULL,
742 NULL,
743 &IoStatusBlock,
744 BootSector,
745 SECTORSIZE,
746 NULL,
747 NULL);
748 NtClose(FileHandle);
749 if (!NT_SUCCESS(Status))
750 {
751 RtlFreeHeap(ProcessHeap, 0, BootSector);
752 return(Status);
753 }
754
755 /* Write bootsector to DstPath */
756 RtlInitUnicodeString(&Name,
757 DstPath);
758
759 InitializeObjectAttributes(&ObjectAttributes,
760 &Name,
761 0,
762 NULL,
763 NULL);
764
765 Status = NtCreateFile(&FileHandle,
766 GENERIC_WRITE,
767 &ObjectAttributes,
768 &IoStatusBlock,
769 NULL,
770 FILE_ATTRIBUTE_NORMAL,
771 0,
772 FILE_SUPERSEDE,
773 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
774 NULL,
775 0);
776 if (!NT_SUCCESS(Status))
777 {
778 RtlFreeHeap(ProcessHeap, 0, BootSector);
779 return(Status);
780 }
781
782 Status = NtWriteFile(FileHandle,
783 NULL,
784 NULL,
785 NULL,
786 &IoStatusBlock,
787 BootSector,
788 SECTORSIZE,
789 NULL,
790 NULL);
791 NtClose(FileHandle);
792
793 /* Free the new boot sector */
794 RtlFreeHeap(ProcessHeap, 0, BootSector);
795
796 return(Status);
797 }
798
799
800 NTSTATUS
801 InstallFat16BootCodeToFile(PWSTR SrcPath,
802 PWSTR DstPath,
803 PWSTR RootPath)
804 {
805 OBJECT_ATTRIBUTES ObjectAttributes;
806 IO_STATUS_BLOCK IoStatusBlock;
807 UNICODE_STRING Name;
808 HANDLE FileHandle;
809 NTSTATUS Status;
810 PUCHAR OrigBootSector;
811 PUCHAR NewBootSector;
812
813 /* Allocate buffer for original bootsector */
814 OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
815 0,
816 SECTORSIZE);
817 if (OrigBootSector == NULL)
818 return(STATUS_INSUFFICIENT_RESOURCES);
819
820 /* Read current boot sector into buffer */
821 RtlInitUnicodeString(&Name,
822 RootPath);
823
824 InitializeObjectAttributes(&ObjectAttributes,
825 &Name,
826 OBJ_CASE_INSENSITIVE,
827 NULL,
828 NULL);
829
830 Status = NtOpenFile(&FileHandle,
831 GENERIC_READ,
832 &ObjectAttributes,
833 &IoStatusBlock,
834 0,
835 FILE_SYNCHRONOUS_IO_NONALERT);
836 if (!NT_SUCCESS(Status))
837 {
838 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
839 return(Status);
840 }
841
842 Status = NtReadFile(FileHandle,
843 NULL,
844 NULL,
845 NULL,
846 &IoStatusBlock,
847 OrigBootSector,
848 SECTORSIZE,
849 NULL,
850 NULL);
851 NtClose(FileHandle);
852 if (!NT_SUCCESS(Status))
853 {
854 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
855 return(Status);
856 }
857
858
859 /* Allocate buffer for new bootsector */
860 NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
861 0,
862 SECTORSIZE);
863 if (NewBootSector == NULL)
864 {
865 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
866 return(STATUS_INSUFFICIENT_RESOURCES);
867 }
868
869 /* Read new bootsector from SrcPath */
870 RtlInitUnicodeString(&Name,
871 SrcPath);
872
873 InitializeObjectAttributes(&ObjectAttributes,
874 &Name,
875 OBJ_CASE_INSENSITIVE,
876 NULL,
877 NULL);
878
879 Status = NtOpenFile(&FileHandle,
880 GENERIC_READ,
881 &ObjectAttributes,
882 &IoStatusBlock,
883 0,
884 FILE_SYNCHRONOUS_IO_NONALERT);
885 if (!NT_SUCCESS(Status))
886 {
887 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
888 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
889 return(Status);
890 }
891
892 Status = NtReadFile(FileHandle,
893 NULL,
894 NULL,
895 NULL,
896 &IoStatusBlock,
897 NewBootSector,
898 SECTORSIZE,
899 NULL,
900 NULL);
901 NtClose(FileHandle);
902 if (!NT_SUCCESS(Status))
903 {
904 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
905 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
906 return(Status);
907 }
908
909 /* Adjust bootsector (copy a part of the FAT BPB) */
910 memcpy((NewBootSector + 11), (OrigBootSector + 11), 51 /*fat BPB length*/);
911
912 /* Free the original boot sector */
913 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
914
915 /* Write new bootsector to DstPath */
916 RtlInitUnicodeString(&Name,
917 DstPath);
918
919 InitializeObjectAttributes(&ObjectAttributes,
920 &Name,
921 0,
922 NULL,
923 NULL);
924
925 Status = NtCreateFile(&FileHandle,
926 GENERIC_WRITE,
927 &ObjectAttributes,
928 &IoStatusBlock,
929 NULL,
930 FILE_ATTRIBUTE_NORMAL,
931 0,
932 FILE_OVERWRITE_IF,
933 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
934 NULL,
935 0);
936 if (!NT_SUCCESS(Status))
937 {
938 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
939 return(Status);
940 }
941
942 #if 0
943 FilePosition.QuadPart = 0;
944 #endif
945 Status = NtWriteFile(FileHandle,
946 NULL,
947 NULL,
948 NULL,
949 &IoStatusBlock,
950 NewBootSector,
951 SECTORSIZE,
952 NULL,
953 NULL);
954 NtClose(FileHandle);
955
956 /* Free the new boot sector */
957 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
958
959 return(Status);
960 }
961
962
963 NTSTATUS
964 InstallFat32BootCodeToFile(PWSTR SrcPath,
965 PWSTR DstPath,
966 PWSTR RootPath)
967 {
968 OBJECT_ATTRIBUTES ObjectAttributes;
969 IO_STATUS_BLOCK IoStatusBlock;
970 UNICODE_STRING Name;
971 HANDLE FileHandle;
972 NTSTATUS Status;
973 PUCHAR OrigBootSector;
974 PUCHAR NewBootSector;
975 LARGE_INTEGER FileOffset;
976
977 /* Allocate buffer for original bootsector */
978 OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
979 0,
980 SECTORSIZE);
981 if (OrigBootSector == NULL)
982 return(STATUS_INSUFFICIENT_RESOURCES);
983
984 /* Read current boot sector into buffer */
985 RtlInitUnicodeString(&Name,
986 RootPath);
987
988 InitializeObjectAttributes(&ObjectAttributes,
989 &Name,
990 OBJ_CASE_INSENSITIVE,
991 NULL,
992 NULL);
993
994 Status = NtOpenFile(&FileHandle,
995 GENERIC_READ,
996 &ObjectAttributes,
997 &IoStatusBlock,
998 0,
999 FILE_SYNCHRONOUS_IO_NONALERT);
1000 if (!NT_SUCCESS(Status))
1001 {
1002 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1003 return(Status);
1004 }
1005
1006 Status = NtReadFile(FileHandle,
1007 NULL,
1008 NULL,
1009 NULL,
1010 &IoStatusBlock,
1011 OrigBootSector,
1012 SECTORSIZE,
1013 NULL,
1014 NULL);
1015 NtClose(FileHandle);
1016 if (!NT_SUCCESS(Status))
1017 {
1018 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1019 return(Status);
1020 }
1021
1022 /* Allocate buffer for new bootsector (2 sectors) */
1023 NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
1024 0,
1025 2 * SECTORSIZE);
1026 if (NewBootSector == NULL)
1027 {
1028 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1029 return(STATUS_INSUFFICIENT_RESOURCES);
1030 }
1031
1032 /* Read new bootsector from SrcPath */
1033 RtlInitUnicodeString(&Name,
1034 SrcPath);
1035
1036 InitializeObjectAttributes(&ObjectAttributes,
1037 &Name,
1038 OBJ_CASE_INSENSITIVE,
1039 NULL,
1040 NULL);
1041
1042 Status = NtOpenFile(&FileHandle,
1043 GENERIC_READ,
1044 &ObjectAttributes,
1045 &IoStatusBlock,
1046 0,
1047 FILE_SYNCHRONOUS_IO_NONALERT);
1048 if (!NT_SUCCESS(Status))
1049 {
1050 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1051 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1052 return(Status);
1053 }
1054
1055 Status = NtReadFile(FileHandle,
1056 NULL,
1057 NULL,
1058 NULL,
1059 &IoStatusBlock,
1060 NewBootSector,
1061 2 * SECTORSIZE,
1062 NULL,
1063 NULL);
1064 NtClose(FileHandle);
1065 if (!NT_SUCCESS(Status))
1066 {
1067 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1068 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1069 return(Status);
1070 }
1071
1072 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1073 memcpy((NewBootSector + 3),
1074 (OrigBootSector + 3),
1075 87); /* FAT32 BPB length */
1076
1077 /* Disable the backup boot sector */
1078 NewBootSector[0x32] = 0x00;
1079 NewBootSector[0x33] = 0x00;
1080
1081 /* Free the original boot sector */
1082 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1083
1084 /* Write the first sector of the new bootcode to DstPath */
1085 RtlInitUnicodeString(&Name,
1086 DstPath);
1087
1088 InitializeObjectAttributes(&ObjectAttributes,
1089 &Name,
1090 0,
1091 NULL,
1092 NULL);
1093
1094 Status = NtCreateFile(&FileHandle,
1095 GENERIC_WRITE,
1096 &ObjectAttributes,
1097 &IoStatusBlock,
1098 NULL,
1099 FILE_ATTRIBUTE_NORMAL,
1100 0,
1101 FILE_SUPERSEDE,
1102 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY,
1103 NULL,
1104 0);
1105 if (!NT_SUCCESS(Status))
1106 {
1107 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1108 return(Status);
1109 }
1110
1111 Status = NtWriteFile(FileHandle,
1112 NULL,
1113 NULL,
1114 NULL,
1115 &IoStatusBlock,
1116 NewBootSector,
1117 SECTORSIZE,
1118 NULL,
1119 NULL);
1120 NtClose(FileHandle);
1121 if (!NT_SUCCESS(Status))
1122 {
1123 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1124 return(Status);
1125 }
1126
1127 /* Write the second sector of the new bootcode to boot disk sector 14 */
1128 RtlInitUnicodeString(&Name,
1129 RootPath);
1130
1131 InitializeObjectAttributes(&ObjectAttributes,
1132 &Name,
1133 0,
1134 NULL,
1135 NULL);
1136
1137 Status = NtOpenFile(&FileHandle,
1138 GENERIC_WRITE,
1139 &ObjectAttributes,
1140 &IoStatusBlock,
1141 0,
1142 FILE_SYNCHRONOUS_IO_NONALERT);
1143 if (!NT_SUCCESS(Status))
1144 {
1145 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1146 return(Status);
1147 }
1148
1149 FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE);
1150 Status = NtWriteFile(FileHandle,
1151 NULL,
1152 NULL,
1153 NULL,
1154 &IoStatusBlock,
1155 (NewBootSector + SECTORSIZE),
1156 SECTORSIZE,
1157 &FileOffset,
1158 NULL);
1159 if (!NT_SUCCESS(Status))
1160 {
1161 }
1162 NtClose(FileHandle);
1163
1164 /* Free the new boot sector */
1165 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1166
1167 return(Status);
1168 }
1169
1170
1171 NTSTATUS
1172 InstallMbrBootCodeToDisk (PWSTR SrcPath,
1173 PWSTR RootPath)
1174 {
1175 OBJECT_ATTRIBUTES ObjectAttributes;
1176 IO_STATUS_BLOCK IoStatusBlock;
1177 UNICODE_STRING Name;
1178 HANDLE FileHandle;
1179 NTSTATUS Status;
1180 PPARTITION_SECTOR OrigBootSector;
1181 PPARTITION_SECTOR NewBootSector;
1182
1183 /* Allocate buffer for original bootsector */
1184 OrigBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap,
1185 0,
1186 sizeof(PARTITION_SECTOR));
1187 if (OrigBootSector == NULL)
1188 return(STATUS_INSUFFICIENT_RESOURCES);
1189
1190 /* Read current boot sector into buffer */
1191 RtlInitUnicodeString(&Name,
1192 RootPath);
1193
1194 InitializeObjectAttributes(&ObjectAttributes,
1195 &Name,
1196 OBJ_CASE_INSENSITIVE,
1197 NULL,
1198 NULL);
1199
1200 Status = NtOpenFile(&FileHandle,
1201 GENERIC_READ,
1202 &ObjectAttributes,
1203 &IoStatusBlock,
1204 0,
1205 FILE_SYNCHRONOUS_IO_NONALERT);
1206 if (!NT_SUCCESS(Status))
1207 {
1208 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1209 return(Status);
1210 }
1211
1212 Status = NtReadFile(FileHandle,
1213 NULL,
1214 NULL,
1215 NULL,
1216 &IoStatusBlock,
1217 OrigBootSector,
1218 SECTORSIZE,
1219 NULL,
1220 NULL);
1221 NtClose(FileHandle);
1222 if (!NT_SUCCESS(Status))
1223 {
1224 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1225 return(Status);
1226 }
1227
1228
1229 /* Allocate buffer for new bootsector */
1230 NewBootSector = (PPARTITION_SECTOR)RtlAllocateHeap(ProcessHeap,
1231 0,
1232 sizeof(PARTITION_SECTOR));
1233 if (NewBootSector == NULL)
1234 {
1235 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1236 return(STATUS_INSUFFICIENT_RESOURCES);
1237 }
1238
1239 /* Read new bootsector from SrcPath */
1240 RtlInitUnicodeString(&Name,
1241 SrcPath);
1242
1243 InitializeObjectAttributes(&ObjectAttributes,
1244 &Name,
1245 OBJ_CASE_INSENSITIVE,
1246 NULL,
1247 NULL);
1248
1249 Status = NtOpenFile(&FileHandle,
1250 GENERIC_READ,
1251 &ObjectAttributes,
1252 &IoStatusBlock,
1253 0,
1254 FILE_SYNCHRONOUS_IO_NONALERT);
1255 if (!NT_SUCCESS(Status))
1256 {
1257 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1258 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1259 return(Status);
1260 }
1261
1262 Status = NtReadFile(FileHandle,
1263 NULL,
1264 NULL,
1265 NULL,
1266 &IoStatusBlock,
1267 NewBootSector,
1268 sizeof(PARTITION_SECTOR),
1269 NULL,
1270 NULL);
1271 NtClose(FileHandle);
1272 if (!NT_SUCCESS(Status))
1273 {
1274 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1275 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1276 return(Status);
1277 }
1278
1279 /* Copy partition table from old MBR to new */
1280 RtlCopyMemory (&NewBootSector->Signature,
1281 &OrigBootSector->Signature,
1282 sizeof(PARTITION_SECTOR) - offsetof(PARTITION_SECTOR, Signature) /* Length of partition table */);
1283
1284 /* Free the original boot sector */
1285 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1286
1287 /* Write new bootsector to RootPath */
1288 RtlInitUnicodeString(&Name,
1289 RootPath);
1290
1291 InitializeObjectAttributes(&ObjectAttributes,
1292 &Name,
1293 0,
1294 NULL,
1295 NULL);
1296
1297 Status = NtOpenFile(&FileHandle,
1298 GENERIC_WRITE,
1299 &ObjectAttributes,
1300 &IoStatusBlock,
1301 0,
1302 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY);
1303 if (!NT_SUCCESS(Status))
1304 {
1305 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1306 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1307 return(Status);
1308 }
1309
1310 Status = NtWriteFile(FileHandle,
1311 NULL,
1312 NULL,
1313 NULL,
1314 &IoStatusBlock,
1315 NewBootSector,
1316 SECTORSIZE,
1317 NULL,
1318 NULL);
1319 NtClose(FileHandle);
1320
1321 /* Free the new boot sector */
1322 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1323
1324 return(Status);
1325 }
1326
1327
1328 NTSTATUS
1329 InstallFat16BootCodeToDisk(PWSTR SrcPath,
1330 PWSTR RootPath)
1331 {
1332 OBJECT_ATTRIBUTES ObjectAttributes;
1333 IO_STATUS_BLOCK IoStatusBlock;
1334 UNICODE_STRING Name;
1335 HANDLE FileHandle;
1336 NTSTATUS Status;
1337 PUCHAR OrigBootSector;
1338 PUCHAR NewBootSector;
1339
1340 /* Allocate buffer for original bootsector */
1341 OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
1342 0,
1343 SECTORSIZE);
1344 if (OrigBootSector == NULL)
1345 return(STATUS_INSUFFICIENT_RESOURCES);
1346
1347 /* Read current boot sector into buffer */
1348 RtlInitUnicodeString(&Name,
1349 RootPath);
1350
1351 InitializeObjectAttributes(&ObjectAttributes,
1352 &Name,
1353 OBJ_CASE_INSENSITIVE,
1354 NULL,
1355 NULL);
1356
1357 Status = NtOpenFile(&FileHandle,
1358 GENERIC_READ,
1359 &ObjectAttributes,
1360 &IoStatusBlock,
1361 0,
1362 FILE_SYNCHRONOUS_IO_NONALERT);
1363 if (!NT_SUCCESS(Status))
1364 {
1365 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1366 return(Status);
1367 }
1368
1369 Status = NtReadFile(FileHandle,
1370 NULL,
1371 NULL,
1372 NULL,
1373 &IoStatusBlock,
1374 OrigBootSector,
1375 SECTORSIZE,
1376 NULL,
1377 NULL);
1378 NtClose(FileHandle);
1379 if (!NT_SUCCESS(Status))
1380 {
1381 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1382 return(Status);
1383 }
1384
1385
1386 /* Allocate buffer for new bootsector */
1387 NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
1388 0,
1389 SECTORSIZE);
1390 if (NewBootSector == NULL)
1391 {
1392 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1393 return(STATUS_INSUFFICIENT_RESOURCES);
1394 }
1395
1396 /* Read new bootsector from SrcPath */
1397 RtlInitUnicodeString(&Name,
1398 SrcPath);
1399
1400 InitializeObjectAttributes(&ObjectAttributes,
1401 &Name,
1402 OBJ_CASE_INSENSITIVE,
1403 NULL,
1404 NULL);
1405
1406 Status = NtOpenFile(&FileHandle,
1407 GENERIC_READ,
1408 &ObjectAttributes,
1409 &IoStatusBlock,
1410 0,
1411 FILE_SYNCHRONOUS_IO_NONALERT);
1412 if (!NT_SUCCESS(Status))
1413 {
1414 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1415 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1416 return(Status);
1417 }
1418
1419 Status = NtReadFile(FileHandle,
1420 NULL,
1421 NULL,
1422 NULL,
1423 &IoStatusBlock,
1424 NewBootSector,
1425 SECTORSIZE,
1426 NULL,
1427 NULL);
1428 NtClose(FileHandle);
1429 if (!NT_SUCCESS(Status))
1430 {
1431 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1432 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1433 return(Status);
1434 }
1435
1436 /* Adjust bootsector (copy a part of the FAT16 BPB) */
1437 memcpy((NewBootSector + 3),
1438 (OrigBootSector + 3),
1439 59); /* FAT16 BPB length*/
1440
1441 /* Free the original boot sector */
1442 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1443
1444 /* Write new bootsector to RootPath */
1445 RtlInitUnicodeString(&Name,
1446 RootPath);
1447
1448 InitializeObjectAttributes(&ObjectAttributes,
1449 &Name,
1450 0,
1451 NULL,
1452 NULL);
1453
1454 Status = NtOpenFile(&FileHandle,
1455 GENERIC_WRITE,
1456 &ObjectAttributes,
1457 &IoStatusBlock,
1458 0,
1459 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY);
1460 if (!NT_SUCCESS(Status))
1461 {
1462 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1463 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1464 return(Status);
1465 }
1466
1467 #if 0
1468 FilePosition.QuadPart = 0;
1469 #endif
1470 Status = NtWriteFile(FileHandle,
1471 NULL,
1472 NULL,
1473 NULL,
1474 &IoStatusBlock,
1475 NewBootSector,
1476 SECTORSIZE,
1477 NULL,
1478 NULL);
1479 NtClose(FileHandle);
1480
1481 /* Free the new boot sector */
1482 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1483
1484 return(Status);
1485 }
1486
1487
1488 NTSTATUS
1489 InstallFat32BootCodeToDisk(PWSTR SrcPath,
1490 PWSTR RootPath)
1491 {
1492 OBJECT_ATTRIBUTES ObjectAttributes;
1493 IO_STATUS_BLOCK IoStatusBlock;
1494 UNICODE_STRING Name;
1495 HANDLE FileHandle;
1496 NTSTATUS Status;
1497 PUCHAR OrigBootSector;
1498 PUCHAR NewBootSector;
1499 LARGE_INTEGER FileOffset;
1500 USHORT BackupBootSector;
1501
1502 /* Allocate buffer for original bootsector */
1503 OrigBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
1504 0,
1505 SECTORSIZE);
1506 if (OrigBootSector == NULL)
1507 return(STATUS_INSUFFICIENT_RESOURCES);
1508
1509 /* Read current boot sector into buffer */
1510 RtlInitUnicodeString(&Name,
1511 RootPath);
1512
1513 InitializeObjectAttributes(&ObjectAttributes,
1514 &Name,
1515 OBJ_CASE_INSENSITIVE,
1516 NULL,
1517 NULL);
1518
1519 Status = NtOpenFile(&FileHandle,
1520 GENERIC_READ,
1521 &ObjectAttributes,
1522 &IoStatusBlock,
1523 0,
1524 FILE_SYNCHRONOUS_IO_NONALERT);
1525 if (!NT_SUCCESS(Status))
1526 {
1527 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1528 return(Status);
1529 }
1530
1531 Status = NtReadFile(FileHandle,
1532 NULL,
1533 NULL,
1534 NULL,
1535 &IoStatusBlock,
1536 OrigBootSector,
1537 SECTORSIZE,
1538 NULL,
1539 NULL);
1540 NtClose(FileHandle);
1541 if (!NT_SUCCESS(Status))
1542 {
1543 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1544 return(Status);
1545 }
1546
1547
1548 /* Allocate buffer for new bootsector (2 sectors) */
1549 NewBootSector = (PUCHAR)RtlAllocateHeap(ProcessHeap,
1550 0,
1551 2 * SECTORSIZE);
1552 if (NewBootSector == NULL)
1553 {
1554 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1555 return(STATUS_INSUFFICIENT_RESOURCES);
1556 }
1557
1558 /* Read new bootsector from SrcPath */
1559 RtlInitUnicodeString(&Name,
1560 SrcPath);
1561
1562 InitializeObjectAttributes(&ObjectAttributes,
1563 &Name,
1564 OBJ_CASE_INSENSITIVE,
1565 NULL,
1566 NULL);
1567
1568 Status = NtOpenFile(&FileHandle,
1569 GENERIC_READ,
1570 &ObjectAttributes,
1571 &IoStatusBlock,
1572 0,
1573 FILE_SYNCHRONOUS_IO_NONALERT);
1574 if (!NT_SUCCESS(Status))
1575 {
1576 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1577 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1578 return(Status);
1579 }
1580
1581 Status = NtReadFile(FileHandle,
1582 NULL,
1583 NULL,
1584 NULL,
1585 &IoStatusBlock,
1586 NewBootSector,
1587 2 * SECTORSIZE,
1588 NULL,
1589 NULL);
1590 NtClose(FileHandle);
1591 if (!NT_SUCCESS(Status))
1592 {
1593 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1594 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1595 return(Status);
1596 }
1597
1598 /* Adjust bootsector (copy a part of the FAT32 BPB) */
1599 memcpy((NewBootSector + 3),
1600 (OrigBootSector + 3),
1601 87); /* FAT32 BPB length */
1602
1603 /* Get the location of the backup boot sector */
1604 BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x32];
1605
1606 /* Free the original boot sector */
1607 RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
1608
1609 /* Write the first sector of the new bootcode to DstPath */
1610 RtlInitUnicodeString(&Name,
1611 RootPath);
1612
1613 InitializeObjectAttributes(&ObjectAttributes,
1614 &Name,
1615 0,
1616 NULL,
1617 NULL);
1618
1619 Status = NtOpenFile(&FileHandle,
1620 GENERIC_WRITE,
1621 &ObjectAttributes,
1622 &IoStatusBlock,
1623 0,
1624 FILE_SYNCHRONOUS_IO_NONALERT | FILE_SEQUENTIAL_ONLY);
1625 if (!NT_SUCCESS(Status))
1626 {
1627 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1628 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1629 return(Status);
1630 }
1631
1632 /* Write sector 0 */
1633 FileOffset.QuadPart = 0ULL;
1634 Status = NtWriteFile(FileHandle,
1635 NULL,
1636 NULL,
1637 NULL,
1638 &IoStatusBlock,
1639 NewBootSector,
1640 SECTORSIZE,
1641 &FileOffset,
1642 NULL);
1643 if (!NT_SUCCESS(Status))
1644 {
1645 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1646 NtClose(FileHandle);
1647 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1648 return(Status);
1649 }
1650
1651 /* Write backup boot sector */
1652 if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
1653 {
1654 FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE);
1655 Status = NtWriteFile(FileHandle,
1656 NULL,
1657 NULL,
1658 NULL,
1659 &IoStatusBlock,
1660 NewBootSector,
1661 SECTORSIZE,
1662 &FileOffset,
1663 NULL);
1664 if (!NT_SUCCESS(Status))
1665 {
1666 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1667 NtClose(FileHandle);
1668 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1669 return(Status);
1670 }
1671 }
1672
1673 /* Write sector 14 */
1674 FileOffset.QuadPart = (ULONGLONG)(14 * SECTORSIZE);
1675 Status = NtWriteFile(FileHandle,
1676 NULL,
1677 NULL,
1678 NULL,
1679 &IoStatusBlock,
1680 (NewBootSector + SECTORSIZE),
1681 SECTORSIZE,
1682 &FileOffset,
1683 NULL);
1684 if (!NT_SUCCESS(Status))
1685 {
1686 DPRINT1("NtWriteFile() failed (Status %lx)\n", Status);
1687 }
1688 NtClose(FileHandle);
1689
1690 /* Free the new boot sector */
1691 RtlFreeHeap(ProcessHeap, 0, NewBootSector);
1692
1693 return(Status);
1694 }
1695
1696
1697 static NTSTATUS
1698 UnprotectBootIni(PWSTR FileName,
1699 PULONG Attributes)
1700 {
1701 UNICODE_STRING Name;
1702 OBJECT_ATTRIBUTES ObjectAttributes;
1703 IO_STATUS_BLOCK IoStatusBlock;
1704 FILE_BASIC_INFORMATION FileInfo;
1705 HANDLE FileHandle;
1706 NTSTATUS Status;
1707
1708 RtlInitUnicodeString(&Name,
1709 FileName);
1710
1711 InitializeObjectAttributes(&ObjectAttributes,
1712 &Name,
1713 OBJ_CASE_INSENSITIVE,
1714 NULL,
1715 NULL);
1716
1717 Status = NtOpenFile(&FileHandle,
1718 GENERIC_READ|GENERIC_WRITE,
1719 &ObjectAttributes,
1720 &IoStatusBlock,
1721 0,
1722 FILE_SYNCHRONOUS_IO_NONALERT);
1723 if (Status == STATUS_NO_SUCH_FILE)
1724 {
1725 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1726 *Attributes = 0;
1727 return(STATUS_SUCCESS);
1728 }
1729 if (!NT_SUCCESS(Status))
1730 {
1731 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1732 return(Status);
1733 }
1734
1735 Status = NtQueryInformationFile(FileHandle,
1736 &IoStatusBlock,
1737 &FileInfo,
1738 sizeof(FILE_BASIC_INFORMATION),
1739 FileBasicInformation);
1740 if (!NT_SUCCESS(Status))
1741 {
1742 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status);
1743 NtClose(FileHandle);
1744 return(Status);
1745 }
1746
1747 *Attributes = FileInfo.FileAttributes;
1748
1749 /* Delete attributes SYSTEM, HIDDEN and READONLY */
1750 FileInfo.FileAttributes = FileInfo.FileAttributes &
1751 ~(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
1752
1753 Status = NtSetInformationFile(FileHandle,
1754 &IoStatusBlock,
1755 &FileInfo,
1756 sizeof(FILE_BASIC_INFORMATION),
1757 FileBasicInformation);
1758 if (!NT_SUCCESS(Status))
1759 {
1760 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status);
1761 }
1762
1763 NtClose(FileHandle);
1764 return(Status);
1765 }
1766
1767
1768 static NTSTATUS
1769 ProtectBootIni(PWSTR FileName,
1770 ULONG Attributes)
1771 {
1772 UNICODE_STRING Name;
1773 OBJECT_ATTRIBUTES ObjectAttributes;
1774 IO_STATUS_BLOCK IoStatusBlock;
1775 FILE_BASIC_INFORMATION FileInfo;
1776 HANDLE FileHandle;
1777 NTSTATUS Status;
1778
1779 RtlInitUnicodeString(&Name,
1780 FileName);
1781
1782 InitializeObjectAttributes(&ObjectAttributes,
1783 &Name,
1784 OBJ_CASE_INSENSITIVE,
1785 NULL,
1786 NULL);
1787
1788 Status = NtOpenFile(&FileHandle,
1789 GENERIC_READ|GENERIC_WRITE,
1790 &ObjectAttributes,
1791 &IoStatusBlock,
1792 0,
1793 FILE_SYNCHRONOUS_IO_NONALERT);
1794 if (!NT_SUCCESS(Status))
1795 {
1796 DPRINT1("NtOpenFile() failed (Status %lx)\n", Status);
1797 return(Status);
1798 }
1799
1800 Status = NtQueryInformationFile(FileHandle,
1801 &IoStatusBlock,
1802 &FileInfo,
1803 sizeof(FILE_BASIC_INFORMATION),
1804 FileBasicInformation);
1805 if (!NT_SUCCESS(Status))
1806 {
1807 DPRINT1("NtQueryInformationFile() failed (Status %lx)\n", Status);
1808 NtClose(FileHandle);
1809 return(Status);
1810 }
1811
1812 FileInfo.FileAttributes = FileInfo.FileAttributes | Attributes;
1813
1814 Status = NtSetInformationFile(FileHandle,
1815 &IoStatusBlock,
1816 &FileInfo,
1817 sizeof(FILE_BASIC_INFORMATION),
1818 FileBasicInformation);
1819 if (!NT_SUCCESS(Status))
1820 {
1821 DPRINT1("NtSetInformationFile() failed (Status %lx)\n", Status);
1822 }
1823
1824 NtClose(FileHandle);
1825 return(Status);
1826 }
1827
1828
1829 NTSTATUS
1830 UpdateBootIni(PWSTR BootIniPath,
1831 PWSTR EntryName,
1832 PWSTR EntryValue)
1833 {
1834 UNICODE_STRING Name;
1835 PINICACHE Cache = NULL;
1836 PINICACHESECTION Section = NULL;
1837 NTSTATUS Status;
1838 ULONG FileAttribute;
1839 PWCHAR OldValue = NULL;
1840
1841 RtlInitUnicodeString(&Name,
1842 BootIniPath);
1843
1844 Status = IniCacheLoad(&Cache,
1845 &Name,
1846 FALSE);
1847 if (!NT_SUCCESS(Status))
1848 {
1849 return(Status);
1850 }
1851
1852 Section = IniCacheGetSection(Cache,
1853 L"operating systems");
1854 if (Section == NULL)
1855 {
1856 IniCacheDestroy(Cache);
1857 return(STATUS_UNSUCCESSFUL);
1858 }
1859
1860 /* Check - maybe record already exists */
1861 Status = IniCacheGetKey(Section,
1862 EntryName,
1863 &OldValue);
1864
1865 /* If either key was not found, or contains something else - add new one */
1866 if (!NT_SUCCESS(Status) || wcscmp(OldValue, EntryValue))
1867 {
1868 IniCacheInsertKey(Section,
1869 NULL,
1870 INSERT_LAST,
1871 EntryName,
1872 EntryValue);
1873 }
1874
1875 Status = UnprotectBootIni(BootIniPath,
1876 &FileAttribute);
1877 if (!NT_SUCCESS(Status))
1878 {
1879 IniCacheDestroy(Cache);
1880 return(Status);
1881 }
1882
1883 Status = IniCacheSave(Cache,
1884 BootIniPath);
1885 if (!NT_SUCCESS(Status))
1886 {
1887 IniCacheDestroy(Cache);
1888 return(Status);
1889 }
1890
1891 FileAttribute |= (FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY);
1892 Status = ProtectBootIni(BootIniPath,
1893 FileAttribute);
1894
1895 IniCacheDestroy(Cache);
1896
1897 return(Status);
1898 }
1899
1900 BOOLEAN
1901 CheckInstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath)
1902 {
1903 #ifdef __REACTOS__
1904 if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") ||
1905 DoesFileExist(SystemRootPath->Buffer, L"boot.ini"))
1906 {
1907 return TRUE;
1908 }
1909 else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") ||
1910 DoesFileExist(SystemRootPath->Buffer, L"msdos.sys"))
1911 {
1912 return TRUE;
1913 }
1914 #endif
1915
1916 return FALSE;
1917 }
1918
1919
1920 NTSTATUS
1921 InstallFatBootcodeToPartition(PUNICODE_STRING SystemRootPath,
1922 PUNICODE_STRING SourceRootPath,
1923 PUNICODE_STRING DestinationArcPath,
1924 UCHAR PartitionType)
1925 {
1926 #ifdef __REACTOS__
1927 WCHAR SrcPath[MAX_PATH];
1928 WCHAR DstPath[MAX_PATH];
1929 NTSTATUS Status;
1930
1931 /* FAT or FAT32 partition */
1932 DPRINT("System path: '%wZ'\n", SystemRootPath);
1933
1934 if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") == TRUE ||
1935 DoesFileExist(SystemRootPath->Buffer, L"boot.ini") == TRUE)
1936 {
1937 /* Search root directory for 'ntldr' and 'boot.ini'. */
1938 DPRINT("Found Microsoft Windows NT/2000/XP boot loader\n");
1939
1940 /* Copy FreeLoader to the boot partition */
1941 wcscpy(SrcPath, SourceRootPath->Buffer);
1942 wcscat(SrcPath, L"\\loader\\freeldr.sys");
1943 wcscpy(DstPath, SystemRootPath->Buffer);
1944 wcscat(DstPath, L"\\freeldr.sys");
1945
1946 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
1947 Status = SetupCopyFile(SrcPath, DstPath);
1948 if (!NT_SUCCESS(Status))
1949 {
1950 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
1951 return Status;
1952 }
1953
1954 /* Create or update freeldr.ini */
1955 if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE)
1956 {
1957 /* Create new 'freeldr.ini' */
1958 DPRINT1("Create new 'freeldr.ini'\n");
1959 wcscpy(DstPath, SystemRootPath->Buffer);
1960 wcscat(DstPath, L"\\freeldr.ini");
1961
1962 Status = CreateFreeLoaderIniForReactos(DstPath,
1963 DestinationArcPath->Buffer);
1964 if (!NT_SUCCESS(Status))
1965 {
1966 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
1967 return Status;
1968 }
1969
1970 /* Install new bootcode */
1971 if (PartitionType == PARTITION_FAT32 ||
1972 PartitionType == PARTITION_FAT32_XINT13)
1973 {
1974 /* Install FAT32 bootcode */
1975 wcscpy(SrcPath, SourceRootPath->Buffer);
1976 wcscat(SrcPath, L"\\loader\\fat32.bin");
1977 wcscpy(DstPath, SystemRootPath->Buffer);
1978 wcscat(DstPath, L"\\bootsect.ros");
1979
1980 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, DstPath);
1981 Status = InstallFat32BootCodeToFile(SrcPath,
1982 DstPath,
1983 SystemRootPath->Buffer);
1984 if (!NT_SUCCESS(Status))
1985 {
1986 DPRINT1("InstallFat32BootCodeToFile() failed (Status %lx)\n", Status);
1987 return Status;
1988 }
1989 }
1990 else
1991 {
1992 /* Install FAT16 bootcode */
1993 wcscpy(SrcPath, SourceRootPath->Buffer);
1994 wcscat(SrcPath, L"\\loader\\fat.bin");
1995 wcscpy(DstPath, SystemRootPath->Buffer);
1996 wcscat(DstPath, L"\\bootsect.ros");
1997
1998 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
1999 Status = InstallFat16BootCodeToFile(SrcPath,
2000 DstPath,
2001 SystemRootPath->Buffer);
2002 if (!NT_SUCCESS(Status))
2003 {
2004 DPRINT1("InstallFat16BootCodeToFile() failed (Status %lx)\n", Status);
2005 return Status;
2006 }
2007 }
2008 }
2009 else
2010 {
2011 /* Update existing 'freeldr.ini' */
2012 DPRINT1("Update existing 'freeldr.ini'\n");
2013 wcscpy(DstPath, SystemRootPath->Buffer);
2014 wcscat(DstPath, L"\\freeldr.ini");
2015
2016 Status = UpdateFreeLoaderIni(DstPath,
2017 DestinationArcPath->Buffer);
2018 if (!NT_SUCCESS(Status))
2019 {
2020 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
2021 return Status;
2022 }
2023 }
2024
2025 /* Update 'boot.ini' */
2026 wcscpy(DstPath, SystemRootPath->Buffer);
2027 wcscat(DstPath, L"\\boot.ini");
2028
2029 DPRINT1("Update 'boot.ini': %S\n", DstPath);
2030 Status = UpdateBootIni(DstPath,
2031 L"C:\\bootsect.ros",
2032 L"\"ReactOS\"");
2033 if (!NT_SUCCESS(Status))
2034 {
2035 DPRINT1("UpdateBootIni() failed (Status %lx)\n", Status);
2036 return Status;
2037 }
2038 }
2039 else if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") == TRUE ||
2040 DoesFileExist(SystemRootPath->Buffer, L"msdos.sys") == TRUE)
2041 {
2042 /* Search for root directory for 'io.sys' and 'msdos.sys'. */
2043 DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
2044
2045 /* Copy FreeLoader to the boot partition */
2046 wcscpy(SrcPath, SourceRootPath->Buffer);
2047 wcscat(SrcPath, L"\\loader\\freeldr.sys");
2048 wcscpy(DstPath, SystemRootPath->Buffer);
2049 wcscat(DstPath, L"\\freeldr.sys");
2050
2051 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
2052 Status = SetupCopyFile(SrcPath, DstPath);
2053 if (!NT_SUCCESS(Status))
2054 {
2055 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
2056 return Status;
2057 }
2058
2059 /* Create or update 'freeldr.ini' */
2060 if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE)
2061 {
2062 /* Create new 'freeldr.ini' */
2063 DPRINT1("Create new 'freeldr.ini'\n");
2064 wcscpy(DstPath, SystemRootPath->Buffer);
2065 wcscat(DstPath, L"\\freeldr.ini");
2066
2067 Status = CreateFreeLoaderIniForDos(DstPath,
2068 DestinationArcPath->Buffer);
2069 if (!NT_SUCCESS(Status))
2070 {
2071 DPRINT1("CreateFreeLoaderIniForDos() failed (Status %lx)\n", Status);
2072 return Status;
2073 }
2074
2075 /* Save current bootsector as 'BOOTSECT.DOS' */
2076 wcscpy(SrcPath, SystemRootPath->Buffer);
2077 wcscpy(DstPath, SystemRootPath->Buffer);
2078 wcscat(DstPath, L"\\bootsect.dos");
2079
2080 DPRINT1("Save bootsector: %S ==> %S\n", SrcPath, DstPath);
2081 Status = SaveCurrentBootSector(SrcPath,
2082 DstPath);
2083 if (!NT_SUCCESS(Status))
2084 {
2085 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
2086 return Status;
2087 }
2088
2089 /* Install new bootsector */
2090 if (PartitionType == PARTITION_FAT32 ||
2091 PartitionType == PARTITION_FAT32_XINT13)
2092 {
2093 wcscpy(SrcPath, SourceRootPath->Buffer);
2094 wcscat(SrcPath, L"\\loader\\fat32.bin");
2095
2096 DPRINT1("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
2097 Status = InstallFat32BootCodeToDisk(SrcPath,
2098 SystemRootPath->Buffer);
2099 if (!NT_SUCCESS(Status))
2100 {
2101 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status);
2102 return Status;
2103 }
2104 }
2105 else
2106 {
2107 wcscpy(SrcPath, SourceRootPath->Buffer);
2108 wcscat(SrcPath, L"\\loader\\fat.bin");
2109
2110 DPRINT1("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
2111 Status = InstallFat16BootCodeToDisk(SrcPath,
2112 SystemRootPath->Buffer);
2113 if (!NT_SUCCESS(Status))
2114 {
2115 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
2116 return Status;
2117 }
2118 }
2119 }
2120 else
2121 {
2122 /* Update existing 'freeldr.ini' */
2123 wcscpy(DstPath, SystemRootPath->Buffer);
2124 wcscat(DstPath, L"\\freeldr.ini");
2125
2126 Status = UpdateFreeLoaderIni(DstPath,
2127 DestinationArcPath->Buffer);
2128 if (!NT_SUCCESS(Status))
2129 {
2130 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
2131 return Status;
2132 }
2133 }
2134 }
2135 else
2136 {
2137 /* No or unknown boot loader */
2138 DPRINT1("No or unknown boot loader found\n");
2139
2140 /* Copy FreeLoader to the boot partition */
2141 wcscpy(SrcPath, SourceRootPath->Buffer);
2142 wcscat(SrcPath, L"\\loader\\freeldr.sys");
2143 wcscpy(DstPath, SystemRootPath->Buffer);
2144 wcscat(DstPath, L"\\freeldr.sys");
2145
2146 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
2147 Status = SetupCopyFile(SrcPath, DstPath);
2148 if (!NT_SUCCESS(Status))
2149 {
2150 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
2151 return Status;
2152 }
2153
2154 /* Create or update 'freeldr.ini' */
2155 if (DoesFileExist(SystemRootPath->Buffer, L"freeldr.ini") == FALSE)
2156 {
2157 /* Create new freeldr.ini */
2158 wcscpy(DstPath, SystemRootPath->Buffer);
2159 wcscat(DstPath, L"\\freeldr.ini");
2160
2161 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
2162 Status = CreateFreeLoaderIniForReactos(DstPath,
2163 DestinationArcPath->Buffer);
2164 if (!NT_SUCCESS(Status))
2165 {
2166 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
2167 return Status;
2168 }
2169
2170 /* Save current bootsector as 'BOOTSECT.OLD' */
2171 wcscpy(SrcPath, SystemRootPath->Buffer);
2172 wcscpy(DstPath, SystemRootPath->Buffer);
2173 wcscat(DstPath, L"\\bootsect.old");
2174
2175 DPRINT("Save bootsector: %S ==> %S\n", SrcPath, DstPath);
2176 Status = SaveCurrentBootSector(SrcPath,
2177 DstPath);
2178 if (!NT_SUCCESS(Status))
2179 {
2180 DPRINT1("SaveCurrentBootSector() failed (Status %lx)\n", Status);
2181 return Status;
2182 }
2183
2184 /* Install new bootsector */
2185 if (PartitionType == PARTITION_FAT32 ||
2186 PartitionType == PARTITION_FAT32_XINT13)
2187 {
2188 wcscpy(SrcPath, SourceRootPath->Buffer);
2189 wcscat(SrcPath, L"\\loader\\fat32.bin");
2190
2191 DPRINT("Install FAT32 bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
2192 Status = InstallFat32BootCodeToDisk(SrcPath,
2193 SystemRootPath->Buffer);
2194 if (!NT_SUCCESS(Status))
2195 {
2196 DPRINT1("InstallFat32BootCodeToDisk() failed (Status %lx)\n", Status);
2197 return Status;
2198 }
2199 }
2200 else
2201 {
2202 wcscpy(SrcPath, SourceRootPath->Buffer);
2203 wcscat(SrcPath, L"\\loader\\fat.bin");
2204
2205 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, SystemRootPath->Buffer);
2206 Status = InstallFat16BootCodeToDisk(SrcPath,
2207 SystemRootPath->Buffer);
2208 if (!NT_SUCCESS(Status))
2209 {
2210 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
2211 return Status;
2212 }
2213 }
2214 }
2215 else
2216 {
2217 /* Update existing 'freeldr.ini' */
2218 wcscpy(DstPath, SystemRootPath->Buffer);
2219 wcscat(DstPath, L"\\freeldr.ini");
2220
2221 Status = UpdateFreeLoaderIni(DstPath,
2222 DestinationArcPath->Buffer);
2223 if (!NT_SUCCESS(Status))
2224 {
2225 DPRINT1("UpdateFreeLoaderIni() failed (Status %lx)\n", Status);
2226 return Status;
2227 }
2228 }
2229 }
2230
2231 return STATUS_SUCCESS;
2232 #else
2233 return STATUS_NOT_IMPLEMENTED;
2234 #endif
2235 }
2236
2237
2238 NTSTATUS
2239 InstallFatBootcodeToFloppy(PUNICODE_STRING SourceRootPath,
2240 PUNICODE_STRING DestinationArcPath)
2241 {
2242 #ifdef __REACTOS__
2243 WCHAR SrcPath[MAX_PATH];
2244 WCHAR DstPath[MAX_PATH];
2245 NTSTATUS Status;
2246
2247 /* Copy FreeLoader to the boot partition */
2248 wcscpy(SrcPath, SourceRootPath->Buffer);
2249 wcscat(SrcPath, L"\\loader\\freeldr.sys");
2250
2251 wcscpy(DstPath, L"\\Device\\Floppy0\\freeldr.sys");
2252
2253 DPRINT("Copy: %S ==> %S\n", SrcPath, DstPath);
2254 Status = SetupCopyFile(SrcPath, DstPath);
2255 if (!NT_SUCCESS(Status))
2256 {
2257 DPRINT1("SetupCopyFile() failed (Status %lx)\n", Status);
2258 return Status;
2259 }
2260
2261 /* Create new 'freeldr.ini' */
2262 wcscpy(DstPath, L"\\Device\\Floppy0\\freeldr.ini");
2263
2264 DPRINT("Create new 'freeldr.ini'\n");
2265 Status = CreateFreeLoaderIniForReactos(DstPath,
2266 DestinationArcPath->Buffer);
2267 if (!NT_SUCCESS(Status))
2268 {
2269 DPRINT1("CreateFreeLoaderIniForReactos() failed (Status %lx)\n", Status);
2270 return Status;
2271 }
2272
2273 /* Install FAT12/16 boosector */
2274 wcscpy(SrcPath, SourceRootPath->Buffer);
2275 wcscat(SrcPath, L"\\loader\\fat.bin");
2276
2277 wcscpy(DstPath, L"\\Device\\Floppy0");
2278
2279 DPRINT("Install FAT bootcode: %S ==> %S\n", SrcPath, DstPath);
2280 Status = InstallFat16BootCodeToDisk(SrcPath,
2281 DstPath);
2282 if (!NT_SUCCESS(Status))
2283 {
2284 DPRINT1("InstallFat16BootCodeToDisk() failed (Status %lx)\n", Status);
2285 return Status;
2286 }
2287
2288 return STATUS_SUCCESS;
2289 #else
2290 return STATUS_NOT_IMPLEMENTED;
2291 #endif
2292 }
2293
2294 /* EOF */