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

📄 findstream.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
字号:
/*__________________________________________________________________________
 Copyright (C) 2002 PGP Corporation
 All rights reserved.
 
 $Id: FindStream.c,v 1.2 2002/08/06 20:10:09 dallen Exp $
__________________________________________________________________________*/

#include <windows.h>
#include <tchar.h>

#ifndef UNICODE
   #include <stdio.h>
#endif

#include "findstream.h"

// FFSTREAMMAGIC is a magic number used to identify a block of memory as FFSTREAM type
#define FFSTREAMMAGIC 0x54534646

// FFSTREAM is used to track where we are in the process of enumerating streams.
typedef struct _FFSTREAM
{
   DWORD   dwFFStreamMagic;
   HANDLE  hFile;
   LPVOID  lpContext;
} FFSTREAM, *LPFFSTREAM;

#define lenof(x)  ((sizeof(x) / sizeof(TCHAR)) - 1)

// DATASTUFFIX is a suffix at the end of stream names returned from BackupRead
#define DATASUFFIX  _T(":$DATA")

/*----------------------------------------------------------------
ffproc(LPFFSTREAM lpFFStream, LPSTREAM_FIND_DATA lpFindStreamData)

This function is the core function used by FindFirstStream and FindNextStream.
Its purpose is to use BackupRead to read the stream header and get the stream
name.  It will then skip the data portion of the backup stream using BackupSeek.
It returns once it finds a backup stream of type ID BACKUP_DATA or
BACKUP_ALTERNATE_DATA or when there is no more data to read.

lpFFStream
    Buffer used internally by FindxxxStream to keep track of
    context.
lpFindStreamData
    Buffer passed thru FindxxxStream used to return stream
    information to the caller

Returns TRUE if successful, FALSE if not.

On failure GetLastError can return:

ERROR_NO_MORE_FILES
    There are no more stream in the file
ERROR_READ_FAULT
    BackupRead returned an error
ERROR_OUTOFMEMROY
   Could not allocate memory to hold internal status information

----------------------------------------------------------------*/

