📄 find.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: find.c
Contains: Contains VirtualCE file system find interface.
Written by: Craig Vinet
Copyright: (c) 2002 Connectix Corporation
*/
#include "vcefsd.h"
#include "fserver.h"
#include "find.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
#define kMaxFC 40
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
extern ServerPB* gvpServerPB;
extern BOOL LongToFileTime( LONG longTime, PFILETIME pft );
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
FindContext gFCList[kMaxFC];
//--------------------------------------------------------------------------------
// Prototypes
//--------------------------------------------------------------------------------
int FindOpen( VolumeState *pVolume,
PCWSTR pwsFilePath,
PWIN32_FIND_DATAW pfd,
FindContext ** outFindContext );
int FindNext( FindContext * pFindContext );
USHORT FindPathElement( PServerPB pb, PCWSTR ptrName);
BOOL MatchesWildcard(DWORD lenWild, PCWSTR pchWild, DWORD lenFile, PCWSTR pchFile);
FindContext * AllocateFindContext( void );
BOOL FreeFindContext( FindContext * inFCPtr );
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
HANDLE VCEFSD_FindFirstFileW( VolumeState *pVolume,
HANDLE hProc,
PCWSTR pwsFilePath,
PWIN32_FIND_DATAW pfd )
{
HANDLE hSearch = INVALID_HANDLE_VALUE;
int error;
FindContext *pFindContext = NULL;
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: FSD_FindFirstFileW\n" ) ) );
EnterCriticalSection(&g_csMain);
error = FindOpen( pVolume,
pwsFilePath,
pfd,
&pFindContext );
if( error == NO_ERROR && pFindContext != NULL )
{
// Fill in the find struct
if( pfd )
{
pfd->dwFileAttributes = pFindContext->fServerPB.fFileAttributes;
LongToFileTime( pFindContext->fServerPB.fFileCreateTimeDate, &pfd->ftCreationTime );
LongToFileTime( pFindContext->fServerPB.fFileTimeDate, &pfd->ftLastAccessTime );
LongToFileTime( pFindContext->fServerPB.fFileTimeDate, &pfd->ftLastWriteTime );
pfd->nFileSizeHigh = 0;
pfd->nFileSizeLow = pFindContext->fServerPB.fSize;
// Copy Unicode name.
lstrcpyW( pfd->cFileName, pFindContext->fServerPB.u.fLfn.fName );
}
// Create FS search handle
hSearch = FSDMGR_CreateSearchHandle( pVolume->vs_Handle, hProc, (ulong)pFindContext );
}
else
{
SetLastError( ERROR_NO_MORE_FILES );
}
LeaveCriticalSection(&g_csMain);
return hSearch;
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL VCEFSD_FindNextFileW( FindContext* pFindContext,
PWIN32_FIND_DATAW pfd )
{
BOOL fSuccess = TRUE;
int error;
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: FSD_FindNextFileW\n" ) ) );
EnterCriticalSection(&g_csMain);
if( (error = FindNext( pFindContext )) != 0 )
{
SetLastError( error );
fSuccess = FALSE;
goto Done;
}
// Fill in the find struct
if( pfd )
{
pfd->dwFileAttributes = pFindContext->fServerPB.fFileAttributes;
LongToFileTime( pFindContext->fServerPB.fFileCreateTimeDate, &pfd->ftCreationTime );
LongToFileTime( pFindContext->fServerPB.fFileTimeDate, &pfd->ftLastAccessTime );
LongToFileTime( pFindContext->fServerPB.fFileTimeDate, &pfd->ftLastWriteTime );
pfd->nFileSizeHigh = 0;
pfd->nFileSizeLow = pFindContext->fServerPB.fSize;
// Copy Unicode name.
lstrcpyW( pfd->cFileName, pFindContext->fServerPB.u.fLfn.fName );
}
Done:
LeaveCriticalSection(&g_csMain);
return fSuccess;
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL VCEFSD_FindClose( FindContext* pFindContext )
{
BOOL fSuccess = TRUE;
DEBUGMSG( ZONE_APIS,( TEXT( "VCEFSD: FSD_FindNClose\n" ) ) );
EnterCriticalSection(&g_csMain);
FreeFindContext( pFindContext );
LeaveCriticalSection(&g_csMain);
return fSuccess;
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
int FindOpen( VolumeState *pVolume,
PCWSTR pwsFilePath,
PWIN32_FIND_DATAW pfd,
FindContext ** outFindContext )
{
FindContext* pFindContext;
int error;
PCWSTR namePtr;
*outFindContext = NULL;
// Allocate a Find Context
pFindContext = AllocateFindContext();
if( pFindContext == NULL )
return ( error = ERROR_NOT_ENOUGH_MEMORY );
error = Find( pVolume,
gvpServerPB,
pwsFilePath );
if( error != NO_ERROR )
{
FreeFindContext( pFindContext );
return error;
}
// Reset index for FindNext and capture the TransactionID from the FindContext
gvpServerPB->fIndex = -1;
gvpServerPB->fFindTransactionID = pFindContext->fServerPB.fFindTransactionID;
// copy over data...
memcpy( &pFindContext->fServerPB, gvpServerPB, sizeof( ServerPB ) );
// Get name for find next...
namePtr = pwsFilePath + lstrlenW( pwsFilePath ) - 1;
for( ; namePtr > pwsFilePath; namePtr-- )
{
if( *namePtr == L'\\' )
{
break;
}
}
namePtr++;
// Save name to continue FindnNext search...
lstrcpyW( pFindContext->fFindName, namePtr );
if( wcscmp( pFindContext->fFindName, L"*.*" ) == 0 )
{
pFindContext->fFindName[1] = 0;
pFindContext->fFindName[2] = 0;
}
error = FindNext( pFindContext ); // First call to FindNext sets file index to found file.
if( error != NO_ERROR )
{
FreeFindContext( pFindContext );
}
else
{
// Return info to caller
*outFindContext = pFindContext;
}
return error;
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
int Find( VolumeState* pVolume,
ServerPB* ioServerPB,
PCWSTR pwsPath )
{
USHORT result;
PWCHAR ptrName;
WCHAR PathCopy[_MAX_PATH];
wcsncpy(PathCopy, pwsPath, ARRAY_SIZE(PathCopy));
if (PathCopy[ARRAY_SIZE(PathCopy)-1] != L'\0') {
// The pwsPath is too long
return -1;
}
// initialize & setup the Virtual PC control block
memset( ioServerPB, 0, sizeof(ServerPB) );
ioServerPB->fStructureSize = sizeof(ServerPB);
ioServerPB->fFindTransactionID = 0xffffffff;
ioServerPB->fWildCard = FALSE;
ioServerPB->fHandle = kInvalidSrvHandle; // to recognize an unopened file
// Split PathCopy into directory path and file parts
ptrName = PathCopy + wcslen(PathCopy);
while (ptrName != PathCopy && *ptrName != L'\\' && *ptrName != L'/') {
ptrName--;
}
// If there is a pathname component, check on it
if (*ptrName == L'\\' || *ptrName == L'/') {
WCHAR TempChar;
TempChar = *(ptrName+1);
*(ptrName+1) = L'\0';
result = FindPathElement(ioServerPB, PathCopy );
if (result != 0) {
return -1;
}
// ensure we found a directory node
if ((ioServerPB->fFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
return -1;
}
*(ptrName+1) = TempChar;
}
// Now check the full pathname
// If there is a wildcard present, note it
if (wcschr(ptrName, L'*') || wcschr(ptrName, L'?')) {
ioServerPB->fWildCard = TRUE;
}
result = FindPathElement(ioServerPB, PathCopy);
if (result != 0) {
return -1;
}
return 0;
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
int FindNext( FindContext * pFindContext )
{
ULONG result;
// Get ptrs to the data we will need
if( pFindContext == NULL )
{
return ERROR_INVALID_PARAMETER;
}
// Copy saved data to global PB
memcpy( gvpServerPB, &pFindContext->fServerPB, sizeof( ServerPB ) );
// Search for the next file
do
{
// Move to the next file index
gvpServerPB->fIndex++;
// Get info on the next file
result = ServerGetInfo( gvpServerPB );
if( result != 0)
{
// No more files
return ERROR_NO_MORE_FILES;
}
if( MatchesWildcard( lstrlenW( pFindContext->fFindName ), pFindContext->fFindName, lstrlenW( gvpServerPB->u.fLfn.fName ), gvpServerPB->u.fLfn.fName ) )
{
// Copy over new PB..
memcpy( &pFindContext->fServerPB, gvpServerPB, sizeof( ServerPB ) );
return NO_ERROR;
}
}while( 1 );
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
USHORT FindPathElement( PServerPB pb, PCWSTR ptrName)
{
USHORT result;
pb->fIndex = -1; // only search for a name
if( pb->fWildCard)
pb->fIndex++;
pb->u.fLfn.fNameLength = lstrlenW(ptrName) * sizeof(WCHAR);
lstrcpyW( pb->u.fLfn.fName, ptrName );
result = ServerGetInfo( pb);
return result; // includes a successful return
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL MatchesWildcard(DWORD lenWild, PCWSTR pchWild, DWORD lenFile, PCWSTR pchFile)
{
while( lenWild && lenFile )
{
if( *pchWild == L'*' )
{
pchWild++;
if( --lenWild )
{
while( lenFile )
{
if( MatchesWildcard( lenWild, pchWild, lenFile--, pchFile++ ) )
return TRUE;
}
return FALSE;
}
return TRUE;
}
else if( ( *pchWild != L'?' ) && _wcsnicmp( pchWild, pchFile, 1 ) )
{
return FALSE;
}
lenWild--;
pchWild++;
lenFile--;
pchFile++;
}
// Done?
if( !lenWild && !lenFile )
{
return TRUE;
}
if( !lenWild )
{
return FALSE;
}
else
{
while( lenWild-- )
{
if( *pchWild++ != L'*' )
return FALSE;
}
}
return TRUE;
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
void InitFind( void )
{
int i;
for( i = 0; i < kMaxFC; i++ )
{
gFCList[i].fInUse = FALSE;
memset( &gFCList[i].fServerPB, 0, sizeof(ServerPB) );
memset( gFCList[i].fFindName, 0, sizeof(gFCList[i].fFindName) );
}
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
FindContext * AllocateFindContext( void )
{
int i;
for( i = 0; i < kMaxFC; i++ )
{
if( gFCList[i].fInUse == FALSE )
{
gFCList[i].fInUse = TRUE;
// Welcome to the department of redundency department...
memset( &gFCList[i].fServerPB, 0, sizeof(ServerPB) );
memset( gFCList[i].fFindName, 0, sizeof(gFCList[i].fFindName) );
gFCList[i].fServerPB.fStructureSize = sizeof(ServerPB);
gFCList[i].fServerPB.fFindTransactionID = i;
return &gFCList[i];
}
}
return NULL;
}
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
BOOL FreeFindContext( FindContext * inFCPtr )
{
int i;
for( i = 0; i < kMaxFC; i++ )
{
if( inFCPtr == & gFCList[i] )
{
inFCPtr->fInUse = FALSE;
memset( &inFCPtr->fServerPB, 0, sizeof(ServerPB) );
memset( inFCPtr->fFindName, 0, sizeof(inFCPtr->fFindName) );
return TRUE;
}
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -