Subversion Repositories Kolibri OS

Rev

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.