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

📄 fileio98.cpp

📁 一本在讲述USB驱动程式的书 及其范例原码
💻 CPP
字号:
// FILEIO98.CPP -- VxD interfaces for File I/O operations
// Copyright (C) 1999 by Walter Oney
// All rights reserved

// Compile this file using __cdecl as the default calling convention and
// without precompiled headers. Note that the project settings include the win_me
// include and library directories and vxdwraps.clb as one of the libraries.

#ifdef _X86_

#if DBG
	#define DEBUG
#else
	#undef DEBUG
#endif

extern "C" {

#define WANTVXDWRAPS
#include <basedef.h>
#include <debug.h>
#include <vmm.h>
#include "ifsmgr.h"
#include <vxdwraps.h>
#include <string.h>

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

// Note that the WinME DDK has a wrapper for Exec_VxD_Int that doesn't
// suit our needs

#undef Exec_VxD_Int

///////////////////////////////////////////////////////////////////////////////

#pragma warning(disable:4035)

DWORD SeekI21File(DWORD hfile, DWORD pos, int origin)
	{							// SeekI21File
	_asm mov eax, 4200h			; fcn 42: seek
	_asm mov al, byte ptr origin
	_asm mov ebx, hfile
	_asm mov edx, pos
	_asm mov ecx, edx
	_asm shr ecx, 16
	_asm push 21h

	VMMCall(Exec_VxD_Int)

	_asm movzx eax, ax
	_asm shl edx, 16
	_asm or eax, edx
	}							// SeekI21File

#pragma warning(default:4035)

///////////////////////////////////////////////////////////////////////////////

ULONG Win98OpenFile(PWORD filename, BYTE read, PFILE_HANDLE* phandle)
	{							// Win98OpenFile
	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)
		{						// path relative to system root
		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);
		}						// path relative to system root

	// 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;
		}						// call IFSMgr
	else
		{						// use INT 21
		_asm
			{					// prepare for INT 21
			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
			}					// prepare for INT 21
	
		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;
		}						// use INT 21

	if (code != 0)
		return 0xC0000001;		// STATUS_UNSUCCESSFUL
		
	PFILE_HANDLE hp = (PFILE_HANDLE) _HeapAllocate(sizeof(FILE_HANDLE), 0);
	if (!hp)
		return 0xC000009A;		// STATUS_INSUFFICIENT_RESOURCES

	hp->hfile = hfile;
	hp->i21 = i21;
	hp->pos = 0;
	*phandle = hp;
	return 0;					// STATUS_SUCCESS
	}							// Win98OpenFile

///////////////////////////////////////////////////////////////////////////////

ULONG Win98CloseFile(PFILE_HANDLE handle)
	{							// Win98CloseFile
	if (handle->i21)
		{						// close INT 21 handle
		_asm mov eax, 3E00h		; fcn 3E: close file
		_asm mov esi, handle
		_asm mov ebx, [esi]FILE_HANDLE.hfile
		_asm push 21h
		VMMCall(Exec_VxD_Int)
		}						// close INT 21 handle
	else
		R0_CloseFile(handle->hfile);

	_HeapFree(handle, 0);

	return 0;					// STATUS_SUCCESS
	}							// Win98CloseFile

///////////////////////////////////////////////////////////////////////////////

ULONG Win98GetFileSize(PFILE_HANDLE handle)
	{							// Win98GetFileSize
	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);
		}						// get size using INT 21 handle
	else
		{						// use IFSMgr
		if (R0_GetFileSize(handle->hfile, &eof) != 0)
			eof = 0xFFFFFFFF;
		}						// use IFSMgr

	return eof;
	}							// Win98GetFileSize

///////////////////////////////////////////////////////////////////////////////

ULONG Win98ReadFile(PFILE_HANDLE handle, PBYTE buffer, ULONG nbytes, PULONG pnumread)
	{							// Win98ReadFile
	int code;
	DWORD numread;

	if (handle->i21)
		{						// read via INT 21 handle
		_asm mov eax, 3F00h		; fcn 3F: read file
		_asm mov esi, handle
		_asm mov ebx, [esi]FILE_HANDLE.hfile
		_asm mov ecx, nbytes
		_asm mov edx, buffer
		_asm push 21h
		VMMCall(Exec_VxD_Int)
		_asm mov numread, eax	; assume success
		_asm sbb eax, eax		; EAX = 0 if success, -1 if error
		_asm mov code, eax
		}						// read via INT 21 handle
	else
		code = R0_ReadFile(TRUE, handle->hfile, nbytes, handle->pos, buffer, &numread);

	if (code == 0)
		{						// success
		*pnumread = numread;
		handle->pos += numread;
		return 0;				// STATUS_SUCCESS
		}						// success

	return 0xC0000001;			// STATUS_UNSUCCESSFUL
	}							// Win98ReadFile

///////////////////////////////////////////////////////////////////////////////

ULONG Win98SetFilePosition(PFILE_HANDLE handle, __int64 pos)
	{							// Win98SetFilePosition
	if (handle->i21)
		SeekI21File(handle->hfile, (DWORD) pos, SEEK_SET);
	else
		handle->pos = (DWORD) pos;

	return 0;
	}							// Win98SetFilePosition

///////////////////////////////////////////////////////////////////////////////

ULONG Win98WriteFile(PFILE_HANDLE handle, PBYTE buffer, ULONG nbytes, PULONG pnumwritten)
	{							// Win98WriteFile
	int code;
	DWORD numwritten;

	if (handle->i21)
		{						// write via INT 21 handle
		_asm mov eax, 4000h		; fcn 40: write file
		_asm mov esi, handle
		_asm mov ebx, [esi]FILE_HANDLE.hfile
		_asm mov ecx, nbytes
		_asm mov edx, buffer
		_asm push 21h
		VMMCall(Exec_VxD_Int)
		_asm mov numwritten, eax	; assume success
		_asm sbb eax, eax		; EAX = 0 if success, -1 if error
		_asm mov code, eax
		}						// write via INT 21 handle
	else
		code = R0_WriteFile(TRUE, handle->hfile, nbytes, handle->pos, buffer, &numwritten);

	if (code == 0)
		{						// success
		*pnumwritten = numwritten;
		handle->pos += numwritten;
		return 0;				// STATUS_SUCCESS
		}						// success

	return 0xC0000001;			// STATUS_UNSUCCESSFUL
	}							// Win98WriteFile

} // extern "C"

#endif // _X86_

⌨️ 快捷键说明

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