Rev 6468 | Rev 6828 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6468 | Rev 6827 | ||
---|---|---|---|
Line 3... | Line 3... | ||
3 | ;; Copyright (C) KolibriOS team 2011-2015. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2011-2015. All rights reserved. ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
4 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; ;; |
5 | ;; ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 7... | Line 7... | ||
7 | 7 | ||
Line 8... | Line 8... | ||
8 | $Revision: 6468 $ |
8 | $Revision: 6827 $ |
9 | 9 | ||
10 | ; ============================================================================= |
10 | ; ============================================================================= |
11 | ; ================================= Constants ================================= |
11 | ; ================================= Constants ================================= |
Line 214... | Line 214... | ||
214 | ; Coordinate of first sector in LBA. |
214 | ; Coordinate of first sector in LBA. |
215 | Length dd ? |
215 | Length dd ? |
216 | ; Length of the partition in sectors. |
216 | ; Length of the partition in sectors. |
217 | ends |
217 | ends |
Line -... | Line 218... | ||
- | 218 | ||
- | 219 | ; GUID Partition Table Header, UEFI 2.6, Table 18 |
|
- | 220 | struct GPTH |
|
- | 221 | Signature rb 8 |
|
- | 222 | ; 'EFI PART' |
|
- | 223 | Revision dd ? |
|
- | 224 | ; 0x00010000 |
|
- | 225 | HeaderSize dd ? |
|
- | 226 | ; Size of this header in bytes, must fit to one sector. |
|
- | 227 | HeaderCRC32 dd ? |
|
- | 228 | ; Set this field to zero, compute CRC32 via 0xEDB88320, compare. |
|
- | 229 | Reserved dd ? |
|
- | 230 | ; Myst be zero. |
|
- | 231 | MyLBA dq ? |
|
- | 232 | ; LBA of the sector containing this GPT header. |
|
- | 233 | AlternateLBA dq ? |
|
- | 234 | ; LBA of the sector containing the other GPT header. |
|
- | 235 | ; AlternateLBA of Primary GPTH points to Backup one and vice versa. |
|
- | 236 | FirstUsableLBA dq ? |
|
- | 237 | ; Only sectors between first and last UsableLBA may form partitions |
|
- | 238 | LastUsableLBA dq ? |
|
- | 239 | DiskGUID rb 16 |
|
- | 240 | ; Globally Unique IDentifier |
|
- | 241 | PartitionEntryLBA dq ? |
|
- | 242 | ; First LBA of Partition Entry Array. |
|
- | 243 | ; Length in bytes is computed as a product of two following fields. |
|
- | 244 | NumberOfPartitionEntries dd ? |
|
- | 245 | ; Actual number of partitions depends on the contents of Partition Entry Array. |
|
- | 246 | ; A partition entry is unused if zeroed. |
|
- | 247 | SizeOfPartitionEntry dd ? ; in bytes |
|
- | 248 | PartitionEntryArrayCRC32 dd ? |
|
- | 249 | ; Same CRC as for GPT header. |
|
- | 250 | ends |
|
- | 251 | ||
- | 252 | ; GPT Partition Entry, UEFI 2.6, Table 19 |
|
- | 253 | struct GPE |
|
- | 254 | PartitionTypeGUID rb 16 |
|
- | 255 | UniquePartitionGUID rb 16 |
|
- | 256 | StartingLBA dq ? |
|
- | 257 | EndingLBA dq ? |
|
- | 258 | ; Length in sectors is EndingLBA - StartingLBA + 1. |
|
- | 259 | Attributes dq ? |
|
- | 260 | PartitionName rb 72 |
|
- | 261 | ends |
|
218 | 262 | ||
219 | ; ============================================================================= |
263 | ; ============================================================================= |
220 | ; ================================ Global data ================================ |
264 | ; ================================ Global data ================================ |
221 | ; ============================================================================= |
265 | ; ============================================================================= |
222 | iglobal |
266 | iglobal |
Line 665... | Line 709... | ||
665 | push ebp ; save ebp |
709 | push ebp ; save ebp |
666 | push MAX_NUM_PARTITIONS ; the counter of max MBRs to process |
710 | push MAX_NUM_PARTITIONS ; the counter of max MBRs to process |
667 | xor ebp, ebp ; start from sector zero |
711 | xor ebp, ebp ; start from sector zero |
668 | push ebp ; no extended partition yet |
712 | push ebp ; no extended partition yet |
669 | ; 4. MBR is 512 bytes long. If sector size is less than 512 bytes, |
713 | ; 4. MBR is 512 bytes long. If sector size is less than 512 bytes, |
670 | ; assume no MBR, no partitions and go to 10. |
714 | ; assume no MBR, no partitions and go to 11. |
671 | cmp [esi+DISK.MediaInfo.SectorSize], 512 |
715 | cmp [esi+DISK.MediaInfo.SectorSize], 512 |
672 | jb .notmbr |
716 | jb .notmbr |
673 | .new_mbr: |
717 | .new_mbr: |
674 | ; 5. Read the current sector. |
718 | ; 5. Read the current sector. |
675 | ; Note that 'read' callback operates with 64-bit sector numbers, so we must |
719 | ; Note that 'read' callback operates with 64-bit sector numbers, so we must |
Line 687... | Line 731... | ||
687 | ; [ecx+0x40] is shorter than [ebx+0x1fe]: one-byte offset vs 4-bytes offset. |
731 | ; [ecx+0x40] is shorter than [ebx+0x1fe]: one-byte offset vs 4-bytes offset. |
688 | lea ecx, [ebx+0x1be] ; ecx -> partition table |
732 | lea ecx, [ebx+0x1be] ; ecx -> partition table |
689 | cmp word [ecx+0x40], 0xaa55 |
733 | cmp word [ecx+0x40], 0xaa55 |
690 | jnz .mbr_failed |
734 | jnz .mbr_failed |
691 | ; 8. The MBR is treated differently from EBRs. For MBR we additionally need to |
735 | ; 8. The MBR is treated differently from EBRs. For MBR we additionally need to |
692 | ; execute step 9 and possibly step 10. |
736 | ; execute step 10 and possibly step 11. |
693 | test ebp, ebp |
737 | test ebp, ebp |
694 | jnz .mbr |
738 | jnz .mbr |
- | 739 | ; 9. Handle GUID Partition Table |
|
- | 740 | ; 9a. Check if MBR is protective |
|
- | 741 | call is_protective_mbr |
|
- | 742 | jnz .no_gpt |
|
- | 743 | ; 9b. If so, try to scan GPT headers |
|
- | 744 | call disk_scan_gpt |
|
- | 745 | ; 9c. If any GPT header is valid, ignore MBR |
|
- | 746 | jz .done |
|
- | 747 | ; Otherwise process legacy/protective MBR |
|
- | 748 | .no_gpt: |
|
695 | ; The partition table can be present or not present. In the first case, we just |
749 | ; The partition table can be present or not present. In the first case, we just |
696 | ; read the MBR. In the second case, we just read the bootsector for a |
750 | ; read the MBR. In the second case, we just read the bootsector for a |
697 | ; filesystem. |
751 | ; filesystem. |
698 | ; The following algorithm is used to distinguish between these cases. |
752 | ; The following algorithm is used to distinguish between these cases. |
699 | ; A. If at least one entry of the partition table is invalid, this is |
753 | ; A. If at least one entry of the partition table is invalid, this is |
Line 701... | Line 755... | ||
701 | ; definition of validity. |
755 | ; definition of validity. |
702 | ; B. If all entries are empty (filesystem type field is zero) and the first |
756 | ; B. If all entries are empty (filesystem type field is zero) and the first |
703 | ; byte is jmp opcode (0EBh or 0E9h), this is a bootsector which happens to |
757 | ; byte is jmp opcode (0EBh or 0E9h), this is a bootsector which happens to |
704 | ; have zeros in the place of partition table. |
758 | ; have zeros in the place of partition table. |
705 | ; C. Otherwise, this is an MBR. |
759 | ; C. Otherwise, this is an MBR. |
706 | ; 9. Test for MBR vs bootsector. |
760 | ; 10. Test for MBR vs bootsector. |
707 | ; 9a. Check entries. If any is invalid, go to 10 (rule A). |
761 | ; 10a. Check entries. If any is invalid, go to 11 (rule A). |
708 | call is_partition_table_entry |
762 | call is_partition_table_entry |
709 | jc .notmbr |
763 | jc .notmbr |
710 | add ecx, 10h |
764 | add ecx, 10h |
711 | call is_partition_table_entry |
765 | call is_partition_table_entry |
712 | jc .notmbr |
766 | jc .notmbr |
Line 714... | Line 768... | ||
714 | call is_partition_table_entry |
768 | call is_partition_table_entry |
715 | jc .notmbr |
769 | jc .notmbr |
716 | add ecx, 10h |
770 | add ecx, 10h |
717 | call is_partition_table_entry |
771 | call is_partition_table_entry |
718 | jc .notmbr |
772 | jc .notmbr |
719 | ; 9b. Check types of the entries. If at least one is nonzero, go to 11 (rule C). |
773 | ; 10b. Check types of the entries. If at least one is nonzero, go to 12 (rule C). |
720 | mov al, [ecx-30h+PARTITION_TABLE_ENTRY.Type] |
774 | mov al, [ecx-30h+PARTITION_TABLE_ENTRY.Type] |
721 | or al, [ecx-20h+PARTITION_TABLE_ENTRY.Type] |
775 | or al, [ecx-20h+PARTITION_TABLE_ENTRY.Type] |
722 | or al, [ecx-10h+PARTITION_TABLE_ENTRY.Type] |
776 | or al, [ecx-10h+PARTITION_TABLE_ENTRY.Type] |
723 | or al, [ecx+PARTITION_TABLE_ENTRY.Type] |
777 | or al, [ecx+PARTITION_TABLE_ENTRY.Type] |
724 | jnz .mbr |
778 | jnz .mbr |
725 | ; 9c. Empty partition table or bootsector with many zeroes? (rule B) |
779 | ; 10c. Empty partition table or bootsector with many zeroes? (rule B) |
726 | cmp byte [ebx], 0EBh |
780 | cmp byte [ebx], 0EBh |
727 | jz .notmbr |
781 | jz .notmbr |
728 | cmp byte [ebx], 0E9h |
782 | cmp byte [ebx], 0E9h |
729 | jnz .mbr |
783 | jnz .mbr |
730 | .notmbr: |
784 | .notmbr: |
731 | ; 10. This is not an MBR. The media is not partitioned. Create one partition |
785 | ; 11. This is not an MBR. The media is not partitioned. Create one partition |
732 | ; which covers all the media and abort the loop. |
786 | ; which covers all the media and abort the loop. |
733 | stdcall disk_add_partition, 0, 0, \ |
787 | stdcall disk_add_partition, 0, 0, \ |
734 | dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4], esi |
788 | dword [esi+DISK.MediaInfo.Capacity], dword [esi+DISK.MediaInfo.Capacity+4], esi |
735 | jmp .done |
789 | jmp .done |
736 | .mbr: |
790 | .mbr: |
737 | ; 11. Process all entries of the new MBR/EBR |
791 | ; 12. Process all entries of the new MBR/EBR |
738 | lea ecx, [ebx+0x1be] ; ecx -> partition table |
792 | lea ecx, [ebx+0x1be] ; ecx -> partition table |
739 | push 0 ; assume no extended partition |
793 | push 0 ; assume no extended partition |
740 | call process_partition_table_entry |
794 | call process_partition_table_entry |
741 | add ecx, 10h |
795 | add ecx, 10h |
742 | call process_partition_table_entry |
796 | call process_partition_table_entry |
743 | add ecx, 10h |
797 | add ecx, 10h |
744 | call process_partition_table_entry |
798 | call process_partition_table_entry |
745 | add ecx, 10h |
799 | add ecx, 10h |
746 | call process_partition_table_entry |
800 | call process_partition_table_entry |
747 | pop ebp |
801 | pop ebp |
748 | ; 12. Test whether we found a new EBR and should continue the loop. |
802 | ; 13. Test whether we found a new EBR and should continue the loop. |
749 | ; 12a. If there was no next EBR, return. |
803 | ; 13a. If there was no next EBR, return. |
750 | test ebp, ebp |
804 | test ebp, ebp |
751 | jz .done |
805 | jz .done |
752 | ; Ok, we have EBR. |
806 | ; Ok, we have EBR. |
753 | ; 12b. EBRs addresses are relative to the start of extended partition. |
807 | ; 13b. EBRs addresses are relative to the start of extended partition. |
754 | ; For simplicity, just abort if an 32-bit overflow occurs; large disks |
808 | ; For simplicity, just abort if an 32-bit overflow occurs; large disks |
755 | ; are most likely partitioned with GPT, not MBR scheme, since the precise |
809 | ; are most likely partitioned with GPT, not MBR scheme, since the precise |
756 | ; calculation here would increase limit just twice at the price of big |
810 | ; calculation here would increase limit just twice at the price of big |
757 | ; compatibility problems. |
811 | ; compatibility problems. |
758 | pop eax ; load extended partition |
812 | pop eax ; load extended partition |
759 | add ebp, eax |
813 | add ebp, eax |
760 | jc .mbr_failed |
814 | jc .mbr_failed |
761 | ; 12c. If extended partition has not yet started, start it. |
815 | ; 13c. If extended partition has not yet started, start it. |
762 | test eax, eax |
816 | test eax, eax |
763 | jnz @f |
817 | jnz @f |
764 | mov eax, ebp |
818 | mov eax, ebp |
765 | @@: |
819 | @@: |
766 | ; 12c. If the limit is not exceeded, continue the loop. |
820 | ; 13d. If the limit is not exceeded, continue the loop. |
767 | dec dword [esp] |
821 | dec dword [esp] |
768 | push eax ; store extended partition |
822 | push eax ; store extended partition |
769 | jnz .new_mbr |
823 | jnz .new_mbr |
770 | .mbr_failed: |
824 | .mbr_failed: |
771 | .done: |
825 | .done: |
772 | ; 13. Cleanup after the loop. |
826 | ; 14. Cleanup after the loop. |
773 | pop eax ; not important anymore |
827 | pop eax ; not important anymore |
774 | pop eax ; not important anymore |
828 | pop eax ; not important anymore |
775 | pop ebp ; restore ebp |
829 | pop ebp ; restore ebp |
776 | ; 14. Release the buffer. |
830 | ; 15. Release the buffer. |
777 | ; 14a. Test whether it is the global buffer or we have allocated it. |
831 | ; 15a. Test whether it is the global buffer or we have allocated it. |
778 | cmp ebx, mbr_buffer |
832 | cmp ebx, mbr_buffer |
779 | jz .release_partition_buffer |
833 | jz .release_partition_buffer |
780 | ; 14b. If we have allocated it, free it. |
834 | ; 15b. If we have allocated it, free it. |
781 | xchg eax, ebx |
835 | xchg eax, ebx |
782 | call free |
836 | call free |
783 | jmp .nothing |
837 | jmp .nothing |
784 | ; 14c. Otherwise, release reference. |
838 | ; 15c. Otherwise, release reference. |
785 | .release_partition_buffer: |
839 | .release_partition_buffer: |
786 | lock dec [partition_buffer_users] |
840 | lock dec [partition_buffer_users] |
787 | .nothing: |
841 | .nothing: |
788 | ; 15. Return. |
842 | ; 16. Return. |
- | 843 | ret |
|
- | 844 | ||
- | 845 | ||
- | 846 | ; This function is called from disk_scan_partitions to validate and parse |
|
- | 847 | ; primary and backup GPTs. |
|
- | 848 | proc disk_scan_gpt |
|
- | 849 | ; Scan primary GPT (second sector) |
|
- | 850 | stdcall scan_gpt, 1, 0 |
|
- | 851 | test eax, eax |
|
- | 852 | ; There is no code to restore backup GPT if it's corrupt. |
|
- | 853 | ; Therefore just exit if Primary GPT has been parsed successfully. |
|
- | 854 | jz .exit |
|
- | 855 | DEBUGF 1, 'K : Primary GPT is corrupt, trying backup one\n' |
|
- | 856 | mov eax, dword[esi+DISK.MediaInfo.Capacity+0] |
|
- | 857 | mov edx, dword[esi+DISK.MediaInfo.Capacity+4] |
|
- | 858 | sub eax, 1 |
|
- | 859 | sbb edx, 0 |
|
- | 860 | ; Scan backup GPT (last sector) |
|
- | 861 | stdcall scan_gpt, eax, edx |
|
- | 862 | test eax, eax |
|
- | 863 | jz .exit |
|
- | 864 | DEBUGF 1, 'K : Backup GPT is also corrupt, fallback to legacy MBR\n' |
|
- | 865 | .exit: |
|
- | 866 | ; Return value is ZF |
|
- | 867 | ret |
|
- | 868 | endp |
|
- | 869 | ||
- | 870 | ||
- | 871 | ; This function is called from disk_scan_gpt to process a single GPT. |
|
- | 872 | proc scan_gpt _mylba:qword |
|
- | 873 | locals |
|
- | 874 | GPEA_len dd ? ; Length of GPT Partition Entry Array in bytes |
|
- | 875 | endl |
|
- | 876 | push ebx edi |
|
- | 877 | ; Allocalte memory for GPT header |
|
- | 878 | mov eax, [esi+DISK.MediaInfo.SectorSize] |
|
- | 879 | stdcall kernel_alloc, eax |
|
- | 880 | test eax, eax |
|
- | 881 | jz .fail |
|
- | 882 | ; Save pointer to stack, just in case |
|
- | 883 | push eax |
|
- | 884 | mov ebx, eax |
|
- | 885 | ; Read GPT header |
|
- | 886 | mov al, DISKFUNC.read |
|
- | 887 | push 1 |
|
- | 888 | stdcall disk_call_driver, ebx, dword[_mylba+0], dword[_mylba+4], esp |
|
- | 889 | pop ecx |
|
- | 890 | test eax, eax |
|
- | 891 | jnz .fail_free_gpt |
|
- | 892 | ; Check signature |
|
- | 893 | cmp dword[ebx+GPTH.Signature+0], 'EFI ' |
|
- | 894 | jnz .fail_free_gpt |
|
- | 895 | cmp dword[ebx+GPTH.Signature+4], 'PART' |
|
- | 896 | jnz .fail_free_gpt |
|
- | 897 | ; Check Revision |
|
- | 898 | cmp [ebx+GPTH.Revision], 0x00010000 |
|
- | 899 | jnz .fail_free_gpt |
|
- | 900 | ; Compute and check CRC32 |
|
- | 901 | xor edx, edx |
|
- | 902 | xchg edx, [ebx+GPTH.HeaderCRC32] |
|
- | 903 | mov eax, -1 |
|
- | 904 | stdcall crc_32, 0xEDB88320, ebx, [ebx+GPTH.HeaderSize] |
|
- | 905 | xor eax, -1 |
|
- | 906 | cmp eax, edx |
|
- | 907 | jnz .fail_free_gpt |
|
- | 908 | ; Reserved must be zero |
|
- | 909 | cmp [ebx+GPTH.Reserved], 0 |
|
- | 910 | jnz .fail_free_gpt |
|
- | 911 | ; MyLBA of GPT header at LBA X must equal X |
|
- | 912 | mov eax, dword[ebx+GPTH.MyLBA+0] |
|
- | 913 | mov edx, dword[ebx+GPTH.MyLBA+4] |
|
- | 914 | cmp eax, dword[_mylba+0] |
|
- | 915 | jnz .fail_free_gpt |
|
- | 916 | cmp edx, dword[_mylba+4] |
|
- | 917 | jnz .fail_free_gpt |
|
- | 918 | ; Capacity - MyLBA = AlternateLBA |
|
- | 919 | mov eax, dword[esi+DISK.MediaInfo.Capacity+0] |
|
- | 920 | mov edx, dword[esi+DISK.MediaInfo.Capacity+4] |
|
- | 921 | sub eax, dword[_mylba+0] |
|
- | 922 | sbb edx, dword[_mylba+4] |
|
- | 923 | cmp eax, dword[ebx+GPTH.AlternateLBA+0] |
|
- | 924 | ; DISK.MediaInfo.Capacity is -1 for ATA devices, disable this check for now. |
|
- | 925 | ; jnz .fail_free_gpt |
|
- | 926 | cmp edx, dword[ebx+GPTH.AlternateLBA+4] |
|
- | 927 | ; jnz .fail_free_gpt |
|
- | 928 | ||
- | 929 | ; Compute GPT Partition Entry Array (GPEA) length in bytes |
|
- | 930 | mov eax, [ebx+GPTH.NumberOfPartitionEntries] |
|
- | 931 | mul [ebx+GPTH.SizeOfPartitionEntry] |
|
- | 932 | test edx, edx ; far too big |
|
- | 933 | jnz .fail_free_gpt |
|
- | 934 | ; Round up to sector boundary |
|
- | 935 | mov ecx, [esi+DISK.MediaInfo.SectorSize] ; power of two |
|
- | 936 | dec ecx |
|
- | 937 | add eax, ecx |
|
- | 938 | jc .fail_free_gpt ; too big |
|
- | 939 | not ecx |
|
- | 940 | and eax, ecx |
|
- | 941 | ; We will need this length to compute CRC32 of GPEA |
|
- | 942 | mov [GPEA_len], eax |
|
- | 943 | ; Allocate memory for GPEA |
|
- | 944 | stdcall kernel_alloc, eax |
|
- | 945 | test eax, eax |
|
- | 946 | jz .fail_free_gpt |
|
- | 947 | ; Save to not juggle with registers |
|
- | 948 | push eax |
|
- | 949 | mov edi, eax |
|
- | 950 | mov eax, [GPEA_len] |
|
- | 951 | xor edx, edx |
|
- | 952 | ; Get the number of sectors GPEA fits into |
|
- | 953 | div [esi+DISK.MediaInfo.SectorSize] |
|
- | 954 | push eax ; esp = pointer to the number of sectors |
|
- | 955 | mov al, DISKFUNC.read |
|
- | 956 | stdcall disk_call_driver, edi, dword[ebx+GPTH.PartitionEntryLBA+0], \ |
|
- | 957 | dword[ebx+GPTH.PartitionEntryLBA+4], esp |
|
- | 958 | pop ecx |
|
- | 959 | test eax, eax |
|
- | 960 | jnz .fail_free_gpea_gpt |
|
- | 961 | ; Compute and check CRC32 of GPEA |
|
- | 962 | mov edx, [ebx+GPTH.PartitionEntryArrayCRC32] |
|
- | 963 | mov eax, -1 |
|
- | 964 | stdcall crc_32, 0xEDB88320, edi, [GPEA_len] |
|
- | 965 | xor eax, -1 |
|
- | 966 | cmp eax, edx |
|
- | 967 | jnz .fail_free_gpea_gpt |
|
- | 968 | ||
- | 969 | ; Process partitions, skip zeroed ones. |
|
- | 970 | .next_gpe: |
|
- | 971 | xor eax, eax |
|
- | 972 | mov ecx, [ebx+GPTH.SizeOfPartitionEntry] |
|
- | 973 | repz scasb |
|
- | 974 | jz .skip |
|
- | 975 | add edi, ecx |
|
- | 976 | sub edi, [ebx+GPTH.SizeOfPartitionEntry] |
|
- | 977 | ; Length of a partition in sectors is EndingLBA - StartingLBA + 1 |
|
- | 978 | mov eax, dword[edi+GPE.EndingLBA+0] |
|
- | 979 | mov edx, dword[edi+GPE.EndingLBA+4] |
|
- | 980 | sub eax, dword[edi+GPE.StartingLBA+0] |
|
- | 981 | sbb edx, dword[edi+GPE.StartingLBA+4] |
|
- | 982 | add eax, 1 |
|
- | 983 | adc edx, 0 |
|
- | 984 | stdcall disk_add_partition, dword[edi+GPE.StartingLBA+0], \ |
|
- | 985 | dword[edi+GPE.StartingLBA+4], eax, edx, esi |
|
- | 986 | add edi, [ebx+GPTH.SizeOfPartitionEntry] |
|
- | 987 | .skip: |
|
- | 988 | dec [ebx+GPTH.NumberOfPartitionEntries] |
|
- | 989 | jnz .next_gpe |
|
- | 990 | ||
- | 991 | ; Pointers to GPT header and GPEA are on the stack |
|
- | 992 | stdcall kernel_free |
|
- | 993 | stdcall kernel_free |
|
- | 994 | pop edi ebx |
|
- | 995 | xor eax, eax |
|
- | 996 | ret |
|
- | 997 | .fail_free_gpea_gpt: |
|
- | 998 | stdcall kernel_free |
|
- | 999 | .fail_free_gpt: |
|
- | 1000 | stdcall kernel_free |
|
- | 1001 | .fail: |
|
- | 1002 | pop edi ebx |
|
- | 1003 | xor eax, eax |
|
- | 1004 | inc eax |
|
- | 1005 | ret |
|
- | 1006 | endp |
|
- | 1007 | ||
- | 1008 | ; ecx = pointer to partition records array (MBR + 446) |
|
- | 1009 | is_protective_mbr: |
|
- | 1010 | push ecx edi |
|
- | 1011 | xor eax, eax |
|
- | 1012 | cmp [ecx-6], eax |
|
- | 1013 | jnz .exit |
|
- | 1014 | cmp [ecx-2], eax |
|
- | 1015 | jnz .exit |
|
- | 1016 | ; Partition record 0 has specific fields |
|
- | 1017 | cmp dword[ecx+0], 0x00020000 |
|
- | 1018 | jnz .exit |
|
- | 1019 | cmp byte[ecx+4], 0xEE |
|
- | 1020 | jnz .exit |
|
- | 1021 | cmp dword[ecx+8], 1 |
|
- | 1022 | jnz .exit |
|
- | 1023 | ; DISK.MediaInfo.Capacity is -1 for ATA devices, disable this check for now. |
|
- | 1024 | ; cmp dword[esi+DISK.MediaInfo.Capacity+4], eax |
|
- | 1025 | ; mov edi, 0xFFFFFFFF |
|
- | 1026 | ; jnz @f |
|
- | 1027 | ; mov edi, dword[esi+DISK.MediaInfo.Capacity+0] |
|
- | 1028 | ; dec edi |
|
- | 1029 | ;@@: |
|
- | 1030 | ; cmp dword[ecx+12], edi |
|
- | 1031 | ; jnz .exit |
|
- | 1032 | ||
- | 1033 | ; Check that partition records 1-3 are filled with zero |
|
- | 1034 | lea edi, [ecx+16] |
|
- | 1035 | mov ecx, 16*3/2 ; 3 partitions |
|
- | 1036 | repz scasw |
|
- | 1037 | .exit: |
|
- | 1038 | pop edi ecx |
|
- | 1039 | ; Return value is ZF |
|
789 | ret |
1040 | ret |
Line 790... | Line 1041... | ||
790 | 1041 | ||
791 | ; This is an internal function called from disk_scan_partitions. It checks |
1042 | ; This is an internal function called from disk_scan_partitions. It checks |
792 | ; whether the entry pointed to by ecx is a valid entry of partition table. |
1043 | ; whether the entry pointed to by ecx is a valid entry of partition table. |