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

📄 int21.c

📁 freedos32的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				r->x.dx = 0; /* Revision 0, no flags... */				RMREGS_CLEAR_CARRY;				return;			}			r->h.al = 0xFF; /* Invalid subfunction */			RMREGS_SET_CARRY;			return;		/* DOS 2+ - Get free disk space (DL=drive number, 0=default, 1=A, etc.) */		case 0x36:		{			fd32_getfsfree_t fsfree;			char drive[4] = " :\\";			drive[0] = fd32_get_default_drive();			if (r->h.dl) drive[0] = r->h.dl + 'A' - 1;			fsfree.Size = sizeof(fd32_getfsfree_t);			res = fd32_get_fsfree(drive, &fsfree);			LOG_PRINTF(("INT 21h - Get free disk space for \"%s\", returns %08x\n", drive, res));			LOG_PRINTF(("          Got: %lu secperclus, %lu availclus, %lu bytspersec, %lu totclus\n",			            fsfree.SecPerClus, fsfree.AvailClus, fsfree.BytesPerSec, fsfree.TotalClus));			if (res < 0)			{				r->x.ax = 0xFFFF; /* Unusual way to report error condition */				return;			}			r->x.ax = fsfree.SecPerClus;  /* AX = Sectors per cluster     */			r->x.bx = fsfree.AvailClus;   /* BX = Number of free clusters */			r->x.cx = fsfree.BytesPerSec; /* CX = Bytes per sector        */			r->x.dx = fsfree.TotalClus;   /* DX = Total clusters on drive */			return;		}		/* DOS 2+ - "MKDIR" - Create subdirectory (DS:DX->ASCIZ directory name) */		case 0x39:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			LOG_PRINTF(("INT 21h - Make directory \"%s\"\n", fn));			if (res >= 0) res = fd32_mkdir(fn);			break;		/* DOS 2+ - "RMDIR" - Remove subdirectory (DS:DX->ASCIZ directory name) */		case 0x3A:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			LOG_PRINTF(("INT 21h - Remove directory \"%s\"\n", fn));			if (res >= 0) res = fd32_rmdir(fn);			break;		/* DOS 2+ - "CHDIR" - Set current directory (DS:DX->ASCIZ directory name) */		case 0x3B:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			LOG_PRINTF(("INT 21h - Change directory to \"%s\"\n", fn));			if (res >= 0) res = fd32_chdir(fn);			break;		/* DOS 2+ - "CREAT" - Create or truncate file (DS:DX->ASCIZ file name,		 * CX=attributes, volume label and directory not allowed).		 */		case 0x3C:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			LOG_PRINTF(("INT 21h - Creat \"%s\" with attr %04x\n", fn, r->x.cx));			if (res < 0) break;			res = fd32_open(fn, O_RDWR | O_CREAT | O_TRUNC, r->x.cx, 0, NULL);			res2dos(res, r);			if (res >= 0) r->x.ax = (WORD) res; /* The new handle */			break;		/* DOS 2+ - "OPEN" - Open existing file (DS:DX->ASCIZ file name,		 * AL=opening mode, CL=search attributes for server call).		 */		case 0x3D:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			LOG_PRINTF(("INT 21h - Open \"%s\" with mode %02x\n", fn, r->h.al));			if (res < 0) break;			res = fd32_open(fn, r->h.al, FD32_ANONE, 0, NULL);			res2dos(res, r);			if (res >= 0) r->x.ax = (WORD) res; /* The new handle */			break;		/* DOS 2+ - "CLOSE" - Close file (BX=file handle) */		case 0x3E:			LOG_PRINTF(("INT 21h - Close handle %04x\n", r->x.bx));			res = fd32_close(r->x.bx);			break; /* Recent DOSes preserve AH, we are OK with this */		/* DOS 2+ - "READ" - Read from file or device (BX=file handle,		 * CX=bytes to read, DS:DX->transfer buffer).		 */		case 0x3F:			res = fd32_read(r->x.bx, (void *) FAR2ADDR(r->x.ds, r->x.dx), r->x.cx);			//LOG_PRINTF(("INT 21h - Read (AH=3Fh) from handle %04x (%d bytes). Res=%08xh\n", r->x.bx, r->x.cx, res));			if (res < 0) break;			#if 0 /* FIXME: Can this be removed now? */			/* This is a quick'n'dirty hack to return \n after \r from stdin.  */			/* It works only if console input is on handle 0 and if the number */			/* of bytes to read is greater than the first carriage return.     */			/* TODO: Make this \r\n stuff functional according to the console. */			if (r->x.bx == 0)			{				BYTE *buf = (BYTE *) FAR2ADDR(r->x.ds, r->x.dx);				if (res < r->x.cx) buf[res++] = '\n';			}			#endif			RMREGS_CLEAR_CARRY;			r->x.ax = (WORD) res; /* bytes read */			return;		/* DOS 2+ - "WRITE" - Write to file or device (BX=file handle,		 * CX=bytes to write, DS:DX->transfer buffer).		 */		case 0x40:			res = fd32_write(r->x.bx, (/*const*/ void *) FAR2ADDR(r->x.ds, r->x.dx), r->x.cx);			//LOG_PRINTF(("INT 21h - Write (AH=40h) to handle %04x (%d bytes). Res=%08xh\n", r->x.bx, r->x.cx, res));			res2dos(res, r);			if (res >= 0) r->x.ax = (WORD) res; /* bytes written */			return;		/* DOS 2+ - "UNLINK" - Delete file (DS:DX->ASCIZ file name,		 * CL=search attributes for server call).		 */		case 0x41:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			LOG_PRINTF(("INT 21h - Delete file \"%s\"\n", fn));			if (res >= 0) res = fd32_unlink(fn, FD32_FAALL | FD32_FRNONE);			break;		/* DOS 2+ - "LSEEK" - Set current file position (BX=file handle,		 * CX:DX=offset, AL=origin).		 * FIXME: Replace with off_t		 */		case 0x42:			res = fd32_lseek(r->x.bx, ((long long) r->x.cx << 8) + (long long) r->x.dx, r->h.al, &res64);			res2dos(res, r);			if (res >= 0)			{				r->x.ax = (WORD) res64;				r->x.dx = (WORD) (res64 >> 16);			}			return;		/* DOS 2+ - Get/set file attributes */		case 0x43:			dos_get_and_set_attributes(r);			return;		/* IOCTL functions		 * TODO: They should be done... one day		 */		case 0x44:			res = fd32_get_dev_info(r->x.bx);			if (res < 0)			{				r->x.ax = DOS_EBADF;				RMREGS_SET_CARRY;			}			else			{				r->x.ax = res;				r->x.dx = r->x.ax;				RMREGS_CLEAR_CARRY;			}			return;		/* DOS 2+ - "DUP" - Duplicate file handle (BX=file handle) */		case 0x45:			/* BX file handle */			res = fd32_dup(r->x.bx);			res2dos(res, r);			if (res >= 0) r->x.ax = (WORD) res; /* new handle */			return;		/* DOS 2+ - "DUP2", "FORCEDUP" - Force duplicate file handle		 * (BX=file handle, CX=new handle).		 */		case 0x46:			res = fd32_forcedup(r->x.bx, r->x.cx);			break;		/* DOS 2+ - "CWD" - Get current directory (DL=drive number, 0=default		 * 1=A, etc., DS:DI->64 bytes buffer for ASCIZ path name).		 */		case 0x47:		{			char  drive[2] = "A";			char *c;			char *dest = (char *) FAR2ADDR(r->x.ds, r->x.si);			LOG_PRINTF(("INT 21h - Get current dir of drive %02x\n", r->h.dl));			drive[0] = fd32_get_default_drive();			if (r->h.dl) drive[0] = r->h.dl + 'A' - 1;			res = fd32_getcwd(drive, fn);			if (res < 0) break;			LOG_PRINTF(("After getcwd:\"%s\"\n", fn));			/* Convert all component to 8.3 */			res = fd32_sfn_truename(fn, fn);			if (res < 0) break;			LOG_PRINTF(("After sfn_truename:\"%s\"\n", fn));			/* Skip drive specification and initial backslash as required from DOS */			for (c = fn; *c != '\\'; c++);			strcpy(dest, c + 1);			LOG_PRINTF(("Returned CWD:\"%s\"\n", dest));			r->x.ax = 0x0100; /* Undocumented success return value */			RMREGS_CLEAR_CARRY;			/* TODO: Convert from UTF-8 to OEM */			return;		}		/* DOS 2+ - "EXEC" - Load and/or Execute program */		case 0x4B:		{			ExecParams *pb;			char *args, *p, c[128];			int cnt, i;			pb = (ExecParams *) FAR2ADDR(r->x.es, r->x.bx);			/* Only AH = 0x00 - Load and Execute - is currently supported */			if (r->h.al != 0)			{				r->h.al = 0xFF; /* Invalid subfunction */				RMREGS_SET_CARRY;				return;			}			p = (char *) FAR2ADDR(pb->arg_seg, pb->arg_offs);			cnt = *p++;			if (cnt == 0) {				args = NULL;			} else {				for (i = 0; i < cnt; i++) {				c[i] = *p++;				}				c[i] = 0;				args = c;			}			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			LOG_PRINTF(("INT 21h - Load and Execute \"%s\"\n", fn));			if (res >= 0) res = dos_exec(fn, pb->Env, args, pb->Fcb1, pb->Fcb2, &dos_return_code);			break;		}		/* DOS 2+ - Get return code */		case 0x4D:			RMREGS_CLEAR_CARRY;			r->h.ah = 0; /* Only normal termination, for now... */			r->h.al = dos_return_code;			dos_return_code = 0; /* DOS clears it after reading it */			return;		/* DOS 2+ - "FINDFIRST" - Find first matching file (DS:DX->ASCIZ file spec,		 * CX=allowable attributes (archive and read only ignored),		 * AL=special flag for append (ignored).		 */		case 0x4E:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			LOG_PRINTF(("INT 21h - Findfirst \"%s\" with attr %04x\n", fn, r->x.cx));			if (res < 0) break;			res = fd32_dos_findfirst(fn, r->x.cx, current_psp->dta);			LOG_PRINTF(("a\n"));			res2dos(res, r);			LOG_PRINTF(("b\n"));			if (res == -ENOENT) r->x.ax = DOS_ENOMOREF;			LOG_PRINTF(("c\n"));			return;		/* DOS 2+ - "FINDNEXT" - Find next matching file */		case 0x4F:			LOG_PRINTF(("INT 21h - Findnext\n"));			res = fd32_dos_findnext(current_psp->dta);			res2dos(res, r);			if (res == -ENOENT) r->x.ax = DOS_ENOMOREF;			return;		/* DOS 2+ - "RENAME" - Rename or move file (DS:DX->old name,		 * ES:DI->new name, CL=attributes for server call).		 */		case 0x56:		{			char newfn[FD32_LFNPMAX];			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			if (res < 0) break;			res = fix_path(newfn, (const char *) FAR2ADDR(r->x.es, r->x.di), sizeof(newfn));			if (res < 0) break;			LOG_PRINTF(("INT 21h - Renaming \"%s\" to \"%s\"\n", fn, newfn));			res = fd32_rename(fn, newfn);			break;		}		/* DOS 2+ - Get/set file's time stamps */		case 0x57:			get_and_set_time_stamps(r);			return;		/* DOS 3.0+ - Create new file (DS:DX->ASCIZ file name, CX=attributes) */		case 0x5B:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			LOG_PRINTF(("INT 21h - Creating new file (AH=5Bh) \"%s\" with attr %04x\n", fn, r->x.cx));			if (res < 0) break;			res = fd32_open(fn, O_RDWR | O_CREAT | O_EXCL, r->x.cx, 0, NULL);			res2dos(res, r);			if (res >= 0) r->x.ax = (WORD) res; /* The new handle */			return;		/* DOS 3.0+ - Get current PSP address */		case 0x62:			LOG_PRINTF(("INT 21h - Get current PSP address\n"));			r->x.bx = (DWORD) current_psp >> 4;			return;		/* DOS 3.3+ - "FFLUSH" - Commit file		 * and DOS 4.0+ Undocumented - Commit file (BX=file handle).		 */		case 0x68:		case 0x6A:			LOG_PRINTF(("INT 21h - fflush\n"));			/* BX file handle */			res = fd32_fflush(r->x.bx);			break;		/* DOS 5+ Undocumented - Null function */		case 0x6B:			LOG_PRINTF(("INT 21h - Null function. Hey, somebody calls it!\n"));			r->h.al = 0;			RMREGS_CLEAR_CARRY;			return;		/* DOS 4.0+ - Extended open/create file (AL=00h, BL=access and sharing mode,		 * BH=flags, CX=attributes for creation, DL=action, DH=00h, DS:DI->ASCIZ file name).		 */		case 0x6C:		{			int action;			res = parse_open_action(r->x.dx);			if (res < 0) break;			action = res;			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.si), sizeof(fn));			if (res < 0) break;			res = fd32_open(fn, action | (DWORD) r->x.bx, r->x.cx, 0, &action);			LOG_PRINTF(("INT 21h - Extended open/create (AH=6Ch) \"%s\" res=%08xh\n", fn, res));			res2dos(res, r);			if (res >= 0)			{				r->x.ax = (WORD) res; /* The new handle */				r->x.cx = (WORD) action; /* Action taken */			}			return;		}		/* Long File Name functions */		case 0x71:			if (use_lfn) lfn_functions(r);			else			{				r->x.ax = 0x7100; /* Yet another convention */				RMREGS_SET_CARRY;			}			return;		/* Windows 95 beta - "FindClose" - Terminate directory search		* _Guessing_ that BX is the directory handle.		*/		case 0x72:			res = fd32_lfn_findclose(r->x.bx);			break;		/* Windows 95 FAT32 services.		 * Only AH=03h "Get extended free space on drive" is currently supported.		 */		case 0x73:		{			ExtDiskFree *edf;			fd32_getfsfree_t fsfree;			LOG_PRINTF(("INT 21h - FAT32 service %02x issued\n", r->h.al));			if (r->h.al != 0x03)			{				r->h.al = 0xFF; /* Unimplemented subfunction */				RMREGS_SET_CARRY;				return;			}			/* DS:DX->ASCIZ string for drive ("C:\" or "\\SERVER\Share")			 * ES:DI->Buffer for extended free space structure (ExtFreSpace)			 * CX=size of ES:DI buffer			 */			if (r->x.cx < sizeof(ExtDiskFree))			{				r->x.ax = DOS_EBUFSMALL;				RMREGS_SET_CARRY;				return;			}			edf = (ExtDiskFree *) FAR2ADDR(r->x.es, r->x.di);			if (edf->Version != 0x0000)			{				r->x.ax = DOS_EINVAL;				RMREGS_SET_CARRY;				return;			}			fsfree.Size = sizeof(fd32_getfsfree_t);			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			if (res < 0) break;			res = fd32_get_fsfree(fn, &fsfree);			if (res >= 0)			{				edf->Size = sizeof(ExtDiskFree);				/* Currently we don't support volume compression */				edf->SecPerClus  = fsfree.SecPerClus;				edf->BytesPerSec = fsfree.BytesPerSec;				edf->AvailClus   = fsfree.AvailClus;				edf->TotalClus   = fsfree.TotalClus;				edf->RealSecPerClus  = fsfree.SecPerClus;				edf->RealBytesPerSec = fsfree.BytesPerSec;				edf->RealAvailClus   = fsfree.AvailClus;				edf->RealTotalClus   = fsfree.TotalClus;			}			break;		}		/* Unsupported or invalid functions */		default:			r->x.ax = DOS_ENOTSUP;			RMREGS_SET_CARRY;			return;	}	res2dos(res, r);}

⌨️ 快捷键说明

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