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

📄 int21.c

📁 freedos32的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}	fd32_close(fd);	res2dos(res, r);}/* Sub-handler for LFN service "Extended get/set attributes" * INT 21h AX=7143h (DS:DX->ASCIZ file name, BL=action). */static inline void lfn_get_and_set_attributes(union rmregs *r){	char fn[FD32_LFNPMAX];	fd32_fs_attr_t a;	int fd;	int res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));	if (res < 0)	{		res2dos(res, r);		return;	}	fd = fd32_open(fn, O_RDWR, FD32_ANONE, 0, NULL);	if (fd < 0) /* It could be a directory... */		fd = fd32_open(fn, O_RDWR | O_DIRECTORY, FD32_ANONE, 0, NULL);	if (fd < 0)	{		res2dos(res, r);		return;	}	a.Size = sizeof(fd32_fs_attr_t);	switch (r->h.bl)	{		/* Get file attributes */		case 0x00:			res = fd32_get_attributes(fd, &a);			if (res >= 0) r->x.cx = a.Attr;			break;		/* Set file attributes */		case 0x01:			res = fd32_get_attributes(fd, &a);			if (res >= 0)			{				a.Attr = r->x.cx;				res = fd32_set_attributes(fd, &a);			}			break;		/* Get physical size of compressed file */		/* case 0x02: Not implemented */		/* Set last modification date and time */		case 0x03:			res = fd32_get_attributes(fd, &a);			if (res >= 0)			{				a.MDate = r->x.di;				a.MTime = r->x.cx;				res = fd32_set_attributes(fd, &a);			}			break;		/* Get last modification date and time */		case 0x04:			res = fd32_get_attributes(fd, &a);			if (res >= 0)			{				r->x.di = a.MDate;				r->x.cx = a.MTime;			}			break;		/* Set last access date */		case 0x05:			/* DI new date in DOS format */			res = fd32_get_attributes(fd, &a);			if (res >= 0)			{				a.ADate = r->x.di;				res = fd32_set_attributes(fd, &a);			}			break;		/* Get last access date */		case 0x06:			res = fd32_get_attributes(fd, &a);			if (res >= 0) r->x.di = a.ADate;			break;		/* Set creation date and time */		case 0x07:			res = fd32_get_attributes(fd, &a);			if (res >= 0)			{				a.CDate = r->x.di;				a.CTime = r->x.cx;				a.CHund = r->x.si;				res = fd32_set_attributes(fd, &a);			}			break;		/* Get creation date and time */		case 0x08:			res = fd32_get_attributes(fd, &a);			if (res >= 0)			{				r->x.di = a.CDate;				r->x.cx = a.CTime;				r->x.si = a.CHund;			}			break;		/* Unsupported or invalid actions */		default:			fd32_close(fd);			r->x.ax = 0x7100; /* Yet another convention */			RMREGS_SET_CARRY;			return;	}	fd32_close(fd);	res2dos(res, r);}/* Sub-handler for Long File Names services * INT 21h AH=71h (AL=function) */static inline void lfn_functions(union rmregs *r){	char fn[FD32_LFNPMAX];	int res;	switch (r->h.al)	{		/* Make directory (DS:DX->ASCIZ directory name) */		case 0x39:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			if (res >= 0) res = fd32_mkdir(fn);			break;		/* Remove directory (DS:DX->ASCIZ directory name) */		case 0x3A:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			if (res >= 0) res = fd32_rmdir(fn);			break;		/* Change directory (DS:DX->ASCIZ directory name) */		case 0x3B:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			if (res >= 0) res = fd32_chdir(fn);			break;		/* Delete file (DS:DX->ASCIZ file name, CL=search attributes,		 * CL=must-match attributes, SI=use wildcards and attributes [0=no,1=yes]).		 * FIXME: Parameter in SI not used.		 */		case 0x41:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			if (res >= 0) res = fd32_unlink(fn, ((DWORD) r->h.ch << 8) + (DWORD) r->h.cl);			break;		/* Extended get/set file attributes */		case 0x43:			lfn_get_and_set_attributes(r);			return;		/* Get current directory (DL=drive number [0=default, 1=A, etc.],		 * DS:SI->260-bytes buffer for ASCIZ pathname).		 * Same as INT 21h AH=47h, but we don't convert to 8.3 the resulting path		 */		case 0x47:		{			char  drive[2] = "A";			char *dest = (char *) FAR2ADDR(r->x.ds, r->x.si);			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)			{				strcpy(dest, fn + 1); /* Skip leading backslash */				/* FIXME: Convert from UTF-8 to OEM */			}			break;		}		/* Find first matching file (DS:DX->ASCIZ file spec, ES:DI->find data record,		 * CL=allowable attributes, CH=required attributes, SI=date/time format		 * [0=Windows time, 1=DOS time]).		 * FIXME: Parameter in SI not used.		 */		case 0x4E:			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			if (res < 0) break;			res = fd32_lfn_findfirst(fn, ((DWORD) r->h.ch << 8) + (DWORD) r->h.cl,			                         (fd32_fs_lfnfind_t *) FAR2ADDR(r->x.es, r->x.di));			res2dos(res, r);			if (res >= 0)			{				r->x.ax = (WORD) res; /* The directory handle to continue the search */				/* FIXME: Unicode conversion flags in CX not implemented				 * bit 0 set if the returned long name contains				 *  underscores for unconvertable Unicode characters				 * bit 1 set if the returned short name contains				 *  underscores for unconvertable Unicode characters				 */				r->x.cx = 0; 			}			else if (res == -ENOENT) r->x.ax = DOS_ENOMOREF;			return;		/* Find next matching file (ES:DI->find data record, BX=directory handle,		 * SI=date/time format [0=Windows time, 1=DOS time]).		 * FIXME: Same FIXMEs as case 0x4E.		 */		case 0x4F:			res = fd32_lfn_findnext(r->x.bx, 0, (fd32_fs_lfnfind_t *) FAR2ADDR(r->x.es, r->x.di));			res2dos(res, r);			if (res >= 0) r->x.cx = 0;			else if (res == -ENOENT) r->x.ax = DOS_ENOMOREF;			return;		/* Rename of move file (DS:DX->ASCIZ old name, ES:DI->ASCIZ new name) */		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) res = fd32_rename(fn, newfn);			break;		}		/* Truename (CL=subfunction) */		case 0x60:			/* FIXME: Only subservice 01h "Get short (8.3) filename for file" is implemented */			if (r->h.cl != 0x01)			{				res = -ENOTSUP;				break;			}			/* CH=SUBST expansion flag (ignored), 80h to not resolve SUBST			 * DS:SI->ASCIZ long file name or path			 * ES:DI->64-bytes buffer for short path name			 */			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.si), sizeof(fn));			if (res >= 0) res = fd32_sfn_truename((char *) FAR2ADDR(r->x.es, r->x.di), fn);			break;		/* Create or open file (BX=access mode and sharing flags, CX=attributes		 * for creation, DX=action, DS:SI->ASCIZ file name, DI=numeric tail hint).		 */		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, r->x.di, &action);			res2dos(res, r);			if (res >= 0)			{				r->x.ax = (WORD) res; /* Returned handle */				r->x.cx = (WORD) action; /* Action taken */			}			return;		}		/* Get volume informations (DS:DX->ASCIZ root directory name,		 * ES:DI->buffer to store the file system name, CX=size of the		 * buffer pointed by ES:DI).		 */		case 0xA0:		{			fd32_fs_info_t fsi;			res = fix_path(fn, (const char *) FAR2ADDR(r->x.ds, r->x.dx), sizeof(fn));			if (res < 0) break;			fsi.Size       = sizeof(fd32_fs_info_t);			fsi.FSNameSize = r->x.cx;			fsi.FSName     = (char *) FAR2ADDR(r->x.es, r->x.di);			res = fd32_get_fsinfo(fn, &fsi);			if (res >= 0)			{				r->x.bx = fsi.Flags;				r->x.cx = fsi.NameMax;				r->x.dx = fsi.PathMax;			}			break;		}		/* "FindClose" - Terminate directory search (BX=directory handle) */		case 0xA1:			res = fd32_lfn_findclose(r->x.bx);			break;		/* Unsupported or invalid actions */		default:			r->x.ax = 0x7100; /* Yet another convention */			RMREGS_SET_CARRY;			return;	}	res2dos(res, r);}/* INT 21h handler for DOS file system services (AH=function) */void int21_handler(union rmregs *r){	int res;	long long int res64;	char fn[FD32_LFNPMAX];	switch (r->h.ah)	{		/* DOS 1+ - Direct character input, without echo */		case 0x07:		{			int tmp;			/* Perform 1-byte read from the stdin, file handle 0.			   1. Save the old mode of stdin			   2. Set the stdin to the raw mode without echo			   3. Read 1 byte from stdin and restore the old mode			   This procedure is very alike when doing on the Win32 platform			 */			/* This call doesn't check for Ctrl-C or Ctrl-Break.  */			fd32_get_attributes(0, &tmp);			res = 0; /* Res used to set the attributes only once */			fd32_set_attributes(0, &res);			res = fd32_read(0, &(r->h.al), 1);			fd32_set_attributes(0, &tmp);			/* Return the character in AL */			/* TODO:			   1. Get rid of the warning: passing arg 2 of `fd32_get_attributes'			   from incompatible pointer type, maybe using another system call?			   2. from RBIL: if the interim console flag is set (see AX=6301h),			   partially-formed double-byte characters may be returned			*/			return;		}		/* DOS 1+ - Set default drive (DL=drive, 0=A, etc.) */		case 0x0E:			LOG_PRINTF(("INT 21h - Set default drive to %02x\n", r->h.dl));			res = fd32_set_default_drive(r->h.dl + 'A');			if (res >= 0) return; 			{				/* Return the number of potentially valid drive letters in AL */				r->h.al = (BYTE) res;				RMREGS_CLEAR_CARRY;			}			/* No error code is documented. Check this. */			return;		/* DOS 1+ - Get default drive (in AL, 0=A, etc.) */		case 0x19:			r->h.al = fd32_get_default_drive() - 'A';			LOG_PRINTF(("INT 21h - Get default drive: %02x\n", r->h.al));			RMREGS_CLEAR_CARRY;			return;		/* DOS 1+ - Set Disk Transfer Area address (DS:DX->new DTA) */		case 0x1A:			LOG_PRINTF(("INT 21h - Set Disk Transfer Area Address: %04x:%04x\n", r->x.ds, r->x.dx));			current_psp->dta = (void *) FAR2ADDR(r->x.ds, r->x.dx);			return;		/* DOS 1+ - GET SYSTEM DATE */		case 0x2A:		{			fd32_date_t d;			fd32_get_date(&d);			r->x.cx = d.Year;			r->h.dh = d.Mon;			r->h.dl = d.Day;			r->h.al = d.weekday;			RMREGS_CLEAR_CARRY;			return;		}		/* DOS 1+ - GET SYSTEM TIME */		case 0x2C:		{			fd32_time_t t;			fd32_get_time(&t);			r->h.ch = t.Hour;			r->h.cl = t.Min;			r->h.dh = t.Sec;			r->h.dl = t.Hund;			RMREGS_CLEAR_CARRY;			return;		}		/* DOS 2+ - Get Disk Transfer Area address (ES:BX <- current DTA) */		case 0x2F:			r->x.es = (DWORD) current_psp->dta >> 4;			r->x.bx = (DWORD) current_psp->dta & 0xF;			LOG_PRINTF(("INT 21h - Get Disk Transfer Area Address: %04x:%04x\n", r->x.es, r->x.bx));			return;		/* DOS 2+ - Get DOS version, subject to modification by SETVER		 * (AL=what to return in BH: 0=OEM number, 1=version flag).		 */		case 0x30:			LOG_PRINTF(("INT 21h - Get DOS version\n"));			if (r->h.al) r->h.bh = 0x00; /* DOS is not in ROM (bit 3) */			        else r->h.bh = 0xFD; /* We claim to be FreeDOS */			/* Set the 24-bit User Serial Number to zero as we don't use it */			r->h.bl = 0;			r->x.cx = 0;			r->x.ax = 0x0A07; /* We claim to be 7.10 */			RMREGS_CLEAR_CARRY;			return;		/* DOS 2+ AL=06h - Get ture DOS version */		case 0x33:			LOG_PRINTF(("INT 21h - Get true DOS version\n"));			if (r->h.al == 0x06)			{				r->x.bx = 0x0A07; /* We claim to be 7.10 */

⌨️ 快捷键说明

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