⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manager.asm

📁 独立 WIN98下磁盘分区程序(C语言+汇编) 界面功能类似FDISK 但独立编译
💻 ASM
📖 第 1 页 / 共 3 页
字号:
		cmp	ax, NUM_MENUS
		jb	@@boot_n_short
		jmp	@@wait_key
	@@up:
		cmp	ACT_MENU, 0
		jz	@@cont2short
		dec	ACT_MENU
		jmp	@@cont2
	@@down:
		mov	ax, NUM_MENUS
		dec	ax
		jb	@@cont2short
		cmp	ACT_MENU, ax
		jnb	@@cont2short
		inc	ACT_MENU
		jmp	@@cont2
	@@home:
		mov	ACT_MENU, 0
		jmp	@@cont2
	@@end:
		mov	ax, NUM_MENUS
		dec	ax
		jb	@@cont2short
		mov	ACT_MENU, ax
		jmp	@@cont2
	@@space:
		call	SETUP_MENU
		xor	di, di
		jmp	@@while1
	@@boot_a_short:
		jmp	@@boot_a
	@@boot_d_short:
		jmp	@@boot_d
	@@boot_n_short:
		jmp	@@boot_n
	@@boot2short:
		jmp	@@boot
	@@alt_boot2short:
		jmp	@@alt_boot
	@@cont2short:
		jmp	@@cont2
	@@boot_esc2short:
		jmp	@@boot_esc
	@@hide_all:
		mov	bx, 0
		call	CHECK_PASSWORD
		jc	@@cont2short
		mov	ax, ACT_MENU
		push	ax
		mov	ax, -1
		mov	ACT_MENU, ax
		mov	dl, 0
		call	PREP_BOOT_SECT_X
		pop	ax
		mov	ACT_MENU, ax
		jnc	@@break_out_short
		jmp	@@cont2
	@@break_out_short:
		jmp	@@break_out
	@@alt_boot:
		mov	ALT_ENTER, 1
		jmp	@@boot
	@@boot_a:
		mov	bx, 0
		call	CHECK_PASSWORD
		jc	@@cont2short
		mov	dl, 0
		call	PREP_BOOT_SECT_X
		jnc	@@break_out_short
		jmp	@@cont2
	@@boot_d:
		mov	bx, 0
		call	CHECK_PASSWORD
		jc	@@cont2short
		mov	dl, DISK
		inc	dl
		call	PREP_BOOT_SECT_X
		jnc	@@break_out
		jmp	@@cont2
	@@boot_n:
		mov	ACT_MENU, ax
	@@boot:
		cmp	NUM_MENUS, 0
		je	@@boot_a
		mov	bx, ACT_MENU
		shl	bx, 1
		mov	ax, MENU_PTR[bx]
		lea	bx, menu
		sub	ax, bx
		mov	bl, SIZE adv_menu_rec
		div	bl
		mov	adv_act_menu, al
	@@boot_esc:
		cmp	NUM_MENUS, 0
		je	@@boot_a
		

		mov	bx, ACT_MENU
		shl	bx, 1
		mov	bx, MENU_PTR[bx]

		push	bx
		call	CHECK_PASSWORD
		pop	bx
		jc	@@cont2

		cmp	[bx].m_type, M_BOOT_PART
		je	@@boot_type_part
		cmp	[bx].m_type, M_BOOT_NEXT_HD
		je	@@boot_type_next_hd
		cmp	[bx].m_type, M_BOOT_FLOPPY
		je	@@boot_type_floppy
		jmp	@@cont2		; We dont know what it is - ingnoring 
@@boot_type_part:
		call	PREP_BOOT_SECT
		jnc	@@break_out
		jmp	@@cont2
@@boot_type_next_hd:
		mov	dl, DISK
		inc	dl
		call	PREP_BOOT_SECT_X
		jc	@@cont2
		call	FILL_KEYB_BUFFER
		jmp	@@break_out
@@boot_type_floppy:
		mov	dl, 0
		call	PREP_BOOT_SECT_X
		jc	@@cont2
		call	FILL_KEYB_BUFFER
		jmp	@@break_out
	@@cont2:
		mov	di, 1
		jmp	@@while1
	@@break_out:
		ret
MAIN_MENU	ENDP
		;
		;
