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

📄 mdcfs.c

📁 a fat12 source code, it is verified for many platform
💻 C
📖 第 1 页 / 共 2 页
字号:
				set_fat(i, 0xFFF);
				if(cluster)
					set_fat(cluster, i);
				return i; }
		/* Didn't find, reset to start cluster, and try again */
		end = begin;
		begin = 2; }
	while(end != 2);

#ifdef	DEBUG
	printf("Failed!\n");
#endif
	return 0;
}

/*
 * Release a chain of allocated clusters
 */
release(cluster)
	int cluster;
{
	unsigned i;
	while(cluster && (cluster < 0xFF8)) {
		i = get_fat(cluster);
		set_fat(cluster, 0);
		cluster = i; }
}

/*
 * Get a FAT entry for a given cluster number
 */
int get_fat(cluster)
	unsigned cluster;
{
	unsigned sec, fat;

#ifdef	DEBUG
	printf("Get FAT for %u - ", cluster);
#endif

	sec = (cluster *= 3)/2;
	read_work(active_drive, (sec / bytsec) + 1);
	fat = wrkbuff[sec % bytsec];
	read_work(active_drive, (++sec / bytsec) + 1);
	fat |= wrkbuff[sec % bytsec] << 8;
	if(cluster & 1)
		fat >>= 4;

#ifdef	DEBUG
	printf("%u\n", fat & 0xFFF);
#endif

	return fat & 0xfff;
}

/*
 * Set a FAT entry for a given cluster number
 */
set_fat(cluster, value)
	unsigned cluster, value;
{
	unsigned sec, x;

#ifdef	DEBUG
	printf("Set FAT for %u - %u\n", cluster, value);
#endif

	sec = (cluster *= 3)/2;

	/* Set LOW byte of FAT */
	read_work(active_drive, (sec / bytsec) + 1);
	x = sec % bytsec;
	if(cluster & 1)
		wrkbuff[x] = (wrkbuff[x] & 0x0F) | (value << 4);
	else
		wrkbuff[x] = value;
	wrkchg = -1;

	/* Set high byte of FAT */
	read_work(active_drive, (++sec / bytsec) + 1);
	x = sec % bytsec;
	if(cluster & 1)
		wrkbuff[x] = value >> 4;
	else
		wrkbuff[x] = (wrkbuff[x] & 0xF0) | ((value >> 8) & 0x0F);
	wrkchg = -1;
}


/*
 * Directory manipulation functions:
 *
 *	lookup(file)				- Locate a files directory entry
 *		file	- Name of file to locate
 *		returns : Pointer to directory entry, 0 if failure.
 *
 *	create_file(file,attrs) 	- Create a mew file
 *		file	- Name of file to create
 *		attrs	- Attributes for file (0 = normal)
 *		returns : Pointer to directory entry, 0 if failure.
 *
 *	parse_filename(buffer,name)	- Get filename in directory format
 *		buffer	- Buffer for directory format filename (13 bytes)
 *		name	- ASCII filename to convert
 *
 *	memcmp(ptr1, ptr2, size)	- Block memory compare
 *		ptr1	- Pointer to first block
 *		ptr2	- Pointer to second block
 *		size	- Number of bytes to compare
 *		returns	: -1 of match, 0 if different.
 */

/*
 * Lookup a directory entry & return pointer to it
 */
struct Dentry *lookup(file)
	char *file;
{
	unsigned i, j, k;
	char fbuffer[12];

	parse_filename(fbuffer, file);

#ifdef	DEBUG
	printf("Lookup: '%s' ", fbuffer);
#endif

	j = bytsec;
	k = dirsec;
	for(i=0; i < dirent; ++i) {
		if(j >= bytsec) {
			read_work(active_drive, k++);
			j = 0; }
		if(memcmp(wrkbuff+j, fbuffer, 11)) {
#ifdef	DEBUG
	printf("Found - Cluster: %u\n", *(int*)(wrkbuff+j+0x1A));
#endif
			return wrkbuff+j; }
		j += sizeof(struct Dentry); }

#ifdef	DEBUG
	printf("Not found\n");
#endif
	return 0;
}