static BOOL ffproc(LPFFSTREAM lpFFStream, LPSTREAM_FIND_DATA lpFindStreamData)
{
   WIN32_STREAM_ID BackupStreamHeader;
   LPWSTR lpStreamName;
   DWORD dwLoToSeek, dwHiToSeek;
   DWORD dwLoSeek, dwHiSeek;
   DWORD dwToRead, dwRead;
   BOOL bFoundDataStream;

   // Enumerate the streams now
   // we loop here until we get a stream with ID BACKUP_DATA or
   // BACKUP_ALTERNATE_DATA
   bFoundDataStream = FALSE;
   while (!bFoundDataStream)
   {
      // Read the backup stream header
      // We read up to the stream name
      dwToRead = (DWORD)((LPBYTE)&(BackupStreamHeader.cStreamName[0]) -
                 (LPBYTE)&BackupStreamHeader.dwStreamId);

      if (!BackupRead(lpFFStream->hFile, (BYTE *)&BackupStreamHeader, dwToRead,
                      &dwRead, FALSE, TRUE, &(lpFFStream->lpContext)))
      {
         SetLastError(ERROR_READ_FAULT);
         return FALSE;
      }

      if (dwRead == 0)
      {
         SetLastError(ERROR_NO_MORE_FILES);
         return FALSE;
      }

      // if there is a stream name (length > 0), then process it
      if (BackupStreamHeader.dwStreamNameSize > 0)
      {
         // the stream name is a Unicode string.  BackupRead returns the
         // stream name length in bytes.

         // allocate enough memory to hold the stream name (including the
         // terminating null)
         if ((lpStreamName = (LPWSTR)HeapAlloc(GetProcessHeap(), 0,
                                               BackupStreamHeader.dwStreamNameSize +
                                               sizeof(WCHAR))) == NULL)
         {
            SetLastError(ERROR_OUTOFMEMORY);
            return FALSE;
         }


         if (!BackupRead(lpFFStream->hFile, (LPBYTE)lpStreamName,
                         BackupStreamHeader.dwStreamNameSize, &dwRead, FALSE, TRUE,
                         &(lpFFStream->lpContext)))
         {
            SetLastError(ERROR_READ_FAULT);
            return FALSE;
         }

         // Fill in the terminating nul for the string
         lpStreamName[BackupStreamHeader.dwStreamNameSize / sizeof(WCHAR)] =
         _T('\0');
      }
      else
         lpStreamName = L"";


      if (BackupStreamHeader.dwStreamId == BACKUP_DATA ||
          BackupStreamHeader.dwStreamId == BACKUP_ALTERNATE_DATA)
      {
         bFoundDataStream = TRUE;

         // Record the size of the stream in structure passed by caller
         lpFindStreamData->Size.QuadPart = BackupStreamHeader.Size.QuadPart;

#ifdef UNICODE
         // if Unicode, then copy the name to the structure passed by caller
         lstrcpy(lpFindStreamData->cStreamName, lpStreamName);
#else
         // if ANSI then convert the name into the structure passed by caller
         WideCharToMultiByte(CP_ACP, 0, lpStreamName, -1,
                             lpFindStreamData->cStreamName,
                             sizeof(lpFindStreamData->cStreamName), NULL, NULL);
#endif

         // remove :$DATA at end...
         if (lstrcmp(lpFindStreamData->cStreamName +
                     lstrlen(lpFindStreamData->cStreamName) -
                     lenof(DATASUFFIX),
                     DATASUFFIX) == 0)
         {
            lpFindStreamData->cStreamName[
                                         lstrlen(lpFindStreamData->cStreamName) -
                                         lenof(DATASUFFIX)] = _T('\0');
         }

         // remove : at beginning...
         if (*lpFindStreamData->cStreamName == _T(':'))
            lstrcpy(lpFindStreamData->cStreamName,
                    lpFindStreamData->cStreamName + 1);
      }

      // if the stream had a name, then free the memory used to hold it
      if (BackupStreamHeader.dwStreamNameSize > 0)
         HeapFree(GetProcessHeap(), 0, lpStreamName);

      // Skip the stream data
      dwLoToSeek = BackupStreamHeader.Size.LowPart;
      dwHiToSeek = BackupStreamHeader.Size.HighPart;
      if (!BackupSeek(lpFFStream->hFile, dwLoToSeek, dwHiToSeek, &dwLoSeek,
                      &dwHiSeek, &(lpFFStream->lpContext)))
      {
         SetLastError(ERROR_READ_FAULT);
         return FALSE;
      }
   }

   return TRUE;
}

/*----------------------------------------------------------------
FindFirstStream(LPCTSTR lpFileName,
                LPSTREAM_FIND_DATA lpFindStreamData)

The FindFirstStream function enumerates the streams contained in the
file specified by lpFileName.  Use FindNextStream to continue
enumerating streams.  Use FindCloseStream when done.

lpFileName
    Null terminated string contains the name of file to enumerate
    streams
lpFindStreamData
    Buffer used to return stream information to the caller

Returns INVALID_HANDLE_VALUE if it fails, a HANDLE otherwise

On failure GetLastError can return:

ERROR_FILE_NOT_FOUND
   The file does not exist or it does not contain any streams.
   Note that empty files do not contain any streams.
ERROR_READ_FAULT
   Could not read the names of the streams
ERROR_OUTOFMEMROY
   Could not allocate memory to hold internal status information

Other error codes could be passed from lower level APIs
----------------------------------------------------------------*/

