📄 file.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include "relfsd.h"
#include "cefs.h"
#define HCONSOLE -2
// #define NO_PAGING 1
HANDLE RELFSD_CreateFileW(VolumeState *pVolume, HANDLE hProc, LPCWSTR lpFileName, DWORD dwAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreate, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
HANDLE hFile;
int nFileId;
FileState *pfs;
int nFlags = 0;
DWORD dwAttributes;
BOOL fExists = FALSE;
WIN32_FIND_DATA wfd;
TCHAR szWindowsName[MAX_PATH];
if (!lpFileName) {
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
if (lpFileName && (*lpFileName == L'\\'))
lpFileName++; // skip leading '/'
if ((OPEN_EXISTING == dwCreate) && (FILE_ATTRIBUTE_ROMMODULE == dwFlagsAndAttributes)) {
// special loader flag to load a rom-module across relfsd for debug purpose
dwFlagsAndAttributes = 0; // unset the flag, go through normal process
} else if ((OPEN_EXISTING == dwCreate) && !(GENERIC_WRITE & dwAccess)) {
// fail the create call if the file exists in ROM
wcsncpy( szWindowsName, L"\\WINDOWS\\", MAX_PATH-2);
szWindowsName[MAX_PATH-1] = 0;
wcsncat( szWindowsName, lpFileName, MAX_PATH-20);
szWindowsName[MAX_PATH-1] = 0;
wcsncpy( wfd.cFileName, lpFileName, MAX_PATH-1);
wfd.cFileName[MAX_PATH-1] = 0;
wfd.cFileName[0] = wcslen(lpFileName+1);
dwAttributes = GetFileAttributes(szWindowsName);
if ((dwAttributes != -1) && (dwAttributes & FILE_ATTRIBUTE_INROM)) {
DEBUGMSG( ZONE_ERROR, (TEXT("RELFSD: Aborting CreateFile of %s since module was found in rom\r\n"), lpFileName));
SetLastError(ERROR_NO_MORE_FILES);
return INVALID_HANDLE_VALUE;
}
}
hFile = INVALID_HANDLE_VALUE;
DEBUGMSG(ZONE_APIS, (TEXT("ReleaseFSD : CreateFile: %s (dwCreate = %x, dwAccess = %x, dwFlagsAndAttributes= %x)\n"), lpFileName, dwCreate, dwAccess, dwFlagsAndAttributes));
if (dwAccess & GENERIC_WRITE) {
if (dwAccess & GENERIC_READ)
nFlags = _O_RDWR;
else
nFlags = _O_WRONLY;
}
else if (dwAccess & GENERIC_READ) {
nFlags = _O_RDONLY;
}
switch (dwCreate) {
case CREATE_NEW : nFlags |= _O_CREAT | _O_EXCL; break;
case CREATE_ALWAYS : nFlags |= _O_CREAT | _O_TRUNC; break;
case OPEN_EXISTING : break;
case OPEN_ALWAYS : nFlags |= _O_CREAT; break;
case TRUNCATE_EXISTING: nFlags |= _O_TRUNC; break;
default:
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
}
EnterCriticalSectionMM(g_pcsMain);
// Call GetFileAttributes so we can set the correct error code if the file exists.
// This is needed because the protocol currently does not return error codes.
if ((wcscmp(lpFileName, L"VOL:") != 0) && (wcscmp(lpFileName, L"reg:") != 0) && (wcscmp(lpFileName,L"con") != 0)) {
fExists = (rgetfileattrib(lpFileName) != -1);
if (dwCreate == CREATE_NEW && fExists) {
SetLastError(ERROR_ALREADY_EXISTS);
goto exit;
}
else if (dwCreate == OPEN_EXISTING && !fExists) {
SetLastError(ERROR_FILE_NOT_FOUND);
goto exit;
}
}
nFileId = ropen(lpFileName, nFlags);
if (nFileId != -1 || !wcscmp (lpFileName, L"VOL:")) {
pfs = LocalAlloc(0, sizeof(FileState));
if (pfs) {
pfs->fs_Handle = nFileId;
pfs->fs_Volume = pVolume;
hFile = FSDMGR_CreateFileHandle(pVolume->vs_Handle, hProc,(ulong)pfs);
if (hFile == INVALID_HANDLE_VALUE)
{
DEBUGMSG(ZONE_APIS, (TEXT("CreateFile : Invalid Handle")));
LocalFree(pfs);
}
else
{
if (lpFileName && (wcscmp(lpFileName, L"celog.clg") != 0) && (wcscmp(lpFileName, L"reg:") != 0) && (wcscmp(lpFileName,L"con") != 0)) {
RETAILMSG( 1, (TEXT("RELFSD: Opening file %s from desktop\r\n"), lpFileName));
}
// Since attributes are not part of the protocol for CreateFile call, set them if necessary.
if (dwFlagsAndAttributes && dwFlagsAndAttributes != FILE_ATTRIBUTE_NORMAL) {
rsetfileattrib(lpFileName, dwFlagsAndAttributes & CE_ATTRIBUTE_MASK);
}
// Set the appropriate error code so user knows if file existed previously
if (dwCreate == CREATE_ALWAYS || dwCreate == OPEN_ALWAYS) {
SetLastError (fExists ? ERROR_ALREADY_EXISTS : ERROR_SUCCESS);
}
}
}
}
else
{
SetLastError(ERROR_FILE_NOT_FOUND);
}
exit:
LeaveCriticalSectionMM(g_pcsMain);
return hFile;
}
BOOL RELFSD_CloseFile(FileState *pfs)
{
DEBUGMSG(ZONE_APIS, (TEXT("ReleaseFSD : FSD_CloseFile\n")));
EnterCriticalSectionMM(g_pcsMain);
rclose(pfs->fs_Handle);
LocalFree(pfs);
LeaveCriticalSectionMM(g_pcsMain);
return TRUE;
}
BOOL RELFSD_ReadFile( FileState *pfs, PBYTE pBuffer, DWORD cbRead, PDWORD pNumBytesRead, LPOVERLAPPED lpOverlapped)
{
BOOL fSuccess;
int nRead;
if (pfs->fs_Handle == HCONSOLE)
{
EnterCriticalSectionMM(g_pcsMain);
nRead = rread(pfs->fs_Handle, (unsigned char *) pBuffer, cbRead);
LeaveCriticalSectionMM(g_pcsMain);
}
else
{
DEBUGMSG(ZONE_APIS, (TEXT("ReleaseFSD : FSD_ReadFile %#x bytes\n"), cbRead));
EnterCriticalSectionMM(g_pcsMain);
nRead = rread(pfs->fs_Handle, (unsigned char *) pBuffer, cbRead);
LeaveCriticalSectionMM(g_pcsMain);
}
if (nRead < 0) {
nRead = 0;
fSuccess = FALSE;
} else {
fSuccess = TRUE;
}
if (pNumBytesRead)
*pNumBytesRead = (DWORD)nRead;
return fSuccess;
}
BOOL RELFSD_ReadFileWithSeek( FileState *pfs, PBYTE pBuffer, DWORD cbRead, PDWORD pNumBytesRead,
LPOVERLAPPED lpOverlapped, DWORD dwLowOffset, DWORD dwHighOffset)
{
BOOL fSuccess;
LONGLONG pos;
int nRead;
#ifdef NO_PAGING
SetLastError (ERROR_NOT_SUPPORTED);
return FALSE;
#endif
DEBUGMSG(ZONE_APIS, (TEXT("ReleaseFSD: FSD_ReadFileWithSeek %d bytes. Offset: %d, %d\n"), cbRead, dwHighOffset, dwLowOffset));
// Max amount that can be read is one page size
if (cbRead > 4*1024) {
DEBUGMSG (ZONE_APIS, (TEXT("ReleaseFSD: FSD_ReadFileWithSeek %d bytes is too large\n"), cbRead));
return FALSE;
}
/* this case is used as a probe from the kernel to see if paging is OK... */
if ((pBuffer == NULL) && (cbRead == 0)) {
nRead = 0;
fSuccess = TRUE;
} else {
EnterCriticalSectionMM(g_pcsMain);
pos = ((LONGLONG)dwHighOffset << 32) | (LONGLONG)dwLowOffset;
nRead = rreadseek (pfs->fs_Handle, pBuffer, cbRead, (LONG)pos);
#if 0
rlseek(pfs->fs_Handle,(LONG)pos & -1,SEEK_SET);
nRead = rread(pfs->fs_Handle, (unsigned char *) pBuffer, cbRead);
#endif
LeaveCriticalSectionMM(g_pcsMain);
if (nRead < 0) {
nRead = 0;
fSuccess = FALSE;
} else {
fSuccess = TRUE;
}
}
if (pNumBytesRead)
*pNumBytesRead = (DWORD)nRead;
return fSuccess;
}
BOOL RELFSD_WriteFile( FileState *pfs, LPCVOID pBuffer, DWORD cbWrite, PDWORD pNumBytesWritten, LPOVERLAPPED lpOverlapped)
{
BOOL fSuccess;
int nWritten;
if (pfs->fs_Handle == HCONSOLE)
{
EnterCriticalSectionMM(g_pcsMain);
nWritten = rwrite(pfs->fs_Handle, (unsigned char *)pBuffer, cbWrite);
LeaveCriticalSectionMM(g_pcsMain);
}
else
{
DEBUGMSG(ZONE_APIS, (TEXT("ReleaseFSD: FSD_WriteFile %#x bytes\n"), cbWrite));
EnterCriticalSectionMM(g_pcsMain);
nWritten = rwrite(pfs->fs_Handle, (unsigned char *)pBuffer, cbWrite);
LeaveCriticalSectionMM(g_pcsMain);
}
if (nWritten < 0) {
nWritten = 0;
fSuccess = FALSE;
} else {
fSuccess = TRUE;
}
if (pNumBytesWritten)
*pNumBytesWritten = (DWORD)nWritten;
return fSuccess;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -