Example #1
0
/**************************************************************************
 * IStream_fnWrite
 */
static HRESULT WINAPI IStream_fnWrite(IStream *iface, const void* pv, ULONG cb, ULONG* pcbWritten)
{
  ISHFileStream *This = (ISHFileStream *)iface;
  DWORD dwWritten = 0;

  TRACE("(%p,%p,0x%08lx,%p)\n", This, pv, cb, pcbWritten);

  if (!pv)
    return STG_E_INVALIDPOINTER;

  switch (STGM_ACCESS_MODE(This->dwMode))
  {
  case STGM_WRITE:
  case STGM_READWRITE:
    break;
  default:
    return E_FAIL;
  }

  if (!WriteFile(This->hFile, pv, cb, &dwWritten, NULL))
    return HRESULT_FROM_WIN32(GetLastError());

  if (pcbWritten)
    *pcbWritten = dwWritten;
  return S_OK;
}
Example #2
0
/****************************************************************************
 *      GetProtectMode
 *
 * This function will return a protection mode flag for a file-mapping object
 * from the open flags of a file.
 */
static DWORD GetProtectMode(DWORD openFlags)
{
    switch(STGM_ACCESS_MODE(openFlags))
    {
    case STGM_WRITE:
    case STGM_READWRITE:
        return PAGE_READWRITE;
    }
    return PAGE_READONLY;
}
Example #3
0
/*************************************************************************
 * 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;

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

  /* Sharing */
  switch (STGM_SHARE_MODE(dwMode))
  {
  case 0:
  case STGM_SHARE_DENY_NONE:
    dwShare = FILE_SHARE_READ|FILE_SHARE_WRITE;
    break;
  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;
  default:
    return E_INVALIDARG;
  }

  switch(STGM_CREATE_MODE(dwMode))
  {
  case STGM_FAILIFTHERE:
    dwCreate = bCreate ? CREATE_NEW : 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)
    return HRESULT_FROM_WIN32(GetLastError());

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

  if(!*lppStream)
  {
    CloseHandle(hFile);
    return E_OUTOFMEMORY;
  }
  return S_OK;
}
Example #4
0
/***
 * This method is part of the ISequentialStream interface.
 *
 * It writes a block of information to the stream at the current
 * position. It then moves the current position at the end of the
 * written block. If the stream is too small to fit the block,
 * the stream is grown to fit.
 *
 * See the documentation of ISequentialStream for more info.
 */
static HRESULT WINAPI StgStreamImpl_Write(
	          IStream*     iface,
		  const void*    pv,          /* [size_is][in] */
		  ULONG          cb,          /* [in] */
		  ULONG*         pcbWritten)  /* [out] */
{
  StgStreamImpl* This = impl_from_IStream(iface);

  ULONG bytesWritten = 0;
  HRESULT res;

  TRACE("(%p, %p, %d, %p)\n",
	iface, pv, cb, pcbWritten);

  /*
   * Do we have permission to write to this stream?
   */
  switch(STGM_ACCESS_MODE(This->grfMode))
  {
  case STGM_WRITE:
  case STGM_READWRITE:
      break;
  default:
      WARN("access denied by flags: 0x%x\n", STGM_ACCESS_MODE(This->grfMode));
      return STG_E_ACCESSDENIED;
  }

  if (!pv)
    return STG_E_INVALIDPOINTER;

  if (!This->parentStorage)
  {
    WARN("storage reverted\n");
    return STG_E_REVERTED;
  }
 
  /*
   * If the caller is not interested in the number of bytes written,
   * we use another buffer to avoid "if" statements in the code.
   */
  if (pcbWritten == 0)
    pcbWritten = &bytesWritten;

  /*
   * Initialize the out parameter
   */
  *pcbWritten = 0;

  if (cb == 0)
  {
    TRACE("<-- S_OK, written 0\n");
    return S_OK;
  }

  res = StorageBaseImpl_StreamWriteAt(This->parentStorage,
                                      This->dirEntry,
                                      This->currentPosition,
                                      cb,
                                      pv,
                                      pcbWritten);

  /*
   * Advance the position pointer for the number of positions written.
   */
  This->currentPosition.QuadPart += *pcbWritten;

  if (SUCCEEDED(res))
    res = StorageBaseImpl_Flush(This->parentStorage);

  TRACE("<-- %08x, written %u\n", res, *pcbWritten);
  return res;
}
Example #5
0
/***
 * This method is part of the ISequentialStream interface.
 *
 * It writes a block of information to the stream at the current
 * position. It then moves the current position at the end of the
 * written block. If the stream is too small to fit the block,
 * the stream is grown to fit.
 *
 * See the documentation of ISequentialStream for more info.
 */
static HRESULT WINAPI StgStreamImpl_Write(
	          IStream*     iface,
		  const void*    pv,          /* [size_is][in] */
		  ULONG          cb,          /* [in] */
		  ULONG*         pcbWritten)  /* [out] */
{
  StgStreamImpl* const This=(StgStreamImpl*)iface;

  ULARGE_INTEGER newSize;
  ULONG bytesWritten = 0;

  TRACE("(%p, %p, %ld, %p)\n",
	iface, pv, cb, pcbWritten);

  /*
   * Do we have permission to write to this stream?
   */
  switch(STGM_ACCESS_MODE(This->grfMode))
  {
  case STGM_WRITE:
  case STGM_READWRITE:
      break;
  default:
      WARN("access denied by flags: 0x%lx\n", STGM_ACCESS_MODE(This->grfMode));
      return STG_E_ACCESSDENIED;
  }

  if (!pv)
    return STG_E_INVALIDPOINTER;

  if (!This->parentStorage)
  {
    WARN("storage reverted\n");
    return STG_E_REVERTED;
  }
 
  /*
   * If the caller is not interested in the number of bytes written,
   * we use another buffer to avoid "if" statements in the code.
   */
  if (pcbWritten == 0)
    pcbWritten = &bytesWritten;

  /*
   * Initialize the out parameter
   */
  *pcbWritten = 0;

  if (cb == 0)
  {
    TRACE("<-- S_OK, written 0\n");
    return S_OK;
  }
  else
  {
    newSize.u.HighPart = 0;
    newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
  }

  /*
   * Verify if we need to grow the stream
   */
  if (newSize.u.LowPart > This->streamSize.u.LowPart)
  {
    /* grow stream */
    IStream_SetSize(iface, newSize);
  }

  /*
   * Depending on the type of chain that was opened when the stream was constructed,
   * we delegate the work to the method that readwrites to the block chains.
   */
  if (This->smallBlockChain!=0)
  {
    SmallBlockChainStream_WriteAt(This->smallBlockChain,
				  This->currentPosition,
				  cb,
				  pv,
				  pcbWritten);

  }
  else if (This->bigBlockChain!=0)
  {
    BlockChainStream_WriteAt(This->bigBlockChain,
			     This->currentPosition,
			     cb,
			     pv,
			     pcbWritten);
  }
  else
    assert(FALSE);

  /*
   * Advance the position pointer for the number of positions written.
   */
  This->currentPosition.u.LowPart += *pcbWritten;

  TRACE("<-- S_OK, written %lu\n", *pcbWritten);
  return S_OK;
}