/*
 * Create a file with the specified name
 * NOTE: Does NOT check for duplicates. It is assumed that "lookup()"
 * has been called first, to verify that the file does not already
 * exist on the disk.
 */
struct Dentry *create_file(file, attrs)
	char *file;
	int attrs;
{
	int i, j, k;
	char fbuffer[12];
	struct Dentry *dirptr;

	parse_filename(fbuffer, file);

#ifdef	DEBUG
	printf("Create '%s' ", fbuffer);
#endif

	j = bytsec;
	k = dirsec;
	for(i=0; i < dirent; ++i) {
		if(j >= bytsec) {
			read_work(active_drive, k++);
			j = 0; }
		if((*(dirptr = wrkbuff+j)->Dname == EMPTY) || !*dirptr->Dname) {
#ifdef	DEBUG
	printf("Dir entry #%u\n", i);
#endif
			memset(dirptr, 0, sizeof(struct Dentry));
			strcpy(dirptr, fbuffer);
			dirptr->Dattr = attrs;
			/* Set directory date of creation here - if you wish */
			wrkchg = -1;
			return wrkbuff+j; }
	j += sizeof(struct Dentry); }

#ifdef	DEBUG
	printf("No directory!\n");
#endif

	return 0;
}

/*
 * Parse a filename into directory format (12 characters, space filled)
 */
parse_filename(buffer, name)
	char buffer[], *name;
{
	int i;

	i = 0;
	while(i < 8)
		buffer[i++] = (*name && (*name != '.')) ? toupper(*name++) : ' ';
	if(*name == '.')
		++name;
	while(i < 11)
		buffer[i++] = *name ? toupper(*name++) : ' ';
	buffer[i] = 0;
}

/*
 * Memory to memory compare
 */
int memcmp(ptr1, ptr2, size)
	char *ptr1, *ptr2;
	unsigned size;
{
	while(size--)
		if(*ptr1++ != *ptr2++)
			return 0;
	return -1;
}


/*
 * Internal "work" sector manipulation functions:
 *
 *	read_work(sector)		- Read sector into work buffer (if necessary)
 *		sector	- Sector number to read.
 *
 *	update_work()			- Write work sector back to disk if changed
 */

/*
 * Read a work sector into memory if it is not already in memory.
 */
read_work(drive, sector)
	char drive;
	int sector;
{
	if((wrkdrv != drive) || (wrksec != sector)) {
		update_work();
		read_sector(wrkdrv = drive, wrksec = sector, wrkbuff); }
}

/*
 * Write the work sector if it has been marked as modified
 */
update_work()
{
	if(wrkchg) {
		write_sector(wrkdrv, wrksec, wrkbuff);
		wrkchg = 0; }
}


/*
 * Low level disk I/O functions:
 *
 *	disk_error(code)		- Called if unrecoverable disk error
 *		code	- Disk failure code (system depandant)
 *
 *	read_sector(d, s, b)	- Read a sector from the disk
 *		d		- Drive to read (0=A, 1=B ...)
 *		s		- Sector number to read (1-n)
 *		b		- Pointer to buffer to receive data
 *
 *	write_sector(d, s, b)	- Write a sector to the disk
 *		d		- Drive to write (0=A, 1=B ...)
 *		s		- Sector number to write (1-n)
 *		b		- Pointer to buffer containing the data
 *
 * These functions make use of the IBM PC BIOS, and are compatible
 * with Microsoft MASM assembler. Use these if you are compiling the
 * demo program with the MICRO-C DOS compiler.
 */

/*
 * Report a disk error
 */
disk_error(code)
	int code;
{
	printf("Disk error - Code: %04x\n", code);
	exit(-1);
}

/*
 * Read a sector from the disk drive
 */
read_sector(drive, sector, buffer) asm
{
		PUSH	DS			; Save DS
		POP		ES			; Set ES
		MOV		BX,4[BP]	; Get buffer
		MOV		AX,6[BP]	; Get sector
		XOR		DX,DX		; Zero high
		DIV		WORD PTR _sectrk; Calculate track
		MOV		CL,DL		; CL = sector
		INC		CL			; 1-
		XOR		DX,DX		; Zero high
		DIV		WORD PTR _numhead; Compute head
		MOV		CH,AL		; CH = cylinder
		MOV		DH,DL		; DH = head
		MOV		DL,8[BP]	; DL = drive
		MOV		DI,3		; Try three times
read1:	MOV		AX,0201h	; Read 1 sector
		INT		13h			; Call BIOS
		JNC		read2		; Success
		DEC		DI			; Reduce count
		JNZ		read1		; Keep trying
		PUSH	AX			; Pass parameter
		CALL	_disk_error	; Report an error
		POP		AX			; Clean stack
read2:	XOR		AX,AX		; Zero return
}

/*
 * Write a sector to the disk drive
 */
write_sector(drive, sector, buffer) asm
{
		PUSH	DS			; Save DS
		POP		ES			; Set ES
		MOV		BX,4[BP]	; Get buffer
		MOV		AX,6[BP]	; Get sector
		XOR		DX,DX		; Zero high
		DIV		WORD PTR _sectrk; Calculate track
		MOV		CL,DL		; CL = sector
		INC		CL			; 1-
		XOR		DX,DX		; Zero high
		DIV		WORD PTR _numhead; Compute head
		MOV		CH,AL		; CH = cylinder
		MOV		DH,DL		; DH = head
		MOV		DL,8[BP]	; DL = drive
		MOV		DI,3		; Try three times
write1:	MOV		AX,0301h	; Write 1 sector
		INT		13h			; Call BIOS
		JNC		write2		; Success
		DEC		DI			; Reduce count
		JNZ		write1		; Keep trying
		PUSH	AX			; Pass parameter
		CALL	_disk_error	; Report an error
		POP		AX			; Clean stack
write2:	XOR		AX,AX		; Zero return
}


/*
 * Sample Main program (Not part of MDCFS) to demonstrate reading,
 * writing and deleteing files. This also uses the standard file
 * I/O of the MICRO-C DOS compiler, and will not run stand-alone.
 *
 * Demo command syntax:
 *   MCDFS W <file>		- Copy file from current DOS dir to floppy
 *   MCDFS R <file>     - Copy file from floppy to current DOS dir
 *   MCDFS D <file>     - Delete file from floppy.
 *
 * All accesss to the floppy are performed via MCDFS.
 */
main(argc, argv)
	int argc;
	char *argv[];
{
	int c;
	struct Fblock *fp;
	FILE *xfp;

	open_drive(0);		/* Change to (1) for drive B: */
	switch((argc > 2) ? toupper(*argv[1]) : 0) {

		case 'R' :		/* Read file from floppy drive */
			if(!(fp = open_file(argv[2], READ)))
				abort("Couldn't read MDCFS file");
			xfp = fopen(argv[2], "wbvq");
			while((c = read_byte(fp)) >= 0)
				putc(c, xfp);
			close_file(fp);
			fclose(xfp);
			c = 0;		/* Disk has not been modified */
			break;

		case 'W' :		/* Write file to floppy drive */
			xfp = fopen(argv[2], "rvbq");
			if(!(fp = open_file(argv[2], WRITE)))
				abort("Couldn't write MDCFS file");
			while((c = getc(xfp)) >= 0)
				write_byte(c, fp);
			fclose(xfp);
			close_file(fp);
			c = -1;		/* Note that disk may have been written */
			break;

		case 'D' :		/* Delete file from floppy drive */
			delete_file(argv[2]);
			c = -1;		/* Note that disk may have been written */
			break;

		default:
			abort("Use: MDCFS (Read/Write/Delete) <filename>"); }

	if(c) {
		printf("\nNote: Since MDCFS bypasses DOS completely, DOS will be unaware\n");
		printf("of any changes to the disk... Due to DOS buffering, files written\n");
		printf("may not appear in DOS 'dir' command, or may have their sizes\n");
		printf("reported incorrectly... Press CONTROL-C to force DOS to flush\n");
		printf("its buffers before accessing the floppy disk"); }
}

⌨️ 快捷键说明

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