Subversion Repositories Kolibri OS

Rev

Rev 9047 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9047 Rev 9048
Line 3... Line 3...
3
;; Copyright (C) KolibriOS team 2004-2020. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2020. 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: 8876 $
8
$Revision: 9048 $
9
 
9
 
Line 562... Line 562...
562
        mov     ebp, esp
562
        mov     ebp, esp
563
        mov     ebx, cr2
563
        mov     ebx, cr2
564
        push    ebx               ;that is locals: .err_addr = cr2
564
        push    ebx               ;that is locals: .err_addr = cr2
565
        inc     [pg_data.pages_faults]
565
        inc     [pg_data.pages_faults]
Line 566... Line 566...
566
 
566
 
Line 567... Line 567...
567
        mov     eax, [pf_err_code]
567
        mov     esi, [pf_err_code]
568
 
568
 
Line 569... Line 569...
569
        cmp     ebx, OS_BASE      ;ebx == .err_addr
569
        cmp     ebx, OS_BASE      ;ebx == .err_addr
570
        jb      .user_space       ;page in application memory
570
        jb      .user_space       ;page in application memory
Line -... Line 571...
-
 
571
 
571
 
572
        cmp     ebx, page_tabs
572
        cmp     ebx, page_tabs
573
        jb      .kernel_space     ;page in kernel memory
573
        jb      .kernel_space     ;page in kernel memory
574
 
574
 
575
        xor     eax, eax
575
        cmp     ebx, kernel_tabs
576
        cmp     ebx, kernel_tabs
576
        jb      .alloc;.app_tabs  ;page tables of application ;
577
        jb      .alloc;.app_tabs  ;page tables of application ;
577
                                  ;simply create one
578
                                  ;simply create one
578
.core_tabs:
579
.core_tabs:
-
 
580
.fail:  ;simply return to caller
-
 
581
        mov     esp, ebp
-
 