CHECK_PASSWORD	PROC	NEAR
		;
		; Input:   bx - pointer to ActiveMenu, or 0 if no menu
		;
		; Output:  CF - clear if password validated
		;	   CF - set if user cannot proceed
		;
		PUSH_REGS

		cmp	PASS_VALIDATED, 1
		je	@@valid

		cmp	bx, 0
		jz	@@do_check

		test	[bx].m_options, M_OPT_PASSW
		jz	@@valid		; This menu item needs no validation
@@do_check:
		cmp	adv_password, 0
		je	@@valid		; No master password set

		call	GET_PASSWORD

		cmp	ax, adv_password
		je	@@valid
@@invalid:
		lea	si, MesgPasswordInvalid
		call	SHOW_ERROR
		stc
		jmp	@@end
@@valid:
		mov	PASS_VALIDATED, 1
      		clc
@@end:
		POP_REGS
		ret
CHECK_PASSWORD	ENDP
		;
		;
		;
PREP_BOOT_SECT	PROC	NEAR
		;
		;  Output:  CF - set if error
		;
		PUSH_REGS
		
		call	MAKE_PART_TAB
		
		mov	di, ACT_MBR_REC

		mov	bx, Offset OS_BOOT_SECT
		mov	dx, [di]
		mov	cx, [di+2]
		call	READ_SECT
		jc	@@err_read
		
		mov	di, Offset OS_BOOT_SECT
		mov	cx, 512
		mov	al, 0
		repe
		   scasb
		jcxz	@@sect_empty

		call	COMPARE_MBR_SECT	; did we change boot sector
		jnc	@@not_changed		; no need to save

		mov	bx, Offset MBR_SECT
		xor	dx, dx
		xor	ax, ax
		mov	cx, 1
		call	WRITE_N_SECT
		jc	@@err_save
@@not_changed:
		call	FILL_KEYB_BUFFER
		clc
		jmp	@@end
@@err_read:
		lea	si, MesgErrorRead
		call	SHOW_ERROR
		stc
		jmp	@@end
@@sect_empty:
		lea	si, MesgBootInvalid
		call	SHOW_ERROR
		stc
		jmp	@@end
@@err_save:
		lea	si, MesgErrorSave
		call	SHOW_ERROR
		stc
@@end:
		POP_REGS
		ret
PREP_BOOT_SECT	ENDP
		;
		;
PREP_BOOT_SECT_X PROC	NEAR
		;
		; Input:   DL - Disk number
		; Output:  CF - set if error
		;
		PUSH_REGS
		
		push	dx
		call	MAKE_PART_TAB
		pop	dx
		
		lea	di, FD_PARAMS
		mov	cx, 1
		mov	dh, 0
		mov	[di], dx
		mov	[di+2],cx
		mov	ACT_MBR_REC, di
		mov	bx, Offset OS_BOOT_SECT

		call	READ_SECT
		jc	@@err_read

		call	COMPARE_MBR_SECT	; did we change boot sector
		jnc	@@not_changed		; no need to save

		mov	bx, Offset MBR_SECT
		xor	dx, dx
		xor	ax, ax
		mov	cx, 1
		call	WRITE_N_SECT
		jc	@@err_save
@@not_changed:
		clc
		jmp	@@end
@@err_read:
		lea	si, MesgErrorRead
		call	SHOW_ERROR
		stc
		jmp	@@end
@@err_save:
		lea	si, MesgErrorSave
		call	SHOW_ERROR
		clc			; We still want to boot from A: (or D:)
@@end:
		POP_REGS
		ret
PREP_BOOT_SECT_X ENDP
		;
		;
		;
BACKUP_MBR_SECT PROC	NEAR
		push	cx
		push	si
		push	di

		mov	cx, 512
		mov	si, Offset MBR_SECT
		mov	di, Offset MBR_SECT_BAK
		
		rep
		  movsb

		pop	di
		pop	si
		pop	cx
		ret
BACKUP_MBR_SECT ENDP
		;
		;
		;
COMPARE_MBR_SECT PROC	NEAR
		;
		; CF - set if boot sector was changed
		;
		push	cx
		push	si
		push	di

		mov	cx, 512
		mov	si, Offset MBR_SECT
		mov	di, Offset MBR_SECT_BAK
		
		repe
		 cmpsb

		je	@@equal
		stc
		jmp	@@end
	@@equal:
		clc
	@@end:
		pop	di
		pop	si
		pop	cx
		ret