HANDLE FindFirstStream(LPCTSTR lpFileName, LPSTREAM_FIND_DATA lpFindStreamData)
{
   LPFFSTREAM lpFFStream;

   if ((lpFFStream = HeapAlloc(GetProcessHeap(), 0, sizeof(FFSTREAM))) == NULL)
   {
      SetLastError(ERROR_OUTOFMEMORY);
      return INVALID_HANDLE_VALUE;
   }

   // set the magic number which mark the handle as valid...
   lpFFStream->dwFFStreamMagic = FFSTREAMMAGIC;
   lpFFStream->lpContext = NULL;

   if ((lpFFStream->hFile = CreateFile(lpFileName, GENERIC_READ,
                                       FILE_SHARE_READ | FILE_SHARE_WRITE,
                                       NULL, OPEN_EXISTING,
                                       FILE_FLAG_BACKUP_SEMANTICS, NULL)) ==
       INVALID_HANDLE_VALUE)
   {
      HeapFree(GetProcessHeap(), 0, lpFFStream);
      // pass on error from CreateFile...
      return INVALID_HANDLE_VALUE;
   }

   if (!ffproc(lpFFStream, lpFindStreamData))
   {
      // free resource on failure...
      CloseHandle(lpFFStream->hFile);

      HeapFree(GetProcessHeap(), 0, lpFFStream);

      // pass on error...
      if (GetLastError() == ERROR_NO_MORE_FILES)
         SetLastError(ERROR_FILE_NOT_FOUND);
      return INVALID_HANDLE_VALUE;
   }

   return (HANDLE)lpFFStream;
}

/*----------------------------------------------------------------
FindNextStream(HANDLE hFindStream,
                LPSTREAM_FIND_DATA lpFindStreamData)

The FindNextStream function continues enumerating the streams
specified by hFindStream.  Use FindFirstStream to start the
enumeration.  Use FindCloseStream when done.

hFindStream
    Handle returned from FindFirstStream
lpFindStreamData
    Buffer used to return stream information to the caller

Returns TRUE if it succeeds, FALSE otherwise.

On failure GetLastError can return:

ERROR_INVALID_HANDLE
    The passed handle was not created using FindFirstStream or
    was closed already.
ERROR_NO_MORE_FILES
    There are no more stream in the file
ERROR_READ_FAULT
    There was a problem reading stream names using the Backup
    APIs.
ERROR_OUTOFMEMROY
    Could not allocate memory to hold internal status information

----------------------------------------------------------------*/

BOOL FindNextStream(HANDLE hFindStream, LPSTREAM_FIND_DATA lpFindStreamData)
{
   LPFFSTREAM lpFFStream = (LPFFSTREAM)hFindStream;

   // verify that the passed structure is a FFSTREAM structure...
   if (lpFFStream->dwFFStreamMagic != FFSTREAMMAGIC)
   {
      SetLastError(ERROR_INVALID_HANDLE);
      return FALSE;
   }

   if (!ffproc(lpFFStream, lpFindStreamData))
   {
      // pass on error...
      return FALSE;
   }

   return TRUE;
}

/*----------------------------------------------------------------
FindCloseStream(HANDLE hFindStream)

The FindCloseStream function releases the resources used to
enumerate the streams specified by hFindStream.  Use FindFirstStream
to start the enumeration.

hFindStream
    Handle returned from FindFirstStream

Returns TRUE if it succeeds, FALSE otherwise.

On failure GetLastError can return:

ERROR_INVALID_HANDLE
    The passed handle was not created using FindFirstStream or
    was closed already.

----------------------------------------------------------------*/
BOOL FindCloseStream(HANDLE hFindStream)
{
   LPFFSTREAM lpFFStream = (LPFFSTREAM)hFindStream;

   // verify that the passed structure is a FFSTREAM structure...
   if (lpFFStream->dwFFStreamMagic != FFSTREAMMAGIC)
   {
      SetLastError(ERROR_INVALID_HANDLE);
      return FALSE;
   }

   // Release the context memory
   BackupRead(0, NULL, 0, NULL, TRUE, FALSE, &(lpFFStream->lpContext));

   // Close the file handle
   CloseHandle(lpFFStream->hFile);

   // obliterate the magic number of handle making it invalid...
   lpFFStream->dwFFStreamMagic = 0;

   // Free the handle...
   HeapFree(GetProcessHeap(), 0, lpFFStream);

   return TRUE;
}


/*__Editor_settings____

	Local Variables:
	tab-width: 4
	End:
	vi: ts=4 sw=4
	vim: si
_____________________*/

⌨️ 快捷键说明

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