582
        pop     ebx               ;restore exception number (#PF)
-
 
583
        ret
-
 
584
.fail_maybe_unlock:
-
 
585
        test    esi, esi
-
 
586
        jz      .fail
-
 
587
.fail_unlock:
Line 579... Line 588...
579
.fail:  ;simply return to caller
588
        mov     ecx, [current_process]
-
 
589
        add     ecx, PROC.heap_lock
-
 
590
        call    mutex_unlock
-
 
591
        jmp     .fail
-
 
592
 
-
 
593
.user_space:
-
 
594
; PF entry in IDT is interrupt gate, so up to this moment
-
 
595
; atomicity was guaranteed by cleared IF.
-
 
596
; It is inpractical to guard all modifications in the page table by cli/sti,
-
 
597
; so enable interrupts and acquire the address space lock.
-
 
598
; Unfortunately, that enables the scenario when the fault of current thread
-
 
599
; is resolved by another thread when the current thread waits in mutex_lock,
-
 
600
; so watch out: in lock-protected section we can find out that
580
        mov     esp, ebp
601
; there is no error already.
581
        pop     ebx               ;restore exception number (#PF)
602
        sti
582
        ret
603
        mov     ecx, [current_process]
Line 583... Line 604...
583
 
604
        add     ecx, PROC.heap_lock
584
.user_space:
605
        call    mutex_lock
585
        test    eax, PG_READ
606
        test    esi, PG_READ
586
        jnz     .err_access       ;Page presents
607
        jnz     .err_access       ;Page is present
587
                                  ;Access error ?
-
 
588
 
608
                                  ;Access error ?
589
        shr     ebx, 12
609
 
Line 590... Line 610...
590
        mov     ecx, ebx
610
        shr     ebx, 12
591
        shr     ecx, 10
611
        mov     ecx, ebx
-
 
612
        shr     ecx, 10
-
 
613
        test    dword [master_tab+ecx*4], PG_READ
592
        mov     edx, [master_tab+ecx*4]
614
        jz      .fail_unlock      ;page table is not created
593
        test    edx, PG_READ
-
 
-
 
615
                                  ;incorrect address in program
-
 
616
 
594
        jz      .fail             ;page table is not created
617
        mov     eax, [page_tabs+ebx*4]
-
 
618
        test    eax, PG_READ
595
                                  ;incorrect address in program
619
        jnz     .exit_unlock      ; already resolved by a parallel thread
596
 
620
        test    eax, LAZY_ALLOC_PAGE
597
        mov     eax, [page_tabs+ebx*4]
621
        jz      .fail_unlock      ;address is not reserved for use, error
Line 598... Line 622...
598
        test    eax, 2
622
        test    eax, LAZY_ALLOC_UNREADABLE
-
 
623
        jnz     .fail_unlock
-
 
624
.alloc:
-
 
625
        mov     esi, eax
599
        jz      .fail             ;address is not reserved for usage. Error
626
        call    alloc_zero_page
600
                                  
627
        test    eax, eax
601
.alloc:
628
        jz      .fail_maybe_unlock
602
        call    alloc_page
629
 
-
 
630
        mov     edx, PG_UWR
603
        test    eax, eax
631
        test    esi, LAZY_ALLOC_UNWRITABLE
604
        jz      .fail
632
        jz      @f
605
 
633
        mov     edx, PG_UR
606
        stdcall map_page, [.err_addr], eax, PG_UWR
634
@@:
607
 
635
        stdcall map_page, [.err_addr], eax, edx
608
        mov     edi, [.err_addr]
636
        mov     ecx, [current_process]
609
        and     edi, 0xFFFFF000
637
        add     [ecx+PROC.mem_used], 0x1000
Line 610... Line 638...
610
        mov     ecx, 1024
638
.exit_unlock:
611
        xor     eax, eax
639
        mov     ecx, [current_process]
-
 
640
        add     ecx, PROC.heap_lock
-
 
641
        call    mutex_unlock
-
 
642
.exit:  ;iret with repeat fault instruction
-
 
643
        add     esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
-
 
644
        restore_ring3_context
-
 
645
        iretd
-
 
646
 
-
 
647
.err_access:
-
 
648
; access denied? this may be a result of copy-on-write protection
-
 
649
; Check whether the problem has already been resolved
-
 
650
; while we were waiting in mutex_lock.
-
 
651
        mov     eax, ebx
-
 
652
        shr     eax, 12
612
       ;cld     ;caller is duty for this
653
        mov     eax, [page_tabs+eax*4]
613
        rep stosd
654
        test    eax, PG_READ
614
.exit:  ;iret with repeat fault instruction
655
        jz      .fail_unlock ; someone has free'd the page
615
        add     esp, 12;clear in stack: locals(.err_addr) + #PF + ret_to_caller
656
        test    eax, PG_USER
616
        restore_ring3_context
657
        jz      .fail_unlock ; page is mprotect'ed without PROT_READ
-
 
658
        test    eax, PG_WRITE
-
 
659
        jnz     .exit_unlock ; someone has enabled write
617
        iretd
660
        test    eax, PG_SHARED
618
 
661
        jz      .fail_unlock ; only shared pages can be copy-on-write
619
.err_access:
662
; check list of mapped data
-
 
663
        and     ebx, not 0xFFF
-
 
664
        call    find_smap_by_address
620
; access denied? this may be a result of copy-on-write protection for DLL
665
        test    esi, esi
621
; check list of HDLLs
666
        jz      .fail_unlock
622
        and     ebx, not 0xFFF
667
; ignore children of SMEM, only children of PEDESCR can have copy-on-write data
-
 
668
        cmp     [esi+SMAP.type], SMAP_TYPE_PE
-
 
669
        jnz     .fail_unlock
623
        mov     eax, [current_process]
670
        shr     edi, 12
624
        mov     eax, [eax+PROC.dlls_list_ptr]
671
; lock page array in PEDESCR
625
        test    eax, eax
672
        mov     esi, [esi+SMAP.parent]
626
        jz      .fail
673
        lea     ecx, [esi+PEDESCR.page_array_lock]
627
        mov     esi, [eax+HDLL.fd]
674
        push    eax
628
.scan_hdll:
675
        call    mutex_lock
629
        cmp     esi, eax
676
        pop     eax
630
        jz      .fail
677
; check whether the page is shared
631
        mov     edx, ebx
678
; PG_SHARED flag could be set by lock_and_map_page
632
        sub     edx, [esi+HDLL.base]
679
        xor     eax, [esi+sizeof.PEDESCR+edi*4]
633
        cmp     edx, [esi+HDLL.size]
680
        test    eax, not 0xFFF
634
        jb      .fault_in_hdll
681
        jnz     .fail_unlock2
635
.scan_hdll.next:
682
; check whether write is allowed by section attributes
636
        mov     esi, [esi+HDLL.fd]
683
        mov     eax, [esi+sizeof.PEDESCR+edi*4]
637
        jmp     .scan_hdll
684
        test    eax, IMAGE_SCN_MEM_WRITE shr 20
638
.fault_in_hdll:
685
        jz      .fail_unlock2
639
; allocate new page, map it as rw and copy data
686
; if we're faulting on the page which was originally shareable writable,
-
 
687
; it means that someone has disabled writing with mprotect; fail
640
        call    alloc_page
688
        test    eax, IMAGE_SCN_MEM_SHARED shr 20
641
        test    eax, eax
689
        jnz     .fail_unlock2
642
        jz      .fail
690
        stdcall pe_copy_on_write, PG_UWR
Line 643... Line 691...
643
        stdcall map_page, ebx, eax, PG_UWR
691
        jc	.fail_unlock2
644
        mov     edi, ebx
692
.exit_unlock2:
645
        mov     ecx, 1024
693
        lea     ecx, [esi+PEDESCR.page_array_lock]
Line 646... Line 694...
646
        sub     ebx, [esi+HDLL.base]
694
        call    mutex_unlock
647
        mov     esi, [esi+HDLL.parent]
695
        jmp     .exit_unlock
Line 648... Line 696...
648
        mov     esi, [esi+DLLDESCR.data]
696
.fail_unlock2:
649
        add     esi, ebx
697
        lea     ecx, [esi+PEDESCR.page_array_lock]
650
        rep movsd
-
 
-
 
698
        call    mutex_unlock
Line 651... Line 699...
651
        jmp     .exit
699
        jmp     .fail_unlock
Line 652... Line 700...
652
 
700
 
653
.kernel_space:
701
.kernel_space:
Line 675... Line 723...
675
        call    alloc_page
723
        call    alloc_page
676
        test    eax, eax
724
        test    eax, eax
677
        jz      .fail
725
        jz      .fail
Line 678... Line 726...
678
 
726
 
679
        push    eax
727
        push    eax
680
        stdcall map_page, [.err_addr], eax, dword PG_SWR
728
        stdcall map_page, [.err_addr], eax, PG_SWR
681
        pop     eax
729
        pop     eax
682
        mov     edi, [.err_addr]
730
        mov     edi, [.err_addr]
683
        and     edi, -4096
731
        and     edi, -4096
Line 694... Line 742...
694
       ;cld     ;caller is duty for this
742
       ;cld     ;caller is duty for this
695
        rep movsd
743
        rep movsd
696
        jmp     .exit
744
        jmp     .exit
697
endp
745
endp
Line -... Line 746...
-
 
746
 
-
 
747
; Sometimes we can just allocate a page and let the caller fill it.
-
 
748
; Sometimes we need a zero-filled page, but we can zero it at the target.
-
 
749
; Sometimes we need a zero-filled page before mapping to the target.
-
 
750
; This function is for the last case.
-
 
751
; out: eax = physical page
-
 
752
; destroys: nothing
-
 
753
proc alloc_zero_page
-
 
754
	call	alloc_page
-
 
755
	test	eax, eax
-
 
756
	jz	.nothing
-
 
757
	spin_lock_irqsave zero_page_spinlock
-
 
758
	push	ecx edx edi eax
-
 
759
	mov	edi, [zero_page_tab]
-
 
760
	stdcall	map_page, edi, [esp+4], PG_SWR
-
 
761
	pushd	0 [esp+4] edi ; for map_page
-
 
762
	mov	ecx, 0x1000/4
-
 
763
	xor	eax, eax
-
 
764
	rep stosd
-
 
765
	call	map_page
-
 
766
	pop	eax edi edx ecx
-
 
767
	spin_unlock_irqrestore zero_page_spinlock
-
 
768
.nothing:
-
 
769
	ret
-
 
770
endp
-
 
771
 
-
 
772
; in: ebx = address
-
 
773
; out if SMAP exists for this address: esi -> SMAP, edi = ebx - SMAP.base
-
 
774
; out if SMAP does not exist: esi = 0
-
 
775
proc find_smap_by_address
-
 
776
        mov     edx, [current_process]
-
 
777
        add     edx, PROC.smap_list
-
 
778
        mov     esi, [edx+SMAP.fd]
-
 
779
.scan:
-
 
780
        cmp     esi, edx
-
 
781
        jz      .fail
-
 
782
        mov     edi, ebx
-
 
783
        sub     edi, [esi+SMAP.base]
-
 
784
        cmp     edi, [esi+SMAP.size]
-
 
785
        jb      .exit
-
 
786
        mov     esi, [esi+SMAP.fd]
-
 
787
        jmp     .scan
-
 
788
.fail:
-
 
789
        xor     esi, esi
-
 
790
.exit:
-
 
791
        ret
-
 
792
endp
-
 
793
 
-
 
794
; Someone is about to write to copy-on-write page inside mapped PE.
-
 
795
; Provide a page that can be written to.
-
 
796
; in: esi -> PEDESCR
-
 
797
; in: edi = page number inside PE
-
 
798
; in: eax = [esi+sizeof.PEDESCR+edi*4]
-
 
799
; in: ebx = address in process, must be page-aligned
-
 
800
; in: [esp+4] = access rights for the new page
-
 
801
; out: CF=0 - ok, CF=1 - error, no memory
-
 
802
proc pe_copy_on_write
-
 
803
; 1. Decrement reference counter unless it is 0xFF.
-
 
804
        mov     edx, eax
-
 
805
        and     edx, 0xFF
-
 
806
        cmp     edx, 0xFF
-
 
807
        jz      @f
-
 
808
        dec     eax
-
 
809
@@:
-
 
810
; 2. If reference counter is zero now, transfer ownership from PEDESCR to the process.
-
 
811
        test    eax, 0xFF
-
 
812
        jnz     .alloc_copy
-
 
813
        mov     dword [esi+sizeof.PEDESCR+edi*4], 0
-
 
814
        and     eax, not 0xFFF
-
 
815
.remap:
-
 
816
        stdcall map_page, ebx, eax, [esp+4]
-
 
817
        clc
-
 
818
        ret     4
-
 
819
.alloc_copy:
-
 
820
; 3. Otherwise, store updated reference counter to PEDESCR,
-
 
821
; allocate new page, map it as rw and copy data.
-
 
822
        mov     [esi+sizeof.PEDESCR+edi*4], eax
-
 
823
        stdcall kernel_alloc, 0x1000
-
 
824
        test    eax, eax
-
 
825
        jz      .error
-
 
826
        push    esi
-
 
827
        mov     esi, ebx
-
 
828
        mov     edi, eax
-
 
829
        mov     ecx, 0x1000/4
-
 
830
        rep movsd
-
 
831
        mov     esi, eax
-
 
832
        call    get_pg_addr
-
 
833
        push    eax
-
 
834
        stdcall free_kernel_space, esi
-
 
835
        pop     eax
-
 
836
        pop     esi
-
 
837
        jmp     .remap
-
 
838
.error:
-
 
839
        stc
-
 
840
        ret     4
-
 
841
endp
-
 
842
 
-
 
843
PROT_READ = 1
-
 
844
PROT_WRITE = 2
-
 
845
PROT_EXEC = 4
-
 
846
proc mprotect stdcall uses ebx esi edi, address:dword, size:dword, access:dword
-
 
847
locals
-
 
848
retval		dd	-1
-
 
849
smap_ptr	dd	0
-
 
850
endl
-
 
851
	mov	ecx, [current_process]
-
 
852
	add	ecx, PROC.heap_lock
-
 
853
	call	mutex_lock
-
 
854
	test	[access], not (PROT_READ+PROT_WRITE+PROT_EXEC)
-
 
855
	jnz	.error
-
 
856
	cmp	[size], 0
-
 
857
	jz	.error
-
 
858
	mov	eax, [address]
-
 
859
	add	[size], eax
-
 
860
	and	eax, not 0xFFF
-
 
861
.addrloop:
-
 
862
	mov	[address], eax
-
 
863
	mov	ecx, eax
-
 
864
	cmp	eax, OS_BASE
-
 
865
	jae	.error
-
 
866
	shr     eax, 22
-
 
867
	test    byte [master_tab+eax*4], PG_READ
-
 
868
	jz      .error
-
 
869
	shr	ecx, 12
-
 
870
	mov	eax, [page_tabs+ecx*4]
-
 
871
	test	al, PG_READ
-
 
872
	jnz	.page_present
-
 
873
	test	al, LAZY_ALLOC_PAGE
-
 
874
	jz	.error
-
 
875
	cmp	[retval], -1
-
 
876
	jnz	.skip_query
-
 
877
	inc	[retval]
-
 
878
	test	al, LAZY_ALLOC_UNREADABLE
-
 
879
	jnz	@f
-
 
880
	or	[retval], PROT_READ+PROT_EXEC
-
 
881
@@:
-
 
882
	test	al, LAZY_ALLOC_UNWRITABLE
-
 
883
	jnz	@f
-
 
884
	or	[retval], PROT_WRITE
-
 
885
@@:
-
 
886
.skip_query:
-
 
887
	and	al, not (LAZY_ALLOC_UNREADABLE+LAZY_ALLOC_UNWRITABLE)
-
 
888
	test	[access], PROT_READ
-
 
889
	jnz	@f
-
 
890
	or	al, LAZY_ALLOC_UNREADABLE
-
 
891
@@:
-
 
892
	test	[access], PROT_WRITE
-
 
893
	jnz	@f
-
 
894
	or	al, LAZY_ALLOC_UNWRITABLE
-
 
895
@@:
-
 
896
	mov	[page_tabs+ecx*4], eax
-
 
897
	jmp	.nextpage
-
 
898
.page_present:
-
 
899
	test	eax, PG_SHARED
-
 
900
	jnz	.page_shared
-
 
901
.normal_page:
-
 
902
	cmp	[retval], -1
-
 
903
	jnz	.skip_query2
-
 
904
	inc	[retval]
-
 
905
	test	al, PG_USER
-
 
906
	jz	@f
-
 
907
	or	[retval], PROT_READ+PROT_EXEC
-
 
908
@@:
-
 
909
	test	al, PG_WRITE
-
 
910
	jz	@f
-
 
911
	or	[retval], PROT_WRITE
-
 
912
@@:
-
 
913
.skip_query2:
-
 
914
	and	al, not (PG_USER+PG_WRITE)
-
 
915
	test	[access], PROT_READ
-
 
916
	jz	@f
-
 
917
	or	al, PG_USER
-
 
918
@@:
-
 
919
	test	[access], PROT_WRITE
-
 
920
	jz	@f
-
 
921
	or	al, PG_WRITE
-
 
922
@@:
-
 
923
	mov	[page_tabs+ecx*4], eax
-
 
924
	mov	eax, [address]
-
 
925
	invlpg	[eax]
-
 
926
	jmp	.nextpage
-
 
927
.page_shared:
-
 
928
	mov	esi, [smap_ptr]
-
 
929
	test	esi, esi
-
 
930
	jz	.find_smap
-
 
931
	mov	edx, [address]
-
 
932
	sub	edx, [esi+SMAP.base]
-
 
933
	cmp	edx, [esi+SMAP.size]
-
 
934
	jb	.found_smap
-
 
935
.find_smap:
-
 
936
	mov	ebx, [address]
-
 
937
	call	find_smap_by_address
-
 
938
	mov	[smap_ptr], esi
-
 
939
	test	esi, esi
-
 
940
	jz	.normal_page
-
 
941
.found_smap:
-
 
942
	cmp	[esi+SMAP.type], SMAP_TYPE_PE
-
 
943
	jnz	.error
-
 
944
	shr	edi, 12
-
 
945
	mov	esi, [esi+SMAP.parent]
-
 
946
	lea	ecx, [esi+PEDESCR.page_array_lock]
-
 
947
	push	eax
-
 
948
	call	mutex_lock
-
 
949
	pop	eax
-
 
950
	xor	eax, [esi+sizeof.PEDESCR+edi*4]
-
 
951
	test	eax, not 0xFFF
-
 
952
	jnz	.normal_page_unlock
-
 
953
	mov	eax, [esi+sizeof.PEDESCR+edi*4]
-
 
954
	test	eax, IMAGE_SCN_MEM_SHARED shr 20
-
 
955
	jnz	.normal_page_unlock
-
 
956
	cmp	[retval], -1
-
 
957
	jnz	.skip_query3
-
 
958
	mov	edx, [address]
-
 
959
	shr	edx, 12
-
 
960
	inc	[retval]
-
 
961
	test	byte [page_tabs+edx*4], PG_USER
-
 
962
	jz	@f
-
 
963
	or	[retval], PROT_READ+PROT_EXEC
-
 
964
@@:
-
 
965
	test	eax, IMAGE_SCN_MEM_WRITE shr 20
-
 
966
	jz	@f
-
 
967
	or	[retval], PROT_WRITE
-
 
968
@@:
-
 
969
.skip_query3:
-
 
970
	test	[access], PROT_WRITE
-
 
971
	jz	.no_write
-
 
972
	push	PG_SWR
-
 
973
	test	[access], PROT_READ
-
 
974
	jz	@f
-
 
975
	pop	edx
-
 
976
	push	PG_UWR
-
 
977
@@:
-
 
978
	call	pe_copy_on_write
-
 
979
	lea	ecx, [esi+PEDESCR.page_array_lock]
-
 
980
	call	mutex_unlock
-
 
981
	jmp	.nextpage
-
 
982
.normal_page_unlock:
-
 
983
	lea	ecx, [esi+PEDESCR.page_array_lock]
-
 
984
	call	mutex_unlock
-
 
985
	mov	ecx, [address]
-
 
986
	shr	ecx, 12
-
 
987
	mov	eax, [page_tabs+ecx*4]
-
 
988
	jmp	.normal_page
-
 
989
.no_write:
-
 
990
	lea	ecx, [esi+PEDESCR.page_array_lock]
-
 
991
	call	mutex_unlock
-
 
992
	mov	ecx, [address]
-
 
993
	shr	ecx, 12
-
 
994
	mov	eax, [page_tabs+ecx*4]
-
 
995
	jmp	.skip_query2
-
 
996
.nextpage:
-
 
997
	mov	eax, [address]
-
 
998
	add	eax, 0x1000
-
 
999
	cmp	eax, [size]
-
 
1000
	jb	.addrloop
-
 
1001
.exit:
-
 
1002
	mov	ecx, [current_process]
-
 
1003
	add	ecx, PROC.heap_lock
-
 
1004
	call	mutex_unlock
-
 
1005
	mov	eax, [retval]
-
 
1006
	ret
-
 
1007
.error:
-
 
1008
	or	[retval], -1
-
 
1009
	jmp	.exit
-
 
1010
endp
698
 
1011
 
699
; returns number of mapped bytes
1012
; returns number of mapped bytes
700
proc map_mem_ipc stdcall, lin_addr:dword,slot:dword,\
1013
proc map_memEx stdcall uses ebx esi edi, lin_addr:dword,slot:dword,\
701
                      ofs:dword,buf_size:dword,req_access:dword
1014
                      ofs:dword,buf_size:dword,req_access:dword,where:dword
702
        locals
1015
        locals
703
             count   dd ?
1016
             count   dd ?
704
             process dd ?
1017
             process dd ?
Line 708... Line 1021...
708
        cmp     [buf_size], 0
1021
        cmp     [buf_size], 0
709
        jz      .exit
1022
        jz      .exit
Line 710... Line 1023...
710
 
1023
 
711
        mov     eax, [slot]
1024
        mov     eax, [slot]
712
        shl     eax, 8
1025
        shl     eax, 8
713
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
1026
        mov     ecx, [SLOT_BASE+eax+APPDATA.process]
714
        test    eax, eax
1027
        test    ecx, ecx
Line 715... Line 1028...
715
        jz      .exit
1028
        jz      .exit
-
 
1029
 
-
 
1030
        mov     [process], ecx
-
 
1031
        add     ecx, PROC.heap_lock
716
 
1032
        call    mutex_lock
717
        mov     [process], eax
1033
        mov     eax, [process]
718
        mov     ebx, [ofs]
1034
        mov     ebx, [ofs]
719
        shr     ebx, 22
1035
        shr     ebx, 22
720
        mov     eax, [eax+PROC.pdt_0+ebx*4]                 ;get page table
1036
        mov     eax, [eax+PROC.pdt_0+ebx*4]                 ;get page table
721
        mov     esi, [ipc_ptab]
1037
        mov     esi, [where]
722
        and     eax, 0xFFFFF000
1038
        and     eax, 0xFFFFF000
723
        jz      .exit
1039
        jz      .unlock_exit
724
        stdcall map_page, esi, eax, PG_SWR
1040
        stdcall map_page, esi, eax, PG_SWR
725
@@:
1041
@@:
726
        mov     edi, [lin_addr]
1042
        mov     edi, [lin_addr]
727
        and     edi, 0xFFFFF000
1043
        and     edi, 0xFFFFF000
728
        mov     ecx, [buf_size]
1044
        mov     ecx, [buf_size]
729
        add     ecx, 4095
-
 
Line 730... Line 1045...
730
        shr     ecx, 12
1045
        add     ecx, 4095
731
        inc     ecx                  ; ???????????
1046
        shr     ecx, 12
732
 
1047
 
733
        mov     edx, [ofs]
1048
        mov     edx, [ofs]
734
        shr     edx, 12
1049
        shr     edx, 12
735
        and     edx, 0x3FF
1050
        and     edx, 0x3FF
736
.map:
1051
.map:
737
        stdcall safe_map_page, [slot], [req_access], [ofs]
1052
        stdcall lock_and_map_page, [slot], [req_access], [ofs]
738
        jnc     .exit
1053
        jnc     .unlock_exit
739
        add     [count], PAGE_SIZE
1054
        add     [count], PAGE_SIZE
Line 740... Line 1055...
740
        add     [ofs], PAGE_SIZE
1055
        add     [ofs], PAGE_SIZE
741
        dec     ecx
1056
        dec     ecx
742
        jz      .exit
1057
        jz      .unlock_exit
743
 
1058
 
Line 744... Line 1059...
744
        add     edi, PAGE_SIZE
1059
        add     edi, PAGE_SIZE
745
        inc     edx
1060
        inc     edx
746
        cmp     edx, 1024
1061
        cmp     edx, 1024
747
        jnz     .map
1062
        jnz     .map
748
 
1063
 
Line 749... Line 1064...
749
        inc     ebx
1064
        inc     ebx
750
        mov     eax, [process]
1065
        mov     eax, [process]
751
        mov     eax, [eax+PROC.pdt_0+ebx*4]
1066
        mov     eax, [eax+PROC.pdt_0+ebx*4]
-
 
1067
        and     eax, 0xFFFFF000
-
 
1068
        jz      .unlock_exit
-
 
1069
 
-
 
1070
        stdcall map_page, esi, eax, PG_SWR
752
        and     eax, 0xFFFFF000
1071
        xor     edx, edx
753
        jz      .exit
1072
        jmp     .map
754
 
1073
.unlock_exit:
755
        stdcall map_page, esi, eax, PG_SWR
1074
        mov     ecx, [process]
Line 756... Line 1075...
756
        xor     edx, edx
1075
        add     ecx, PROC.heap_lock
757
        jmp     .map
1076
        call    mutex_unlock
758
.exit:
1077
.exit:
759
        mov     eax, [count]
-
 
760
        ret
1078
        mov     eax, [count]
761
endp
1079
        ret
Line 762... Line -...
762
 
-
 
763
proc map_memEx stdcall, lin_addr:dword,slot:dword,\
1080
endp
764
                        ofs:dword,buf_size:dword,req_access:dword
1081
 
Line 765... Line 1082...
765
        locals
1082
proc unmap_memEx stdcall uses ebx esi edi, lin_addr:dword,slot:dword,\
766
             count   dd ?
1083
                      ofs:dword,mapped_size:dword,pagedir:dword
767
             process dd ?
1084
        locals
-
 
1085
             process dd ?
-
 
1086
        endl
768
        endl
1087
 
769
 
1088
        cmp     [mapped_size], 0
770
        mov     [count], 0
-
 
-
 
1089
        jz      .exit
771
        cmp     [buf_size], 0
1090
 
772
        jz      .exit
1091
        mov     eax, [slot]
773
 
1092
        shl     eax, 8
-
 
1093
        mov     ecx, [SLOT_BASE+eax+APPDATA.process]
774
        mov     eax, [slot]
1094
        mov     [process], ecx
-
 
1095
        xor     eax, eax
775
        shl     eax, 8
1096
        test    ecx, ecx
776
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
1097
        jz      @f
777
        test    eax, eax
1098
        add     ecx, PROC.heap_lock
-
 
1099
        call    mutex_lock
778
        jz      .exit
1100
        mov     ebx, [ofs]
779
 
1101
        shr     ebx, 22
-
 
1102
        mov     eax, [process]
-
 
1103
        mov     eax, [eax+PROC.pdt_0+ebx*4]                 ;get page table
780
        mov     [process], eax
1104
@@:
781
        mov     ebx, [ofs]
1105
        xor     esi, esi
782
        shr     ebx, 22
1106
        and     eax, 0xFFFFF000
783
        mov     eax, [eax+PROC.pdt_0+ebx*4]                 ;get page table
1107
        jz      @f
784
        mov     esi, [proc_mem_tab]
1108
        mov     esi, [pagedir]
785
        and     eax, 0xFFFFF000
1109
        stdcall map_page, esi, eax, PG_SWR
Line 786... Line 1110...
786
        jz      .exit
1110
@@:
787
        stdcall map_page, esi, eax, PG_SWR
1111
        mov     ecx, shared_locked_mutex
788
@@:
1112
        call    mutex_lock
-
 
1113
        mov     edi, [lin_addr]
789
        mov     edi, [lin_addr]
1114
        shr     edi, 12
790
        and     edi, 0xFFFFF000
-
 
791
        mov     ecx, [buf_size]
-
 
792
        add     ecx, 4095
1115
        mov     ecx, [mapped_size]
793
        shr     ecx, 12
-
 
794
        inc     ecx                  ; ???????????
1116
        add     ecx, 4095
795
 
1117
        shr     ecx, 12
Line 796... Line 1118...
796
        mov     edx, [ofs]
1118
        mov     [mapped_size], ecx
797
        shr     edx, 12
1119
 
798
        and     edx, 0x3FF
1120
        mov     edx, [ofs]
799
.map:
1121
        shr     edx, 12
Line 800... Line 1122...
800
        stdcall safe_map_page, [slot], [req_access], [ofs]
1122
        and     edx, 0x3FF
-
 
1123
        lea     esi, [esi+edx*4]
-
 
1124
.map:
-
 
1125
        call    unlock_and_unmap_page
801
        jnc     .exit
1126
        dec     [mapped_size]
802
        add     [count], PAGE_SIZE
1127
        jz      .done
803
        add     [ofs], PAGE_SIZE
1128
 
804
        dec     ecx
1129
        inc     edi
Line -... Line 1130...
-
 
1130
        add     esi, 4
805
        jz      .exit
1131
        test    esi, 0xFFF
806
 
-
 
807
        add     edi, PAGE_SIZE
1132
        jnz     .map
-
 
1133
 
-
 
1134
        inc     ebx
-
 
1135
        xor     esi, esi
-
 
1136
        cmp     [process], 0
-
 
1137
        jz      .map
-
 
1138
        mov     eax, [process]
-
 
1139
        mov     eax, [eax+PROC.pdt_0+ebx*4]
-
 
1140
        and     eax, 0xFFFFF000
808
        inc     edx
1141
        jz      .map
809
        cmp     edx, 1024
1142
 
-
 
1143
        mov     esi, [pagedir]
-
 
1144
        stdcall map_page, esi, eax, PG_SWR
-
 
1145
        jmp     .map
-
 
1146
.done:
810
        jnz     .map
1147
        mov     ecx, shared_locked_mutex
811
 
1148
        call    mutex_unlock
Line 812... Line 1149...
812
        inc     ebx
1149
        cmp     [process], 0
813
        mov     eax, [process]
1150
        jz      .exit
814
        mov     eax, [eax+PROC.pdt_0+ebx*4]
1151
        mov     ecx, [process]
-
 
1152
        add     ecx, PROC.heap_lock
815
        and     eax, 0xFFFFF000
1153
        call    mutex_unlock
816
        jz      .exit
1154
.exit:
817
 
1155
        mov     eax, [pagedir]
-
 
1156
        mov     ecx, eax
-
 
1157
        shr     ecx, 12
-
 
1158
        mov     dword [page_tabs+ecx*4], 0
-
 
1159
        invlpg  [eax]
818
        stdcall map_page, esi, eax, PG_SWR
1160
        ret
819
        xor     edx, edx
1161
endp
820
        jmp     .map
1162
 
821
.exit:
1163
; in: esi+edx*4 = pointer to page table entry
822
        mov     eax, [count]
1164
; in: [slot], [req_access], [ofs] on the stack
823
        ret
1165
; in: edi = linear address to map
-
 
1166
; in: address space lock must be held
824
endp
1167
; out: CF cleared <=> failed
-
 
1168
; destroys: only eax
825
 
1169
proc lock_and_map_page stdcall, slot:dword, req_access:dword, ofs:dword
826
; in: esi+edx*4 = pointer to page table entry
1170
    locals
827
; in: [slot], [req_access], [ofs] on the stack
1171
        locked_descr dd ?
828
; in: edi = linear address to map
1172
    endl
829
; out: CF cleared <=> failed
1173
 
830
; destroys: only eax
1174
        mov     eax, [esi+edx*4]
831
proc safe_map_page stdcall, slot:dword, req_access:dword, ofs:dword
1175
        test    eax, PG_READ
832
        mov     eax, [esi+edx*4]
1176
        jz      .not_present
833
        test    al, PG_READ
1177
        test    eax, PG_SHARED
834
        jz      .not_present
1178
        jnz     .resolve_shared
835
        test    al, PG_WRITE
1179
; normal case: not shared allocated page, mark as shared and map with requested access
836
        jz      .resolve_readonly
1180
        or      dword [esi+edx*4], PG_SHARED
837
; normal case: writable page, just map with requested access
1181
.map:
838
.map:
1182
        and     eax, not 0xFFF
-
 
1183
        stdcall map_page, edi, eax, [req_access]
-
 
1184
        stc
-
 
1185
.fail:
839
        stdcall map_page, edi, eax, [req_access]
1186
        ret
-
 
1187
.not_present:
-
 
1188
; check for alloc-on-demand page
-
 
1189
        test    eax, LAZY_ALLOC_PAGE
-
 
1190
        jz      .fail
-
 
1191
; allocate new page, save it to source page table
840
        stc
1192
        push    ecx
841
.fail:
1193
        call    alloc_zero_page
842
        ret
1194
        pop     ecx
843
.not_present:
-
 
844
; check for alloc-on-demand page
1195
        test    eax, eax
845
        test    al, 2
1196
        jz      .fail
846
        jz      .fail
1197
        or      eax, PG_READ+PG_SHARED
847
; allocate new page, save it to source page table
1198
        test    dword [esi+edx*4], LAZY_ALLOC_UNREADABLE
848
        push    ecx
1199
        jnz     @f
849
        call    alloc_page
1200
        or      eax, PG_USER
850
        pop     ecx
1201
@@:
851
        test    eax, eax
1202
        test    dword [esi+edx*4], LAZY_ALLOC_UNWRITABLE
-
 
1203
        jnz     @f
852
        jz      .fail
1204
        or      eax, PG_WRITE
853
        or      al, PG_UWR
1205
@@:
854
        mov     [esi+edx*4], eax
1206
        mov     [esi+edx*4], eax
855
        jmp     .map
1207
        jmp     .map
856
.resolve_readonly:
-
 
857
; readonly page, probably copy-on-write
-
 
858
; check: readonly request of readonly page is ok
1208
.resolve_shared:
859
        test    [req_access], PG_WRITE
1209
        push    ecx edx eax
860
        jz      .map
1210
        mov     eax, sizeof.SHARED_LOCKED_PAGE
861
; find control structure for this page
1211
        call    malloc
862
        pushf
1212
        mov     [locked_descr], eax
863
        cli
1213
        test    eax, eax
864
        cld
1214
        jz      .fail_pop
-
 
1215
        mov     edx, [esp]
865
        push    ebx ecx
1216
        and     edx, not 0xFFF
-
 
1217
        mov     [eax+SHARED_LOCKED_PAGE.address], edx
-
 
1218
        mov     eax, [slot]
-
 
1219
        shl     eax, 8
-
 
1220
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
-
 
1221
        mov     ecx, [eax+PROC.smap_list]
-
 
1222
        add     eax, PROC.smap_list
-
 
1223
.find_shared_parent:
-
 
1224
        cmp     ecx, eax
866
        mov     eax, [slot]
1225
        jz      .shared_orphan
-
 
1226
        mov     edx, [ofs]
-
 
1227
        sub     edx, [ecx+SMAP.base]
-
 
1228
        cmp     edx, [ecx+SMAP.size]
-
 
1229
        jb      .found_shared_parent
867
        shl     eax, 8
1230
        mov     ecx, [ecx+SMAP.fd]
868
        mov     eax, [SLOT_BASE+eax+APPDATA.process]
1231
        jmp     .find_shared_parent
-
 
1232
.shared_abandoned:
-
 
1233
        call    mutex_unlock
869
        mov     eax, [eax+PROC.dlls_list_ptr]
1234
.shared_orphan:
-
 
1235
; no copy-on-write for orphans
-
 
1236
        test    dword [esp], PG_WRITE
-
 
1237
        jnz     @f
-
 
1238
        test    [req_access], PG_WRITE
-
 
1239
        jnz     .shared_forbidden
-
 
1240
@@:
870
        test    eax, eax
1241
; locking the same normal page for second time:
-
 
1242
; the first lock_and_map_page has set PG_SHARED,
-
 
1243
; now we must cooperate with that other thread.
-
 
1244
        mov     ecx, shared_locked_mutex
-
 
1245
        call    mutex_lock
-
 
1246
        mov     eax, [locked_descr]
871
        jz      .no_hdll
1247
        mov     [eax+SHARED_LOCKED_PAGE.parent], 0
-
 
1248
.shared_common:
-
 
1249
        mov     edx, [shared_locked_list+SHARED_LOCKED_PAGE.bk]
872
        mov     ecx, [eax+HDLL.fd]
1250
        mov     [eax+SHARED_LOCKED_PAGE.fd], shared_locked_list
873
.scan_hdll:
1251
        mov     [eax+SHARED_LOCKED_PAGE.bk], edx
874
        cmp     ecx, eax
1252
        mov     [edx+SHARED_LOCKED_PAGE.fd], eax
-
 
1253
        mov     [shared_locked_list+SHARED_LOCKED_PAGE.bk], edx
-
 
1254
        call    mutex_unlock
875
        jz      .no_hdll
1255
        pop     eax edx ecx
-
 
1256
        jmp     .map
-
 
1257
.shared_forbidden_unlock:
-
 
1258
        call    mutex_unlock
876
        mov     ebx, [ofs]
1259
.shared_forbidden:
877
        and     ebx, not 0xFFF
1260
        mov     eax, [locked_descr]
878
        sub     ebx, [ecx+HDLL.base]
1261
        call    free
-
 
1262
.fail_pop:
-
 
1263
        pop     eax edx ecx
-
 
1264
        clc
-
 
1265
        ret
-
 
1266
.found_shared_parent:
-
 
1267
        shr     edx, 12
-
 
1268
        mov     eax, [locked_descr]
-
 
1269
        mov     [eax+SHARED_LOCKED_PAGE.offs], edx
-
 
1270
        cmp     [ecx+SMAP.type], SMAP_TYPE_PE
-
 
1271
        jnz     .parent_smap
-
 
1272
        push    edx
-
 
1273
        mov     ecx, [ecx+SMAP.parent]
879
        cmp     ebx, [ecx+HDLL.size]
1274
        add     ecx, PEDESCR.page_array_lock
880
        jb      .hdll_found
1275
        call    mutex_lock
-
 
1276
        pop     edx
-
 
1277
        mov     eax, [esp]
-
 
1278
        xor     eax, [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4]
-
 
1279
        test    eax, not 0xFFF
-
 
1280
        jnz     .shared_abandoned
-
 
1281
        test    dword [esp], PG_WRITE
-
 
1282
        jnz     @f
-
 
1283
        test    [req_access], PG_WRITE
-
 
1284
        jnz     .pedescr_try_cow
-
 
1285
@@:
-
 
1286
        mov     eax, [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4]
-
 
1287
        inc     eax
-
 
1288
        test    eax, 0xFF
-
 
1289
        jnz     @f
-
 
1290
        dec     eax
-
 
1291
@@:
-
 
1292
        mov     [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4], eax
-
 
1293
        push    ecx
-
 
1294
        mov     ecx, pe_list_mutex
-
 
1295
        call    mutex_lock
-
 
1296
        mov     eax, [esp]
-
 
1297
        inc     dword [eax+PEDESCR.refcount-PEDESCR.page_array_lock]
-
 
1298
        call    mutex_unlock
-
 
1299
        pop     ecx
-
 
1300
        call    mutex_unlock
-
 
1301
        sub     ecx, PEDESCR.page_array_lock
-
 
1302
        push    ecx
-
 
1303
.shared_common2:
-
 
1304
        mov     ecx, shared_locked_mutex
-
 
1305
        call    mutex_lock
-
 
1306
        mov     eax, [locked_descr]
-
 
1307
        pop     [eax+SHARED_LOCKED_PAGE.parent]
-
 
1308
        jmp     .shared_common
881
        mov     ecx, [ecx+HDLL.fd]
1309
.pedescr_try_cow:
882
        jmp     .scan_hdll
1310
        mov     eax, [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4]
-
 
1311
        test	eax, IMAGE_SCN_MEM_WRITE shr 20
-
 
1312
        jz	@f
-
 
1313
        or      dword [esp], PG_WRITE
883
.no_hdll:
1314
@@:
-
 
1315
        dec     eax
-
 
1316
        test    eax, 0xFF
-
 
1317
        jnz     .pedescr_alloc_copy
-
 
1318
        mov     dword [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4], 0
884
        pop     ecx ebx
1319
        call    mutex_unlock
-
 
1320
        mov     eax, [locked_descr]
885
        popf
1321
        call    free
-
 
1322
        pop     eax edx ecx
886
        clc
1323
        or      eax, PG_SHARED
887
        ret
1324
        mov     [esi+edx*4], eax
-
 
1325
        jmp     .map
-
 
1326
.pedescr_alloc_copy:
888
.hdll_found:
1327
        push    ecx edx
-
 
1328
        stdcall kernel_alloc, 0x1000
-
 
1329
        pop     edx ecx
-
 
1330
        test    eax, eax
-
 
1331
        jz      .shared_forbidden_unlock
-
 
1332
        dec     dword [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4]
889
; allocate page, save it in page table, map it, copy contents from base
1333
        push    ecx esi edi
-
 
1334
        mov     esi, edi
-
 
1335
        mov     edi, eax
890
        mov     eax, [ecx+HDLL.parent]
1336
        stdcall map_page, esi, [ecx+sizeof.PEDESCR-PEDESCR.page_array_lock+edx*4], PG_READ
-
 
1337
        mov     ecx, 0x1000/4
-
 
1338
        rep movsd
-
 
1339
        sub     esi, 0x1000
891
        add     ebx, [eax+DLLDESCR.data]
1340
        sub     edi, 0x1000
892
        call    alloc_page
1341
        mov     eax, edi
-
 
1342
        call    get_pg_addr
-
 
1343
        and     dword [esp+12], 0xFFF
-
 
1344
        or      dword [esp+12], eax
-
 
1345
        stdcall map_page, esi, eax, [req_access]
-
 
1346
        stdcall free_kernel_space, edi
-
 
1347
        pop     edi esi ecx
-
 
1348
        call    mutex_unlock
-
 
1349
        mov     eax, [locked_descr]
-
 
1350
        call    free
-
 
1351
        pop     eax edx ecx
-
 
1352
        or      eax, PG_SHARED
-
 
1353
        mov     [esi+edx*4], eax
-
 
1354
        stc
-
 
1355
        ret
-
 
1356
.parent_smap:
-
 
1357
        test    dword [esp], PG_WRITE
-
 
1358
        jnz     @f
-
 
1359
        test    [req_access], PG_WRITE
-
 
1360
        jz      .shared_forbidden
-
 
1361
@@:
-
 
1362
        push    [ecx+SMAP.parent]
-
 
1363
        mov     ecx, shmem_list_mutex
-
 
1364
        call    mutex_lock
-
 
1365
        mov     eax, [esp]
-
 
1366
        inc     dword [esp]
-
 
1367
        inc     [eax+SMEM.refcount]
-
 
1368
        call    mutex_unlock
-
 
1369
        jmp     .shared_common2
-
 
1370
endp
-
 
1371
 
-
 
1372
; in: esi -> process page table entry or esi < 0x1000 if no page table entry
-
 
1373
; in: edi = page number for mapped copy
-
 
1374
; in: shared_locked_mutex is held
-
 
1375
; destroys eax, ecx, edx
-
 
1376
proc unlock_and_unmap_page
-
 
1377
        mov     edx, [page_tabs+edi*4]
-
 
1378
        and     edx, not 0xFFF
-
 
1379
        mov     dword [page_tabs+edi*4], 0
-
 
1380
        mov     eax, edi
-
 
1381
        shl     eax, 12
-
 
1382
        invlpg  [eax]
-
 
1383
        mov     eax, [shared_locked_list+SHARED_LOCKED_PAGE.fd]
-
 
1384
.check_list:
-
 
1385
        cmp     eax, shared_locked_list
-
 
1386
        jz      .not_in_list
-
 
1387
        cmp     edx, [eax+SHARED_LOCKED_PAGE.address]
-
 
1388
        jz      .found_in_list
-
 
1389
        mov     eax, [eax+SHARED_LOCKED_PAGE.fd]
-
 
1390
        jmp     .check_list
-
 
1391
.found_in_list:
-
 
1392
        push    esi
-
 
1393
        mov     esi, [eax+SHARED_LOCKED_PAGE.parent]
-
 
1394
        mov     edx, [eax+SHARED_LOCKED_PAGE.fd]
-
 
1395
        mov     ecx, [eax+SHARED_LOCKED_PAGE.bk]
-
 
1396
        mov     [edx+SHARED_LOCKED_PAGE.bk], ecx
-
 
1397
        mov     [ecx+SHARED_LOCKED_PAGE.fd], edx
-
 
1398
        test    esi, esi
-
 
1399
        jz      .orphan
-
 
1400
        btr     esi, 0
-
 
1401
        jc      .parent_smap
-
 
1402
        push    eax
-
 
1403
        lea     ecx, [esi+PEDESCR.page_array_lock]
-
 
1404
        call    mutex_lock
-
 
1405
        mov     edx, [esp]
-
 
1406
        mov     edx, [edx+SHARED_LOCKED_PAGE.offs]
-
 
1407
        mov     eax, [esi+sizeof.PEDESCR+edx*4]
-
 
1408
        and     eax, 0xFF
-
 
1409
        cmp     eax, 0xFF
-
 
1410
        jz      .no_deref
-
 
1411
        mov     eax, [esi+sizeof.PEDESCR+edx*4]
-
 
1412
        dec     eax
-
 
1413
        test    eax, 0xFF
-
 
1414
        jnz     @f
-
 
1415
        call    free_page
-
 
1416
        xor     eax, eax
-
 
1417
@@:
-
 
1418
        mov     [esi+sizeof.PEDESCR+edx*4], eax
-
 
1419
.no_deref:
-
 
1420
        lea     ecx, [esi+PEDESCR.page_array_lock]
-
 
1421
        call    mutex_unlock
-
 
1422
        call    dereference_pe
-
 
1423
        pop     eax
-
 
1424
        call    free
-
 
1425
        pop     esi
-
 
1426
        ret
-
 
1427
.parent_smap:
-
 
1428
        call    free
-
 
1429
        call    dereference_smem
-
 
1430
        pop     esi
-
 
1431
        ret
-
 
1432
.orphan:
-
 
1433
        call    free
-
 
1434
        pop     esi
893
        test    eax, eax
1435
        ret
Line 894... Line 1436...
894
        jz      .no_hdll
1436
.not_in_list:
895
        or      al, PG_UWR
1437
        cmp     esi, 0x1000
896
        mov     [esi+edx*4], eax
1438
        jb      .just_free
Line 955... Line 1497...
955
 
1497
 
956
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
1498
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword
957
           locals
1499
           locals
958
             dst_slot   dd ?
1500
             dst_slot   dd ?
-
 
1501
             dst_offset dd ?
959
             dst_offset dd ?
1502
             dst_ptr    dd ?
960
             buf_size   dd ?
1503
             buf_size   dd ?
-
 
1504
             used_buf   dd ?
-
 
1505
             mapped_size dd ?
961
             used_buf   dd ?
1506
             result     dd ?
Line 962... Line 1507...
962
           endl
1507
           endl
963
 
1508
 
Line 964... Line 1509...
964
        pushf
1509
        mov     ecx, ipc_mutex
965
        cli
1510
        call    mutex_lock
966
 
1511
 
967
        mov     eax, [PID]
1512
        mov     eax, [PID]
Line 972... Line 1517...
972
        mov     [dst_slot], eax
1517
        mov     [dst_slot], eax
973
        shl     eax, 8
1518
        shl     eax, 8
974
        mov     edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined?
1519
        mov     edi, [eax+SLOT_BASE+APPDATA.ipc_start] ;is ipc area defined?
975
        test    edi, edi
1520
        test    edi, edi
976
        jz      .no_ipc_area
1521
        jz      .no_ipc_area
-
 
1522
        mov     [dst_ptr], edi
Line 977... Line 1523...
977
 
1523
 
978
        mov     ebx, edi
1524
        mov     ebx, edi
979
        and     ebx, 0xFFF
1525
        and     ebx, 0xFFF
Line 990... Line 1536...
990
        stdcall alloc_kernel_space, esi
1536
        stdcall alloc_kernel_space, esi
991
        mov     ecx, eax
1537
        mov     ecx, eax
992
        pop     edi esi
1538
        pop     edi esi
993
@@:
1539
@@:
994
        mov     [used_buf], ecx
1540
        mov     [used_buf], ecx
995
        stdcall map_mem_ipc, ecx, [dst_slot], \
1541
        stdcall map_memEx, ecx, [dst_slot], \
996
                edi, esi, PG_SWR
1542
                edi, esi, PG_SWR, [ipc_ptab]
-
 
1543
        mov     [mapped_size], eax
-
 
1544
        mov     [result], 3 ; buffer overflow
-
 
1545
        sub     eax, [dst_offset]
-
 
1546
        jc      .no_copy_data
-
 
1547
        cmp     [buf_size], eax
-
 
1548
        jb      @f
-
 
1549
        mov     [buf_size], eax
-
 
1550
@@:
-
 
1551
        cmp     [buf_size], 8
-
 
1552
        jb      .no_copy_data
Line -... Line 1553...
-
 
1553
 
997
 
1554
        mov     [result], 2 ; ipc blocked
998
        mov     edi, [dst_offset]
1555
        mov     edi, [dst_offset]
999
        add     edi, [used_buf]
1556
        add     edi, [used_buf]
1000
        cmp     dword [edi], 0
1557
        cmp     dword [edi], 0
Line -... Line 1558...
-
 
1558
        jnz     .no_copy_data         ;if dword [buffer]<>0 - ipc blocked now
1001
        jnz     .ipc_blocked          ;if dword [buffer]<>0 - ipc blocked now
1559
 
1002
 
1560
        mov     [result], 3 ; buffer overflow
1003
        mov     edx, dword [edi+4]
1561
        mov     edx, dword [edi+4]
1004
        lea     ebx, [edx+8]
1562
        lea     ebx, [edx+8]
1005
        add     ebx, [msg_size]
1563
        add     ebx, [msg_size]
Line -... Line 1564...
-
 
1564
        cmp     ebx, [buf_size]
1006
        cmp     ebx, [buf_size]
1565
        ja      .no_copy_data          ;esi<0 - not enough memory in buffer
1007
        ja      .buffer_overflow       ;esi<0 - not enough memory in buffer
1566
 
1008
 
1567
        mov     [result], 0
1009
        mov     dword [edi+4], ebx
1568
        mov     dword [edi+4], ebx
1010
        mov     eax, [TASK_BASE]
1569
        mov     eax, [TASK_BASE]
Line 1017... Line 1576...
1017
        add     edi, 8
1576
        add     edi, 8
1018
        mov     esi, [msg_addr]
1577
        mov     esi, [msg_addr]
1019
       ;    add esi, new_app_base
1578
       ;    add esi, new_app_base
1020
        cld
1579
        cld
1021
        rep movsb
1580
        rep movsb
-
 
1581
.no_copy_data:
-
 
1582
        stdcall unmap_memEx, [used_buf], [dst_slot], [dst_ptr], [mapped_size], [ipc_ptab]
Line 1022... Line -...
1022
 
-
 
1023
        mov     ebx, [ipc_tmp]
-
 
1024
        mov     edx, ebx
1583
 
1025
        shr     ebx, 12
-
 
1026
        xor     eax, eax
-
 
1027
        mov     [page_tabs+ebx*4], eax
-
 
1028
        invlpg  [edx]
-
 
1029
 
-
 
1030
        mov     ebx, [ipc_pdir]
-
 
1031
        mov     edx, ebx
-
 
1032
        shr     ebx, 12
-
 
1033
        xor     eax, eax
-
 
1034
        mov     [page_tabs+ebx*4], eax
-
 
1035
        invlpg  [edx]
-
 
1036
 
-
 
1037
        mov     ebx, [ipc_ptab]
-
 
1038
        mov     edx, ebx
1584
        cmp     [result], 0
1039
        shr     ebx, 12
-
 
1040
        xor     eax, eax
-
 
1041
        mov     [page_tabs+ebx*4], eax
-
 
1042
        invlpg  [edx]
-
 
1043
 
1585
        jnz     @f
1044
        mov     eax, [dst_slot]
1586
        mov     eax, [dst_slot]
1045
        shl     eax, BSF sizeof.APPDATA
1587
        shl     eax, BSF sizeof.APPDATA
-
 
1588
        or      [eax+SLOT_BASE+APPDATA.occurred_events], EVENT_IPC
-
 
1589
@@:
-
 
1590
        mov     eax, [used_buf]
1046
        or      [eax+SLOT_BASE+APPDATA.occurred_events], EVENT_IPC
1591
        cmp     eax, [ipc_tmp]
-
 
1592
        je      @f
-
 
1593
        stdcall free_kernel_space, eax
-
 
1594
@@:
-
 
1595
        mov     ecx, ipc_mutex
1047
        push    0
1596
        call    mutex_unlock
-
 
1597
        mov     eax, [result]
1048
        jmp     .ret
1598
        ret
-
 
1599
.no_pid:
1049
.no_pid:
1600
        mov     ecx, ipc_mutex
1050
        popf
1601
        call    mutex_unlock
1051
        mov     eax, 4
1602
        mov     eax, 4
1052
        ret
1603
        ret
-
 
1604
.no_ipc_area:
1053
.no_ipc_area:
1605
        mov     ecx, ipc_mutex
1054
        popf
1606
        call    mutex_unlock
1055
        xor     eax, eax
1607
        xor     eax, eax
1056
        inc     eax
1608
        inc     eax
1057
        ret
-
 
1058
.ipc_blocked:
-
 
1059
        push    2
-
 
1060
        jmp     .ret
-
 
1061
.buffer_overflow:
-
 
1062
        push    3
-
 
1063
.ret:
-
 
1064
        mov     eax, [used_buf]
-
 
1065
        cmp     eax, [ipc_tmp]
-
 
1066
        je      @f
-
 
1067
        stdcall free_kernel_space, eax
-
 
1068
@@:
-
 
1069
        pop     eax
-
 
1070
        popf
-
 
1071
        ret
1609
        ret
Line 1072... Line 1610...
1072
endp
1610
endp
1073
 
1611
 
1074
align 4
1612
align 4
Line 1101... Line 1639...
1101
f68:
1639
f68:
1102
        cmp     ebx, 4
1640
        cmp     ebx, 4
1103
        jbe     sys_sheduler
1641
        jbe     sys_sheduler
1104
        cmp     ebx, 11
1642
        cmp     ebx, 11
1105
        jb      undefined_syscall
1643
        jb      undefined_syscall
1106
        cmp     ebx, 29
1644
        cmp     ebx, 32
1107
        ja      undefined_syscall
1645
        ja      undefined_syscall
1108
        xor     eax, eax
1646
        xor     eax, eax
1109
        jmp     dword [f68call+ebx*4-11*4]
1647
        jmp     dword [f68call+ebx*4-11*4]
1110
.11:
1648
.11:
1111
        call    init_heap
1649
        call    init_heap
Line 1222... Line 1760...
1222
 
1760
 
1223
.29:
1761
.29:
1224
        stdcall user_ring, ecx
1762
        stdcall user_ring, ecx
1225
        mov     [esp+SYSCALL_STACK._eax], eax
1763
        mov     [esp+SYSCALL_STACK._eax], eax
-
 
1764
	ret
-
 
1765
.30:
-
 
1766
        cmp     ecx, OS_BASE
-
 
1767
        jae     .fail
-
 
1768
        stdcall load_file_maybe_pe, ecx
-
 
1769
        test    esi, esi
-
 
1770
        jz      .30.not_pe
-
 
1771
        stdcall map_pe_usermode, esi, eax, ebx
-
 
1772
        mov     [esp+32], eax
-
 
1773
        ret
-
 
1774
.30.resolve_fail:
-
 
1775
        movi    eax, -5
-
 
1776
        jmp     .30.error
-
 
1777
.30.not_pe:
-
 
1778
        cmp     eax, -0x1000
-
 
1779
        ja      .30.error
-
 
1780
        stdcall kernel_free, eax
-
 
1781
        movi    eax, -31
-
 
1782
.30.error:
-
 
1783
        mov     [esp+32], eax
-
 
1784
        ret
-
 
1785
 
-
 
1786
.31:
-
 
1787
        stdcall unmap_pe_usermode, ecx
-
 
1788
        mov     [esp+32], eax
-
 
1789
        ret
-
 
1790
 
-
 
1791
.32:
-
 
1792
        stdcall mprotect, edx, esi, ecx
-
 
1793
        mov     [esp+32], eax
Line 1226... Line 1794...
1226
        ret
1794
        ret
1227
 
1795
 
1228
.fail:
1796
.fail:
Line 1249... Line 1817...
1249
           dd f68.25   ; unmask exception
1817
           dd f68.25   ; unmask exception
1250
           dd f68.26   ; user_unmap
1818
           dd f68.26   ; user_unmap
1251
           dd f68.27   ; load_file_umode
1819
           dd f68.27   ; load_file_umode
1252
           dd f68.28   ; loadFileUnicode
1820
           dd f68.28   ; loadFileUnicode
1253
           dd f68.29   ; user_ring
1821
           dd f68.29   ; user_ring
-
 
1822
           dd f68.30   ; map_pe_usermode
-
 
1823
           dd f68.31   ; unmap_pe_usermode
-
 
1824
           dd f68.32   ; mprotect
Line 1254... Line 1825...
1254
 
1825
 
1255
align 4
1826
align 4
1256
proc load_pe_driver stdcall, file:dword, cmdline:dword
1827
proc load_pe_driver stdcall, file:dword, cmdline:dword