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

📄 istream.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
{
  IStream_fnQueryInterface,
  IStream_fnAddRef,
  IStream_fnRelease,
  IStream_fnRead,
  IStream_fnWrite,
  IStream_fnSeek,
  IStream_fnSetSize,
  IStream_fnCopyTo,
  IStream_fnCommit,
  IStream_fnRevert,
  IStream_fnLockUnlockRegion,
  IStream_fnLockUnlockRegion,
  IStream_fnStat,
  IStream_fnClone
};

/**************************************************************************
 * IStream_Create
 *
 * Internal helper: Create and initialise a new file stream object.
 */
static IStream *IStream_Create(LPCWSTR lpszPath, HANDLE hFile, DWORD dwMode)
{
 ISHFileStream* fileStream;

 fileStream = HeapAlloc(GetProcessHeap(), 0, sizeof(ISHFileStream));

 if (fileStream)
 {
   fileStream->lpVtbl = &SHLWAPI_fsVTable;
   fileStream->ref = 1;
   fileStream->hFile = hFile;
   fileStream->dwMode = dwMode;
   fileStream->lpszPath = StrDupW(lpszPath);
   fileStream->type = 0; /* FIXME */
   fileStream->grfStateBits = 0; /* FIXME */
 }
 TRACE ("Returning %p\n", fileStream);
 return (IStream *)fileStream;
}

/*************************************************************************
 * SHCreateStreamOnFileEx   [SHLWAPI.@]
 *
 * Create a stream on a file.
 *
 * PARAMS
 *  lpszPath     [I] Path of file to create stream on
 *  dwMode       [I] Mode to create stream in
 *  dwAttributes [I] Attributes of the file
 *  bCreate      [I] Whether to create the file if it doesn't exist
 *  lpTemplate   [I] Reserved, must be NULL
 *  lppStream    [O] Destination for created stream
 *
 * RETURNS
 * Success: S_OK. lppStream contains the new stream object
 * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code
 *
 * NOTES
 *  This function is available in Unicode only.
 */
HRESULT WINAPI SHCreateStreamOnFileEx(LPCWSTR lpszPath, DWORD dwMode,
                                      DWORD dwAttributes, BOOL bCreate,
                                      IStream *lpTemplate, IStream **lppStream)
{
  DWORD dwAccess, dwShare, dwCreate;
  HANDLE hFile;

  TRACE("(%s,%d,0x%08X,%d,%p,%p)\n", debugstr_w(lpszPath), dwMode,
        dwAttributes, bCreate, lpTemplate, lppStream);

  if (!lpszPath || !lppStream || lpTemplate)
    return E_INVALIDARG;

  *lppStream = NULL;

  if (dwMode & STGM_TRANSACTED)
    return E_INVALIDARG;

  /* Access */
  switch (STGM_ACCESS_MODE(dwMode))
  {
  case STGM_READWRITE:
    dwAccess = GENERIC_READ|GENERIC_WRITE;
    break;
  case STGM_WRITE:
    dwAccess = GENERIC_WRITE;
    break;
  case STGM_READ:
    dwAccess = GENERIC_READ;
    break;
  default:
    return E_INVALIDARG;
  }

  /* Sharing */
  switch (STGM_SHARE_MODE(dwMode))
  {
  case STGM_SHARE_DENY_READ:
    dwShare = FILE_SHARE_WRITE;
    break;
  case STGM_SHARE_DENY_WRITE:
    dwShare = FILE_SHARE_READ;
    break;
  case STGM_SHARE_EXCLUSIVE:
    dwShare = 0;
    break;
  case STGM_SHARE_DENY_NONE:
    dwShare = FILE_SHARE_READ|FILE_SHARE_WRITE;
    break;
  default:
    return E_INVALIDARG;
  }

  switch(STGM_CREATE_MODE(dwMode))
  {
  case STGM_FAILIFTHERE:
    dwCreate = OPEN_EXISTING;
    break;
  case STGM_CREATE:
    dwCreate = CREATE_ALWAYS;
    break;
  default:
    return E_INVALIDARG;
  }

  /* Open HANDLE to file */
  hFile = CreateFileW(lpszPath, dwAccess, dwShare, NULL, dwCreate,
                      dwAttributes, 0);

  if(hFile == INVALID_HANDLE_VALUE)
  {
    HRESULT hRet = (HRESULT)GetLastError();
    if(hRet > 0)
      hRet = HRESULT_FROM_WIN32(hRet);
    return hRet;
  }

  *lppStream = IStream_Create(lpszPath, hFile, dwMode);

  if(!*lppStream)
  {
    CloseHandle(hFile);
    return E_OUTOFMEMORY;
  }
  return S_OK;
}

/*************************************************************************
 * SHCreateStreamOnFileW   [SHLWAPI.@]
 *
 * See SHCreateStreamOnFileA.
 */
HRESULT WINAPI SHCreateStreamOnFileW(LPCWSTR lpszPath, DWORD dwMode,
                                   IStream **lppStream)
{
  TRACE("(%s,%d,%p)\n", debugstr_w(lpszPath), dwMode, lppStream);

  if (!lpszPath || !lppStream)
    return E_INVALIDARG;

  return SHCreateStreamOnFileEx(lpszPath, dwMode, 0, FALSE, NULL, lppStream);
}

/*************************************************************************
 * SHCreateStreamOnFileA   [SHLWAPI.@]
 *
 * Create a stream on a file.
 *
 * PARAMS
 *  lpszPath  [I] Path of file to create stream on
 *  dwMode    [I] Mode to create stream in
 *  lppStream [O] Destination for created IStream object
 *
 * RETURNS
 * Success: S_OK. lppStream contains the new IStream object
 * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code
 */
HRESULT WINAPI SHCreateStreamOnFileA(LPCSTR lpszPath, DWORD dwMode,
                                     IStream **lppStream)
{
  WCHAR szPath[MAX_PATH];

  TRACE("(%s,%d,%p)\n", debugstr_a(lpszPath), dwMode, lppStream);

  if (!lpszPath)
    return E_INVALIDARG;
  MultiByteToWideChar(0, 0, lpszPath, -1, szPath, MAX_PATH);
  return SHCreateStreamOnFileW(szPath, dwMode, lppStream);
}

/*************************************************************************
 * @       [SHLWAPI.184]
 *
 * Call IStream_Read() on a stream.
 *
 * PARAMS
 *  lpStream [I] IStream object
 *  lpvDest  [O] Destination for data read
 *  ulSize   [I] Size of data to read
 *
 * RETURNS
 *  Success: S_OK. ulSize bytes have been read from the stream into lpvDest.
 *  Failure: An HRESULT error code, or E_FAIL if the read succeeded but the
 *           number of bytes read does not match.
 */
HRESULT WINAPI SHLWAPI_184(IStream *lpStream, LPVOID lpvDest, ULONG ulSize)
{
  ULONG ulRead;
  HRESULT hRet;

  TRACE("(%p,%p,%d)\n", lpStream, lpvDest, ulSize);

  hRet = IStream_Read(lpStream, lpvDest, ulSize, &ulRead);

  if (SUCCEEDED(hRet) && ulRead != ulSize)
    hRet = E_FAIL;
  return hRet;
}

/*************************************************************************
 * @       [SHLWAPI.166]
 *
 * Determine if a stream has 0 length.
 *
 * PARAMS
 *  lpStream [I] IStream object
 *
 * RETURNS
 *  TRUE:  If the stream has 0 length
 *  FALSE: Otherwise.
 */
BOOL WINAPI SHIsEmptyStream(IStream *lpStream)
{
  STATSTG statstg;
  BOOL bRet = TRUE;

  TRACE("(%p)\n", lpStream);

  memset(&statstg, 0, sizeof(statstg));

  if(SUCCEEDED(IStream_Stat(lpStream, &statstg, 1)))
  {
    if(statstg.cbSize.QuadPart)
      bRet = FALSE; /* Non-Zero */
  }
  else
  {
    DWORD dwDummy;

    /* Try to read from the stream */
    if(SUCCEEDED(SHLWAPI_184(lpStream, &dwDummy, sizeof(dwDummy))))
    {
      LARGE_INTEGER zero;
      zero.QuadPart = 0;

      IStream_Seek(lpStream, zero, 0, NULL);
      bRet = FALSE; /* Non-Zero */
    }
  }
  return bRet;
}

/*************************************************************************
 * @       [SHLWAPI.212]
 *
 * Call IStream_Write() on a stream.
 *
 * PARAMS
 *  lpStream [I] IStream object
 *  lpvSrc   [I] Source for data to write
 *  ulSize   [I] Size of data
 *
 * RETURNS
 *  Success: S_OK. ulSize bytes have been written to the stream from lpvSrc.
 *  Failure: An HRESULT error code, or E_FAIL if the write succeeded but the
 *           number of bytes written does not match.
 */
HRESULT WINAPI SHLWAPI_212(IStream *lpStream, LPCVOID lpvSrc, ULONG ulSize)
{
  ULONG ulWritten;
  HRESULT hRet;

  TRACE("(%p,%p,%d)\n", lpStream, lpvSrc, ulSize);

  hRet = IStream_Write(lpStream, lpvSrc, ulSize, &ulWritten);

  if (SUCCEEDED(hRet) && ulWritten != ulSize)
    hRet = E_FAIL;

  return hRet;
}

/*************************************************************************
 * @       [SHLWAPI.213]
 *
 * Seek to the start of a stream.
 *
 * PARAMS
 *  lpStream [I] IStream object
 *
 * RETURNS
 *  Success: S_OK. The current position within the stream is updated
 *  Failure: An HRESULT error code.
 */
HRESULT WINAPI IStream_Reset(IStream *lpStream)
{
  LARGE_INTEGER zero;
  TRACE("(%p)\n", lpStream);
  zero.QuadPart = 0;
  return IStream_Seek(lpStream, zero, 0, NULL);
}

/*************************************************************************
 * @       [SHLWAPI.214]
 *
 * Get the size of a stream.
 *
 * PARAMS
 *  lpStream [I] IStream object
 *  lpulSize [O] Destination for size
 *
 * RETURNS
 *  Success: S_OK. lpulSize contains the size of the stream.
 *  Failure: An HRESULT error code.
 */
HRESULT WINAPI IStream_Size(IStream *lpStream, ULARGE_INTEGER* lpulSize)
{
  STATSTG statstg;
  HRESULT hRet;

  TRACE("(%p,%p)\n", lpStream, lpulSize);

  memset(&statstg, 0, sizeof(statstg));

  hRet = IStream_Stat(lpStream, &statstg, 1);

  if (SUCCEEDED(hRet) && lpulSize)
    *lpulSize = statstg.cbSize;
  return hRet;
}

⌨️ 快捷键说明

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