COMPARE_MBR_SECT ENDP
		;
		;
		;
MAKE_PART_TAB	PROC	NEAR
		;
		;  Input:  ACT_MENU
		;
		;  Output: ACT_MBR_REC - points to active mbr_part_rec
		;
		push	bp

		mov	ACT_PART_PTR, 0
		;
		;  Clearing PART_TMP and MBR part_rec
		;
		xor	ax, ax
		lea	di, PART_TMP
		mov	cx, SIZE PART_TMP
		rep
		  stosb
		lea	di, PART_TMP2
		mov	cx, SIZE PART_TMP2
		rep
		  stosb
		lea	di, part_rec
		mov	cx, SIZE part_rec
		rep
		  stosb
		;
		; Lets find last partition
		;
		xor	bp, bp
		xor	si, si
		lea	di, part
		mov	cx, MAX_PART_ROWS
		mov	bx, di
@@next_step:
		mov	ax, Word Ptr [di].p_num_sect
		or	ax, Word Ptr [di].p_num_sect+2
		jz	@@last_found
		add	di, SIZE adv_part_rec
		loop	@@next_step
@@last_found:
		cmp	bx, di
		je	@@show_one_je_short
		sub	di, SIZE adv_part_rec

		cmp	NUM_MENUS, 0
@@show_one_je_short:
		je	@@show_one

		mov	bx, ACT_MENU
		cmp	bx, -1
		je	@@show_unused
		shl	bx, 1
		mov	si, MENU_PTR[bx]
		mov	al, [si].m_show
		mov	si, PART_PTR[bx]
		mov	ACT_PART_PTR, si
		cmp	si, 0
		jne	@@not_zero
		xor	di, di		; No partition associated with menu
		xor	bp, bp		; so we will hide everything
		jmp	@@eval_part
	@@not_zero:
		;
		;  SI -> active partition
		;  DI -> last partition
		;  AL - representation mode
		;
		cmp	al, SHOW_NEXT
		je	@@show_next
		cmp	al, SHOW_PREV
		je	@@show_prev
		cmp	al, SHOW_LAST
		je	@@show_last
		cmp	al, SHOW_LAST3
		je	@@show_last3
		jmp	@@show_one
@@show_prev:
		lea	bx, part
		cmp	bx, si
		je	@@show_one
		mov	di, si
		sub	si, SIZE adv_part_rec
		jmp	@@eval_part
@@show_next:
		cmp	si, di
		je	@@show_one
		mov	di, si
		add	di, SIZE adv_part_rec
		jmp	@@eval_part
@@show_last:
		cmp	si, di
		jne	@@eval_part
		jmp	@@show_one
@@show_last3:
		push	di
		sub	di, SIZE adv_part_rec
		sub	di, SIZE adv_part_rec
		cmp	di, Offset part
		jnb	@@now_check_si
		pop	di
		jmp	@@show_last
@@now_check_si:
		cmp	si, di
		pop	di
		jb	@@show_last
		mov	bp, di
		sub	di, SIZE adv_part_rec
		mov	si, di
		sub	si, SIZE adv_part_rec
		jmp	@@eval_part
@@show_one:
		xor	di, di
		jmp	@@eval_part
@@show_unused:					; Show first unused space
		xor	di, di			; greater than 63 sectors
		lea	si, part
		mov	cx, MAX_PART_ROWS
@@unused_next:
		cmp	[si].p_os_id, 0
		jne	@@unused_cont
		cmp	Word Ptr [si].p_num_sect+2, 0
		jne	@@eval_part
		cmp	Word Ptr [si].p_num_sect, 63
		ja	@@eval_part
@@unused_cont:
		add	si, SIZE adv_part_rec
		loop	@@unused_next
		xor	si, si			; didn't find any
@@eval_part:
		;
		;  SI -> first partition, or zero
		;  DI -> second partition, or zero
		;  BP -> third partition, or zero
		;
		lea	bx, part
		mov	ax, Word Ptr [bx].p_rel_sect
		mov	dx, Word Ptr [bx].p_rel_sect+2
		
		lea	bx, PART_TMP
		mov	cx, 0

		mov	LAST_PART, 0
@@next_row:
		cmp	si, 0
		jne	@@check_gap
		jmp	@@tail
@@check_gap:
		cmp	Word Ptr [si].p_rel_sect+2, dx
		ja	@@fill_gap
		cmp	Word Ptr [si].p_rel_sect, ax
		ja	@@fill_gap

		mov	ax, [si].p_os_id
		mov	[bx].p_os_id, ax
		mov	al, [si].p_orig_row
		mov	[bx].p_orig_row, al
		mov	al, 0
		cmp	si, ACT_PART_PTR
		jne	@@not_active
		mov	al, DISK
@@not_active:
		mov	[bx].p_tag, al

		mov	ax, Word Ptr [si].p_rel_sect
		mov	dx, Word Ptr [si].p_rel_sect+2
		mov	Word Ptr [bx].p_rel_sect, ax
		mov	Word Ptr [bx].p_rel_sect+2, dx
		mov	ax, Word Ptr [si].p_num_sect
		mov	dx, Word Ptr [si].p_num_sect+2
		mov	Word Ptr [bx].p_num_sect, ax
		mov	Word Ptr [bx].p_num_sect+2, dx
		add	ax, Word Ptr [si].p_rel_sect
		adc	dx, Word Ptr [si].p_rel_sect+2

		mov	LAST_PART, si
		mov	si, di
		mov	di, bp
		mov	bp, 0
		add	bx, SIZE adv_part_rec
		inc	cx
		cmp	cx, 4
		je	@@table_filled_short
		jmp	@@next_row
@@table_filled_short:
		jmp	@@table_filled
@@fill_gap:
		test	adv_options, ADV_OPT_IGN_UNUSED
		jz	@@go_fill_gap
		cmp	LAST_PART, 0
		je	@@go_fill_gap
		push	si
		sub	si, SIZE adv_part_rec
		cmp	si, LAST_PART
		pop	si
		jne	@@go_fill_gap
		mov	ax, Word Ptr [si].p_rel_sect
		mov	dx, Word Ptr [si].p_rel_sect+2
		jmp	@@next_row
@@go_fill_gap:

		mov	[bx].p_os_id, OS_HIDDEN
		mov	[bx].p_tag, 0
		mov	[bx].p_orig_row, 0
		mov	Word Ptr [bx].p_rel_sect, ax
		mov	Word Ptr [bx].p_rel_sect+2, dx
		mov	ax, Word Ptr [si].p_rel_sect
		mov	dx, Word Ptr [si].p_rel_sect+2
		sub	ax, Word Ptr [bx].p_rel_sect
		sbb	dx, Word Ptr [bx].p_rel_sect+2
		mov	Word Ptr [bx].p_num_sect, ax
		mov	Word Ptr [bx].p_num_sect+2, dx
		mov	ax, Word Ptr [si].p_rel_sect
		mov	dx, Word Ptr [si].p_rel_sect+2
		
		add	bx, SIZE adv_part_rec
		inc	cx
		cmp	cx, 4
		je	@@table_filled
		jmp	@@next_row
@@tail:
		mov	Word Ptr [bx].p_rel_sect, ax
		mov	Word Ptr [bx].p_rel_sect+2, dx
		mov	ax, SECT_PER_CYL
		mov	dx, DISK_NUM_CYLS
		mul	dx
		sub	ax, Word Ptr [bx].p_rel_sect
		sbb	dx, Word Ptr [bx].p_rel_sect+2
		mov	Word Ptr [bx].p_num_sect, ax
		mov	Word Ptr [bx].p_num_sect+2, dx
		or	ax, dx				; is part size zero
		jz	@@table_filled

		mov	[bx].p_os_id, OS_HIDDEN
		mov	[bx].p_tag, 0
		mov	[bx].p_orig_row, 0

@@table_filled:
		;
		;	Now lets make sure that active partition occupies
		;	slot in partition table from which it was taken
		;
@@check_locations:
		mov	cx, 4
		lea	si, PART_TMP
@@check_next_part:
		mov	ah, 0
		mov	al, [si].p_orig_row
		cmp	al, 0
		jne	@@row_is_not_0
		add	si, SIZE adv_part_rec
		loop	@@check_next_part
		jmp	@@nothing_to_move
@@row_is_not_0:
		dec	ax
		mov	bl, SIZE adv_part_rec
		mul	bl
		lea	bx, PART_TMP
		add	bx, ax
		cmp	bx, si
		je	@@part_in_place

		push	bx	; that's where partition supposed to be
		push	si	; that's where it is
		lea	di, PART_TMP2
		mov	cx, SIZE adv_part_rec
		rep		; moving partition to PART_TMP2
		  movsb
		pop	di
		pop	si
		push	si
		mov	cx, SIZE adv_part_rec
		rep		; moving whatever occupies place out
		  movsb
		pop	di
		push	di
		lea	si, PART_TMP2
		mov	cx, SIZE adv_part_rec
		rep		; moving partition to its proper place
		  movsb
		pop	si
@@part_in_place:
		mov	[si].p_orig_row, 0	; so we won't move it again
		jmp	@@check_locations
@@nothing_to_move:
		;
		;	Converting temporary structures
		;	into records in the partition table
		;
		mov	cx, 4
		lea	si, PART_TMP
		lea	di, part_rec
@@next_part_rec:
		push	cx
		push	si
		push	di
		cmp	[si].p_os_id, 0
		je	@@cont
		mov	ax, Word Ptr [si].p_rel_sect
		mov	dx, Word Ptr [si].p_rel_sect+2
		push	dx
		push	ax
		call	REL_SECT_TO_CHS
		mov	dl, [si].p_tag
		or	dl, dl
		jz	@@part_not_active
		mov	ACT_MBR_REC, di
@@part_not_active:
		mov	ax, dx
		stosw
		mov	ax, cx
		stosw
		pop	ax
		pop	dx
		add	ax, Word Ptr [si].p_num_sect
		adc	dx, Word Ptr [si].p_num_sect+2
		sub	ax, 1
		sbb	dx, 0
		call	REL_SECT_TO_CHS
		mov	dl, Byte Ptr [si].p_os_id+1
		mov	ax, dx
		stosw
		mov	ax, cx
		stosw
		lea	si, [si].p_rel_sect
		movsw
		movsw
		movsw
		movsw
	@@cont:
		pop	di
		pop	si
		add	si, SIZE adv_part_rec
		add	di, SIZE mbr_part_rec
		pop	cx
		loop	@@next_part_rec
	@@end:
		pop	bp
		ret		
MAKE_PART_TAB	ENDP
		;
		;
		;
IMPORT_NEW_PART	PROC	NEAR
		push	bp
		mov	IMPORTED_FLAG, 0
		mov	cx, 1
		lea	si, part_rec
@@next_mbr_part:
		push	cx
		cmp	[si].b_os_id, 0		; Unused - ignore it
		je	@@mbr_cont_short
		cmp	[si].b_os_id, 0FFh	; Hidden - ignore it
		je	@@mbr_cont_short
		jmp	@@test_part
@@mbr_cont_short:
		jmp	@@mbr_cont
     @@test_part:
		mov	ax, Word Ptr [si].b_rel_sect
		mov	dx, Word Ptr [si].b_rel_sect+2
		push	ax
		or	ax, dx
		pop	ax
		jz	@@mbr_cont		; Empty - ignore it
		mov	cx, MAX_PART_ROWS
		lea	di, part
     @@next_part:
     		cmp	ax, Word Ptr [di].p_rel_sect
     		jne	@@part_cont
     		cmp	dx, Word Ptr [di].p_rel_sect+2
     		jne	@@part_cont
     		; Relative sectors matched
		mov	ax, Word Ptr [si].b_num_sect
		mov	dx, Word Ptr [si].b_num_sect+2

     		cmp	ax, Word Ptr [di].p_num_sect
     		jne	@@import_part
     		cmp	dx, Word Ptr [di].p_num_sect+2
     		jne	@@import_part
     		; Number of sectors also same
     		jmp	@@check_id
     @@part_cont:
     		add	di, SIZE adv_part_rec
     		loop	@@next_part
     		jmp	@@import_part
      @@check_id:
      		mov	ax, [di].p_os_id
      		cmp	ax, OS_ADV
      		je	@@import_part
      		cmp	ah, [si].b_os_id
      		je	@@mbr_cont
      		mov	ah, [si].b_os_id
      		mov	al, 0
      		mov	[di].p_os_id, ax
      		mov	IMPORTED_FLAG, 1
      		jmp	@@mbr_cont
     @@import_part:
     		mov	cx, MAX_PART_ROWS
     		lea	di, part + SIZE part
     @@step_back:
     		sub	di, SIZE adv_part_rec
     		cmp	[di].p_os_id, 0
     		je	@@copy_part
     		loop	@@step_back
     		jmp	@@mbr_cont
     @@copy_part:
     		mov	ah, [si].b_os_id
     		mov	al, 0
     		stosw	; p_os_id
     		mov	al, 0
     		stosb	; p_tag
     		pop	ax
     		push	ax
     		stosb	; p_orig_row
     		xor	ax, ax
     		stosw	; reserved
     		stosw	; reserved
     		push	si
     		add	si, 8
     		movsw	; rel_sect
     		movsw
     		movsw	; num_sect
     		movsw
     		pop	si
      		mov	IMPORTED_FLAG, 10h
@@mbr_cont:
		add	si, SIZE mbr_part_rec
		pop	cx
		inc	cx
		cmp	cx, 5
		je	@@break_out
		jmp	@@next_mbr_part
@@break_out:
		cmp	IMPORTED_FLAG, 0
		je	@@end

		mov	ax, Word Ptr ADV_REL_SECT
		mov	dx, Word Ptr ADV_REL_SECT+2

		mov	bx, ADV_DATA_ADDR
		mov	cx, ADV_DATA_SECT
		
		call	WRITE_N_SECT
		jnc	@@end
		lea	si, MesgErrorSaveAdv
		call	SHOW_ERROR
	@@end:
		pop	bp
		ret
IMPORT_NEW_PART	ENDP
		;
		;
		;
SPRINTF_MENU	PROC	NEAR
		;
		;  Input:  AX - Menu number
		;  Output: TMP - Filled with menu line
		;
		PUSH_REGS
		push	ax
		inc	ax
		lea	si, TMP
		mov	cx, 3
		call	SPRINTF_INT
		lea	di, TMP+3
		mov	al, ' '
		stosb
		stosb
		mov	cx, 30
		pop	bx
		shl	bx, 1
		mov	si, MENU_PTR[bx]
		lea	si, [si].m_name
	@@char:
		lodsb
		or	al, al
		jz	@@break
		stosb
		loop	@@char
	@@break:
		mov	al, ' '
		jcxz	@@no_spaces
	@@space:
		rep
		 stosb
	@@no_spaces:
		stosb
		mov	si, PART_PTR[bx]
		cmp	si, 0
		je	@@no_part
		mov	ax, Word Ptr [si].p_num_sect
		mov	dx, Word Ptr [si].p_num_sect+2
		mov	cl, 11
		shr	ax, cl
		mov	cl, 5
		shl	dx, cl
		or	ax, dx
		mov	cx, 6
		mov	si, di
		call	SPRINTF_INT
		add	di, 6
		mov	al, 'M'
		stosb
		mov	al, ' '
		stosb
		jmp	@@end
	@@no_part:
		mov	cx, 8
		mov	al,' '
		rep
		 stosb
	@@end:
		mov	al, 0
		stosb
		POP_REGS
		ret
SPRINTF_MENU	ENDP
		;
		;
		;
SPRINTF_INT	PROC	NEAR
		;
		;  Input:  AX - Integer to print
		;          CX - Field len
		;       DS:SI - String to fill
		;
		PUSH_REGS
		mov	di, cx
		mov	bx, 10
		xor	cx, cx
@@next:
		xor	dx, dx
		div	bx
		push	dx
		inc	cx
		cmp	ax, 0
		jne	@@next
		mov	bx, di
		cmp	cx, bx
		jae	@@digit
		sub	bx, cx
		mov	al, ' '
@@space:
		mov	[si], al
		inc	si
		dec	bx
		jne	@@space
@@digit:
		pop	ax
		add	ax, '0'
		mov	[si], al
		inc	si
		dec	cx
		jne	@@digit

		xor	ax, ax
		mov	[si], al
		POP_REGS
		ret
SPRINTF_INT	ENDP
		;
		;
		;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -