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

📄 find.c

📁 我自己编译的armv4i wince60模拟器的bps源文件,已经验证可以使用,欢迎下载
💻 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 + -