www.pudn.com > EZUSBµÄFIRMWARE.zip > Fileio98.cpp


// FILEIO98.CPP -- VxD interfaces for File I/O operations 
// Copyright (C) 1999 by Walter Oney 
// All rights reserved 
 
#if DBG 
	#define DEBUG 
#else 
	#undef DEBUG 
#endif 
 
extern "C" { 
 
#define WANTVXDWRAPS 
#include  
#include  
#include  
#include "ifsmgr.h" 
#include  
#include  
 
typedef struct _FILE_HANDLE { 
	DWORD hfile;				// file system handle 
	BOOL i21;					// TRUE if opened via INT 21 call 
	DWORD pos;					// file position for IFSMgr R/W calls 
	} FILE_HANDLE, *PFILE_HANDLE; 
 
#define SEEK_CUR    1 
#define SEEK_END    2 
#define SEEK_SET    0 
 
#define STATUS_SUCCESS 0 
#define STATUS_UNSUCCESSFUL 0xC0000001 
#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A 
 
/////////////////////////////////////////////////////////////////////////////// 
 
#pragma warning(disable:4035) 
 
DWORD SeekI21File(DWORD hfile, DWORD pos, int origin) { 
	_asm { 
		mov eax, 4200h			; fcn 42: seek 
		mov al, byte ptr origin 
		mov ebx, hfile 
		mov edx, pos 
		mov ecx, edx 
		shr ecx, 16 
		push 21h 
		} 
	VMMCall(Exec_VxD_Int) 
	_asm { 
		movzx eax, ax 
		shl edx, 16 
		or eax, edx 
		} 
	} 
 
#pragma warning(default:4035) 
 
/////////////////////////////////////////////////////////////////////////////// 
 
ULONG Win98OpenFile(PWORD filename, BYTE read, PFILE_HANDLE* phandle) { 
	DWORD hfile; 
	DWORD actiontaken; 
	BOOL i21; 
 
// Convert name to OEM character set 
	char name[MAX_PATH]; 
	name[UniToBCS((PBYTE) name, filename, wcslen(filename) * 2, sizeof(name)-2, BCS_OEM)] = 0; 
 
// Intepret SystemRoot if it's present as the first directory name in the path 
	_strlwr(name); 
	if (memcmp(name, "\\systemroot", 11) == 0) { 
		char* windir = Get_Config_Directory(); 
		char newname[MAX_PATH]; 
		strcpy(newname, windir); 
		newname[strlen(windir)-1] = 0;	// remove NULL at end of directory name 
		strcat(newname, name + 11); 
		strcpy(name, newname); 
		} 
 
// Develop arguments to the open function 
	WORD modeflags = read ? ACCESS_READONLY : ACCESS_WRITEONLY; 
	WORD shareflags = read ? SHARE_DENYWRITE : SHARE_DENYREADWRITE; 
	WORD attrib = 0; 
	BYTE action = read ? ACTION_OPENEXISTING : ACTION_CREATEALWAYS; 
	BYTE flags = 0; 
 
	int code; 
 
	if (VMM_GetSystemInitState() >= SYSSTATE_PREINITCOMPLETE) {		// call IFSMgr 
		code = R0_OpenCreateFile(TRUE, modeflags | shareflags, attrib, action, flags, name, &hfile, &actiontaken); 
		i21 = FALSE; 
		} 
	else {						// use INT 21 
		_asm { 
			mov eax, 6C00h		; AX = function code (extended open/create) 
			mov bx, modeflags	; BX = mode & share flags 
			or  bx, shareflags 
			mov cx, attrib;		; CX = attributes when creating file 
			mov dl, action		; DL = action code 
			xor dh, dh			; DH = flags (must be zero) 
			lea esi, name		; ESI -> name of file to open 
			push 21h			; push 21h as arg for Exec_Vxd_Int 
			} 
		VMMCall(Exec_VxD_Int); 
		_asm 
			{					// test return code 
			movzx eax, ax 
			jc    error			; skip if error 
			mov   hfile, eax 
			xor	  eax, eax		; STATUS_SUCCESS 
error:		mov   code, eax		; save error code 
			}					// test return code 
		i21 = TRUE; 
		} 
	if (code != 0) return STATUS_UNSUCCESSFUL; 
		 
	PFILE_HANDLE hp = (PFILE_HANDLE) _HeapAllocate(sizeof(FILE_HANDLE), 0); 
	if (!hp) return STATUS_INSUFFICIENT_RESOURCES; 
 
	hp->hfile = hfile; 
	hp->i21 = i21; 
	hp->pos = 0; 
	*phandle = hp; 
	return STATUS_SUCCESS; 
	} 
 
/////////////////////////////////////////////////////////////////////////////// 
 
ULONG Win98CloseFile(PFILE_HANDLE handle) { 
	if (handle->i21) {			// close INT 21 handle 
		_asm { 
			mov eax, 3E00h		; fcn 3E: close file 
			mov esi, handle 
			mov ebx, [esi]FILE_HANDLE.hfile 
			push 21h 
			} 
		VMMCall(Exec_VxD_Int) 
		} 
	else R0_CloseFile(handle->hfile); 
 
	_HeapFree(handle, 0); 
	return STATUS_SUCCESS; 
	} 
 
/////////////////////////////////////////////////////////////////////////////// 
 
ULONG Win98GetFileSize(PFILE_HANDLE handle) { 
	DWORD eof; 
 
	if (handle->i21) {			// get size using INT 21 handle 
		DWORD curpos = SeekI21File(handle->hfile, 0, SEEK_CUR); 
		eof = SeekI21File(handle->hfile, 0, SEEK_END); 
		SeekI21File(handle->hfile, curpos, SEEK_SET); 
		} 
	else {						// use IFSMgr 
		if (R0_GetFileSize(handle->hfile, &eof) != 0) eof = 0xFFFFFFFF; 
		} 
	return eof; 
	} 
 
/////////////////////////////////////////////////////////////////////////////// 
 
ULONG Win98ReadFile(PFILE_HANDLE handle, PBYTE buffer, ULONG nbytes, PULONG pnumread) { 
	int code; 
	DWORD numread; 
 
	if (handle->i21) {			// read via INT 21 handle 
		_asm { 
			mov eax, 3F00h		; fcn 3F: read file 
			mov esi, handle 
			mov ebx, [esi]FILE_HANDLE.hfile 
			mov ecx, nbytes 
			mov edx, buffer 
			push 21h 
			} 
		VMMCall(Exec_VxD_Int) 
		_asm  { 
			mov numread, eax	; assume success 
			sbb eax, eax		; EAX = 0 if success, -1 if error 
			mov code, eax 
			} 
		} 
	else code = R0_ReadFile(TRUE, handle->hfile, nbytes, handle->pos, buffer, &numread); 
 
	if (code == 0) {			// success 
		*pnumread = numread; 
		handle->pos += numread; 
		return STATUS_SUCCESS; 
		} 
 
	return STATUS_UNSUCCESSFUL; 
	} 
 
/////////////////////////////////////////////////////////////////////////////// 
 
ULONG Win98WriteFile(PFILE_HANDLE handle, PBYTE buffer, ULONG nbytes, PULONG pnumwritten) { 
	int code; 
	DWORD numwritten; 
 
	if (handle->i21) {			// write via INT 21 handle 
		_asm { 
			mov eax, 4000h		; fcn 40: write file 
			mov esi, handle 
			mov ebx, [esi]FILE_HANDLE.hfile 
			mov ecx, nbytes 
			mov edx, buffer 
			push 21h 
			} 
		VMMCall(Exec_VxD_Int) 
		_asm { 
			mov numwritten, eax	; assume success 
			sbb eax, eax		; EAX = 0 if success, -1 if error 
			mov code, eax 
			} 
		} 
	else code = R0_WriteFile(TRUE, handle->hfile, nbytes, handle->pos, buffer, &numwritten); 
 
	if (code == 0) {			// success 
		*pnumwritten = numwritten; 
		handle->pos += numwritten; 
		return STATUS_SUCCESS; 
		} 
 
	return STATUS_UNSUCCESSFUL; 
	} 
 
} // extern "C"