📄 file.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
/*
File: file.c
Contains: VirtualCE FSD file interface.
Written by: Craig Vinet
Copyright: (c) 2002 Connectix Corporation
*/
#include "vcefsd.h"
#include "fserver.h"
#include "find.h"
#include "file.h"
#include "vol.h"
//--------------------------------------------------------------------------------
// Defines
//--------------------------------------------------------------------------------
#define kMaxFD 40 // Max # of open files
#define kFDSignature 0x64664644
#define kOpenAccessReadOnly 0x0000
#define kOpenAccessWriteOnly 0x0001
#define kOpenAccessReadWrite 0x0002
#define kOpenShareCompatibility 0x0000
#define kOpenShareDenyReadWrite 0x0010
#define kOpenShareDenyWrite 0x0020
#define kOpenShareDenyRead 0x0030
#define kOpenShareDenyNone 0x0040
//--------------------------------------------------------------------------------
// Data
//--------------------------------------------------------------------------------
FileData gFDList[kMaxFD];
extern PUCHAR gvpReadWriteBuffer;
extern ServerPB* gvpServerPB;
extern PUCHAR gpReadWriteBuffer; // Physical addr.
extern SHELLFILECHANGEFUNC_t gpnShellNotify;
//--------------------------------------------------------------------------------
// Prototypes
//--------------------------------------------------------------------------------
BOOL ValidateFileHandle( FileData* pFileData );
FileData* AllocFileData( void );
void FreeFileData( FileData* pFileData );
BOOL LongToFileTime( LONG longTime, PFILETIME pft );
LONG FileTimeToLong( PFILETIME pft );
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void InitFiles( void )
{
ULONG x;
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: +InitFiles\n" ) ) );
for( x=0; x<kMaxFD; x++ )
{
gFDList[x].fInUse = FALSE;
gFDList[x].fSignature = 0;
gFDList[x].fHandle = 0;
}
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: -InitFiles\n" ) ) );
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL ValidateFileHandle( FileData* pFileData )
{
if( pFileData == 0 )
{
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: ValidateFileHandle - bad handle\n" ) ) );
return FALSE;
}
if( pFileData->fSignature != kFDSignature )
{
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: ValidateFileHandle - bad handle\n" ) ) );
return FALSE;
}
return TRUE;
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
FileData * AllocFileData( void )
{
ULONG x;
FileData * pFileData = 0;
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: +AllocFileData\n" ) ) );
for( x=0; x<kMaxFD; x++ )
{
if( gFDList[x].fInUse == FALSE )
{
pFileData = &gFDList[x];
break;
}
}
if( pFileData )
{
pFileData->fSignature = kFDSignature;
pFileData->fInUse = TRUE;
}
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: -AllocFileData\n" ) ) );
return pFileData;
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void FreeFileData( FileData* pFileData )
{
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: +FreeFileData\n" ) ) );
if( ValidateFileHandle( pFileData ) != TRUE )
goto Done;
pFileData->fInUse = FALSE;
pFileData->fSignature = 0;
pFileData->fHandle = 0;
Done:;
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: -FreeFileData\n" ) ) );
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void CloseFiles( void )
{
ULONG x;
ULONG error;
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: +CloseFiles\n" ) ) );
for( x=0; x<kMaxFD; x++ )
{
if( gFDList[x].fInUse )
{
// Fill in the parameter block for the ServerSetAttributes call
memset( gvpServerPB, 0, sizeof(ServerPB) );
gvpServerPB->fStructureSize = sizeof(ServerPB);
gvpServerPB->fHandle = gFDList[x].fHandle;
error = ServerGetFCBInfo( gvpServerPB );
ASSERT( error == 0 );
// Close the file
gvpServerPB->fHandle = gFDList[x].fHandle;
error = ServerClose( gvpServerPB );
ASSERT( error == 0 );
// If we need to update the attributes, do so
if( gFDList[x].fWritten || gFDList[x].fSetAttrOnClose )
{
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: CloseFiles setting attributes\n" ) ) );
if( gFDList[x].fWritten )
gvpServerPB->fFileTimeDate = gFDList[x].fFileTimeDate;
else
gvpServerPB->fFileTimeDate = 0;
gvpServerPB->fFileAttributes =( BYTE ) gFDList[x].fFileAttributes;
ServerSetAttributes( gvpServerPB );
}
// Destroy the file data
FreeFileData( &gFDList[x] );
}
}
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: -CloseFiles\n" ) ) );
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
HANDLE VCEFSD_CreateFileW( VolumeState* pVolumeState,
HANDLE hProc,
LPCWSTR lpFileName,
DWORD dwAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreate,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile )
{
FileData* pFileData;
Boolean fileExists = FALSE;
Boolean truncate = FALSE;
Boolean create = FALSE;
Boolean createAlways = FALSE;
DWORD error = NO_ERROR;
HANDLE hFile = INVALID_HANDLE_VALUE;
FILECHANGEINFO changeInfo;
WCHAR fullFilePathname[MAX_PATH];
SHORT delIndex = 0x7FFF;
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: +FSD_CreateFileW\n" ) ) );
EnterCriticalSection(&g_csMain);
// See if the file exists
if( Find( pVolumeState, gvpServerPB, lpFileName ) == 0 )
{
fileExists = TRUE;
}
// Depending on the action code, do the right thing...
switch( dwCreate )
{
case OPEN_EXISTING:
// Open the existing file
if( fileExists == FALSE )
error = ERROR_FILE_NOT_FOUND;
break;
case TRUNCATE_EXISTING:
if( fileExists == FALSE )
{
error = ERROR_FILE_NOT_FOUND;
}
else
{
truncate = TRUE;
create = TRUE;
}
break;
case CREATE_ALWAYS:
// Truncate existing file or create if none
truncate = TRUE;
createAlways = TRUE;
break;
case OPEN_ALWAYS:
// Create a new empty file or just open
if( fileExists == FALSE )
{
create = TRUE;
}
break;
case CREATE_NEW:
if( fileExists == TRUE )
{
error = ERROR_ALREADY_EXISTS;
}
else
{
create = TRUE;
}
break;
default:
// In the weeds
error = ERROR_INVALID_PARAMETER;
break;
}
// Truncate( Delete ) the file if need be
if( error == 0 && truncate && fileExists == TRUE )
{
delIndex = gvpServerPB->fIndex;
if( ServerDelete( gvpServerPB ) != 0 )
{
error = ERROR_ACCESS_DENIED;
}
}
// Create a new file if need be
if( ( create || createAlways ) && error == NO_ERROR )
{
if( ServerCreate( gvpServerPB ) == 0 )
{
// Set the file's attributes
gvpServerPB->fFileAttributes = ( USHORT )( dwFlagsAndAttributes & 0xFFFF );
// Do not set the modification time
gvpServerPB->fFileTimeDate = 0;
if( ServerSetAttributes( gvpServerPB ) != 0 )
{
error = ERROR_ACCESS_DENIED;
}
}
else
{
error = ERROR_ACCESS_DENIED;
}
}
if( error == 0 && truncate && fileExists == TRUE && !createAlways )
{
// Fix me: reset file date/time to original date/time.
}
// If everything is ok, then open the file
if( error == NO_ERROR )
{
// If we created a file, send a notification to OS...
if( create )
{
changeInfo.cbSize = sizeof( FILECHANGEINFO );
if( truncate && !createAlways )
{
changeInfo.wEventId = SHCNE_UPDATEITEM;
}
else
{
changeInfo.wEventId = SHCNE_CREATE;
}
changeInfo.uFlags = SHCNF_PATH|SHCNF_FLUSHNOWAIT;
// Get full file path name...
FSDMGR_GetVolumeName( pVolumeState->vs_Handle, fullFilePathname, MAX_PATH );
wcscat( fullFilePathname, lpFileName );
changeInfo.dwItem1 = (DWORD)fullFilePathname;
changeInfo.dwItem2 = (DWORD)NULL;
changeInfo.dwAttributes = gvpServerPB->fFileAttributes;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -