ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

istream.c
Go to the documentation of this file.
00001 /*
00002  * SHLWAPI IStream functions
00003  *
00004  * Copyright 2002 Jon Griffiths
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 #include <stdarg.h>
00021 #include <string.h>
00022 
00023 #define COBJMACROS
00024 #define NONAMELESSUNION
00025 #define NONAMELESSSTRUCT
00026 
00027 #include "windef.h"
00028 #include "winbase.h"
00029 #include "winerror.h"
00030 #include "winnls.h"
00031 #define NO_SHLWAPI_REG
00032 #define NO_SHLWAPI_PATH
00033 #include "shlwapi.h"
00034 #include "wine/debug.h"
00035 
00036 WINE_DEFAULT_DEBUG_CHANNEL(shell);
00037 
00038 #define STGM_ACCESS_MODE(stgm)   ((stgm)&0x0000f)
00039 #define STGM_SHARE_MODE(stgm)    ((stgm)&0x000f0)
00040 #define STGM_CREATE_MODE(stgm)   ((stgm)&0x0f000)
00041 
00042 /* Layout of ISHFileStream object */
00043 typedef struct
00044 {
00045   const IStreamVtbl *lpVtbl;
00046   LONG     ref;
00047   HANDLE   hFile;
00048   DWORD    dwMode;
00049   LPOLESTR lpszPath;
00050   DWORD    type;
00051   DWORD    grfStateBits;
00052 } ISHFileStream;
00053 
00054 static HRESULT WINAPI IStream_fnCommit(IStream*,DWORD);
00055 
00056 
00057 /**************************************************************************
00058 *  IStream_fnQueryInterface
00059 */
00060 static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj)
00061 {
00062   ISHFileStream *This = (ISHFileStream *)iface;
00063 
00064   TRACE("(%p,%s,%p)\n", This, debugstr_guid(riid), ppvObj);
00065 
00066   *ppvObj = NULL;
00067 
00068   if(IsEqualIID(riid, &IID_IUnknown) ||
00069      IsEqualIID(riid, &IID_IStream))
00070   {
00071     *ppvObj = This;
00072     IStream_AddRef(iface);
00073     return S_OK;
00074   }
00075   return E_NOINTERFACE;
00076 }
00077 
00078 /**************************************************************************
00079 *  IStream_fnAddRef
00080 */
00081 static ULONG WINAPI IStream_fnAddRef(IStream *iface)
00082 {
00083   ISHFileStream *This = (ISHFileStream *)iface;
00084   ULONG refCount = InterlockedIncrement(&This->ref);
00085   
00086   TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);
00087 
00088   return refCount;
00089 }
00090 
00091 /**************************************************************************
00092 *  IStream_fnRelease
00093 */
00094 static ULONG WINAPI IStream_fnRelease(IStream *iface)
00095 {
00096   ISHFileStream *This = (ISHFileStream *)iface;
00097   ULONG refCount = InterlockedDecrement(&This->ref); 
00098 
00099   TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);
00100   
00101   if (!refCount)
00102   {
00103     IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */
00104     LocalFree(This->lpszPath);
00105     CloseHandle(This->hFile);
00106     HeapFree(GetProcessHeap(), 0, This);
00107   }
00108   
00109   return refCount;
00110 }
00111 
00112 /**************************************************************************
00113  * IStream_fnRead
00114  */
00115 static HRESULT WINAPI IStream_fnRead(IStream *iface, void* pv, ULONG cb, ULONG* pcbRead)
00116 {
00117   ISHFileStream *This = (ISHFileStream *)iface;
00118   DWORD dwRead = 0;
00119 
00120   TRACE("(%p,%p,0x%08x,%p)\n", This, pv, cb, pcbRead);
00121 
00122   if (!ReadFile(This->hFile, pv, cb, &dwRead, NULL))
00123   {
00124     WARN("error %d reading file\n", GetLastError());
00125     return S_FALSE;
00126   }
00127   if (pcbRead)
00128     *pcbRead = dwRead;
00129   return S_OK;
00130 }
00131 
00132 /**************************************************************************
00133  * IStream_fnWrite
00134  */
00135 static HRESULT WINAPI IStream_fnWrite(IStream *iface, const void* pv, ULONG cb, ULONG* pcbWritten)
00136 {
00137   ISHFileStream *This = (ISHFileStream *)iface;
00138   DWORD dwWritten = 0;
00139 
00140   TRACE("(%p,%p,0x%08x,%p)\n", This, pv, cb, pcbWritten);
00141 
00142   switch (STGM_ACCESS_MODE(This->dwMode))
00143   {
00144   case STGM_WRITE:
00145   case STGM_READWRITE:
00146     break;
00147   default:
00148     return STG_E_ACCESSDENIED;
00149   }
00150 
00151   if (!WriteFile(This->hFile, pv, cb, &dwWritten, NULL))
00152     return HRESULT_FROM_WIN32(GetLastError());
00153 
00154   if (pcbWritten)
00155     *pcbWritten = dwWritten;
00156   return S_OK;
00157 }
00158 
00159 /**************************************************************************
00160  *  IStream_fnSeek
00161  */
00162 static HRESULT WINAPI IStream_fnSeek(IStream *iface, LARGE_INTEGER dlibMove,
00163                                      DWORD dwOrigin, ULARGE_INTEGER* pNewPos)
00164 {
00165   ISHFileStream *This = (ISHFileStream *)iface;
00166   DWORD dwPos;
00167 
00168   TRACE("(%p,%d,%d,%p)\n", This, dlibMove.u.LowPart, dwOrigin, pNewPos);
00169 
00170   IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */
00171   dwPos = SetFilePointer(This->hFile, dlibMove.u.LowPart, NULL, dwOrigin);
00172   if( dwPos == INVALID_SET_FILE_POINTER )
00173      return HRESULT_FROM_WIN32(GetLastError());
00174 
00175   if (pNewPos)
00176   {
00177     pNewPos->u.HighPart = 0;
00178     pNewPos->u.LowPart = dwPos;
00179   }
00180   return S_OK;
00181 }
00182 
00183 /**************************************************************************
00184  * IStream_fnSetSize
00185  */
00186 static HRESULT WINAPI IStream_fnSetSize(IStream *iface, ULARGE_INTEGER libNewSize)
00187 {
00188   ISHFileStream *This = (ISHFileStream *)iface;
00189 
00190   TRACE("(%p,%d)\n", This, libNewSize.u.LowPart);
00191 
00192   IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */
00193   if( ! SetFilePointer( This->hFile, libNewSize.QuadPart, NULL, FILE_BEGIN ) )
00194     return E_FAIL;
00195 
00196   if( ! SetEndOfFile( This->hFile ) )
00197     return E_FAIL;
00198 
00199   return S_OK;
00200 }
00201 
00202 /**************************************************************************
00203  * IStream_fnCopyTo
00204  */
00205 static HRESULT WINAPI IStream_fnCopyTo(IStream *iface, IStream* pstm, ULARGE_INTEGER cb,
00206                                        ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten)
00207 {
00208   ISHFileStream *This = (ISHFileStream *)iface;
00209   char copyBuff[1024];
00210   ULONGLONG ulSize;
00211   HRESULT hRet = S_OK;
00212 
00213   TRACE("(%p,%p,%d,%p,%p)\n", This, pstm, cb.u.LowPart, pcbRead, pcbWritten);
00214 
00215   if (pcbRead)
00216     pcbRead->QuadPart = 0;
00217   if (pcbWritten)
00218     pcbWritten->QuadPart = 0;
00219 
00220   if (!pstm)
00221     return S_OK;
00222 
00223   IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */
00224 
00225   /* Copy data */
00226   ulSize = cb.QuadPart;
00227   while (ulSize)
00228   {
00229     ULONG ulLeft, ulAmt;
00230 
00231     ulLeft = ulSize > sizeof(copyBuff) ? sizeof(copyBuff) : ulSize;
00232 
00233     /* Read */
00234     hRet = IStream_fnRead(iface, copyBuff, ulLeft, &ulAmt);
00235     if (pcbRead)
00236       pcbRead->QuadPart += ulAmt;
00237     if (FAILED(hRet) || ulAmt != ulLeft)
00238       break;
00239 
00240     /* Write */
00241     hRet = IStream_fnWrite(pstm, copyBuff, ulLeft, &ulAmt);
00242     if (pcbWritten)
00243       pcbWritten->QuadPart += ulAmt;
00244     if (FAILED(hRet) || ulAmt != ulLeft)
00245       break;
00246 
00247     ulSize -= ulLeft;
00248   }
00249   return hRet;
00250 }
00251 
00252 /**************************************************************************
00253  * IStream_fnCommit
00254  */
00255 static HRESULT WINAPI IStream_fnCommit(IStream *iface, DWORD grfCommitFlags)
00256 {
00257   ISHFileStream *This = (ISHFileStream *)iface;
00258 
00259   TRACE("(%p,%d)\n", This, grfCommitFlags);
00260   /* Currently unbuffered: This function is not needed */
00261   return S_OK;
00262 }
00263 
00264 /**************************************************************************
00265  * IStream_fnRevert
00266  */
00267 static HRESULT WINAPI IStream_fnRevert(IStream *iface)
00268 {
00269   ISHFileStream *This = (ISHFileStream *)iface;
00270 
00271   TRACE("(%p)\n", This);
00272   return E_NOTIMPL;
00273 }
00274 
00275 /**************************************************************************
00276  * IStream_fnLockUnlockRegion
00277  */
00278 static HRESULT WINAPI IStream_fnLockUnlockRegion(IStream *iface, ULARGE_INTEGER libOffset,
00279                                                  ULARGE_INTEGER cb, DWORD dwLockType)
00280 {
00281   ISHFileStream *This = (ISHFileStream *)iface;
00282   TRACE("(%p,%d,%d,%d)\n", This, libOffset.u.LowPart, cb.u.LowPart, dwLockType);
00283   return E_NOTIMPL;
00284 }
00285 
00286 /*************************************************************************
00287  * IStream_fnStat
00288  */
00289 static HRESULT WINAPI IStream_fnStat(IStream *iface, STATSTG* lpStat,
00290                                      DWORD grfStatFlag)
00291 {
00292   ISHFileStream *This = (ISHFileStream *)iface;
00293   BY_HANDLE_FILE_INFORMATION fi;
00294   HRESULT hRet = S_OK;
00295 
00296   TRACE("(%p,%p,%d)\n", This, lpStat, grfStatFlag);
00297 
00298   if (!grfStatFlag)
00299     hRet = STG_E_INVALIDPOINTER;
00300   else
00301   {
00302     memset(&fi, 0, sizeof(fi));
00303     GetFileInformationByHandle(This->hFile, &fi);
00304 
00305     if (grfStatFlag & STATFLAG_NONAME)
00306       lpStat->pwcsName = NULL;
00307     else
00308       lpStat->pwcsName = StrDupW(This->lpszPath);
00309     lpStat->type = This->type;
00310     lpStat->cbSize.u.LowPart = fi.nFileSizeLow;
00311     lpStat->cbSize.u.HighPart = fi.nFileSizeHigh;
00312     lpStat->mtime = fi.ftLastWriteTime;
00313     lpStat->ctime = fi.ftCreationTime;
00314     lpStat->atime = fi.ftLastAccessTime;
00315     lpStat->grfMode = This->dwMode;
00316     lpStat->grfLocksSupported = 0;
00317     memcpy(&lpStat->clsid, &IID_IStream, sizeof(CLSID));
00318     lpStat->grfStateBits = This->grfStateBits;
00319     lpStat->reserved = 0;
00320   }
00321   return hRet;
00322 }
00323 
00324 /*************************************************************************
00325  * IStream_fnClone
00326  */
00327 static HRESULT WINAPI IStream_fnClone(IStream *iface, IStream** ppstm)
00328 {
00329   ISHFileStream *This = (ISHFileStream *)iface;
00330 
00331   TRACE("(%p)\n",This);
00332   if (ppstm)
00333     *ppstm = NULL;
00334   return E_NOTIMPL;
00335 }
00336 
00337 static const IStreamVtbl SHLWAPI_fsVTable =
00338 {
00339   IStream_fnQueryInterface,
00340   IStream_fnAddRef,
00341   IStream_fnRelease,
00342   IStream_fnRead,
00343   IStream_fnWrite,
00344   IStream_fnSeek,
00345   IStream_fnSetSize,
00346   IStream_fnCopyTo,
00347   IStream_fnCommit,
00348   IStream_fnRevert,
00349   IStream_fnLockUnlockRegion,
00350   IStream_fnLockUnlockRegion,
00351   IStream_fnStat,
00352   IStream_fnClone
00353 };
00354 
00355 /**************************************************************************
00356  * IStream_Create
00357  *
00358  * Internal helper: Create and initialise a new file stream object.
00359  */
00360 static IStream *IStream_Create(LPCWSTR lpszPath, HANDLE hFile, DWORD dwMode)
00361 {
00362  ISHFileStream* fileStream;
00363 
00364  fileStream = HeapAlloc(GetProcessHeap(), 0, sizeof(ISHFileStream));
00365 
00366  if (fileStream)
00367  {
00368    fileStream->lpVtbl = &SHLWAPI_fsVTable;
00369    fileStream->ref = 1;
00370    fileStream->hFile = hFile;
00371    fileStream->dwMode = dwMode;
00372    fileStream->lpszPath = StrDupW(lpszPath);
00373    fileStream->type = 0; /* FIXME */
00374    fileStream->grfStateBits = 0; /* FIXME */
00375  }
00376  TRACE ("Returning %p\n", fileStream);
00377  return (IStream *)fileStream;
00378 }
00379 
00380 /*************************************************************************
00381  * SHCreateStreamOnFileEx   [SHLWAPI.@]
00382  *
00383  * Create a stream on a file.
00384  *
00385  * PARAMS
00386  *  lpszPath     [I] Path of file to create stream on
00387  *  dwMode       [I] Mode to create stream in
00388  *  dwAttributes [I] Attributes of the file
00389  *  bCreate      [I] Whether to create the file if it doesn't exist
00390  *  lpTemplate   [I] Reserved, must be NULL
00391  *  lppStream    [O] Destination for created stream
00392  *
00393  * RETURNS
00394  * Success: S_OK. lppStream contains the new stream object
00395  * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code
00396  *
00397  * NOTES
00398  *  This function is available in Unicode only.
00399  */
00400 HRESULT WINAPI SHCreateStreamOnFileEx(LPCWSTR lpszPath, DWORD dwMode,
00401                                       DWORD dwAttributes, BOOL bCreate,
00402                                       IStream *lpTemplate, IStream **lppStream)
00403 {
00404   DWORD dwAccess, dwShare, dwCreate;
00405   HANDLE hFile;
00406 
00407   TRACE("(%s,%d,0x%08X,%d,%p,%p)\n", debugstr_w(lpszPath), dwMode,
00408         dwAttributes, bCreate, lpTemplate, lppStream);
00409 
00410   if (!lpszPath || !lppStream || lpTemplate)
00411     return E_INVALIDARG;
00412 
00413   *lppStream = NULL;
00414 
00415   /* Access */
00416   switch (STGM_ACCESS_MODE(dwMode))
00417   {
00418   case STGM_READWRITE:
00419     dwAccess = GENERIC_READ|GENERIC_WRITE;
00420     break;
00421   case STGM_WRITE:
00422     dwAccess = GENERIC_WRITE;
00423     break;
00424   case STGM_READ:
00425     dwAccess = GENERIC_READ;
00426     break;
00427   default:
00428     return E_INVALIDARG;
00429   }
00430 
00431   /* Sharing */
00432   switch (STGM_SHARE_MODE(dwMode))
00433   {
00434   case 0:
00435     dwShare = FILE_SHARE_READ|FILE_SHARE_WRITE;
00436     break;
00437   case STGM_SHARE_DENY_READ:
00438     dwShare = FILE_SHARE_WRITE;
00439     break;
00440   case STGM_SHARE_DENY_WRITE:
00441     dwShare = FILE_SHARE_READ;
00442     break;
00443   case STGM_SHARE_EXCLUSIVE:
00444     dwShare = 0;
00445     break;
00446   case STGM_SHARE_DENY_NONE:
00447     dwShare = FILE_SHARE_READ|FILE_SHARE_WRITE;
00448     break;
00449   default:
00450     return E_INVALIDARG;
00451   }
00452 
00453   switch(STGM_CREATE_MODE(dwMode))
00454   {
00455   case STGM_FAILIFTHERE:
00456     dwCreate = bCreate ? CREATE_NEW : OPEN_EXISTING;
00457     break;
00458   case STGM_CREATE:
00459     dwCreate = CREATE_ALWAYS;
00460     break;
00461   default:
00462     return E_INVALIDARG;
00463   }
00464 
00465   /* Open HANDLE to file */
00466   hFile = CreateFileW(lpszPath, dwAccess, dwShare, NULL, dwCreate,
00467                       dwAttributes, 0);
00468 
00469   if(hFile == INVALID_HANDLE_VALUE)
00470     return HRESULT_FROM_WIN32(GetLastError());
00471 
00472   *lppStream = IStream_Create(lpszPath, hFile, dwMode);
00473 
00474   if(!*lppStream)
00475   {
00476     CloseHandle(hFile);
00477     return E_OUTOFMEMORY;
00478   }
00479   return S_OK;
00480 }
00481 
00482 /*************************************************************************
00483  * SHCreateStreamOnFileW   [SHLWAPI.@]
00484  *
00485  * See SHCreateStreamOnFileA.
00486  */
00487 HRESULT WINAPI SHCreateStreamOnFileW(LPCWSTR lpszPath, DWORD dwMode,
00488                                    IStream **lppStream)
00489 {
00490   TRACE("(%s,%d,%p)\n", debugstr_w(lpszPath), dwMode, lppStream);
00491 
00492   if (!lpszPath || !lppStream)
00493     return E_INVALIDARG;
00494 
00495   if ((dwMode & (STGM_CONVERT|STGM_DELETEONRELEASE|STGM_TRANSACTED)) != 0)
00496     return E_INVALIDARG;
00497 
00498   return SHCreateStreamOnFileEx(lpszPath, dwMode, 0, FALSE, NULL, lppStream);
00499 }
00500 
00501 /*************************************************************************
00502  * SHCreateStreamOnFileA   [SHLWAPI.@]
00503  *
00504  * Create a stream on a file.
00505  *
00506  * PARAMS
00507  *  lpszPath  [I] Path of file to create stream on
00508  *  dwMode    [I] Mode to create stream in
00509  *  lppStream [O] Destination for created IStream object
00510  *
00511  * RETURNS
00512  * Success: S_OK. lppStream contains the new IStream object
00513  * Failure: E_INVALIDARG if any parameter is invalid, or an HRESULT error code
00514  */
00515 HRESULT WINAPI SHCreateStreamOnFileA(LPCSTR lpszPath, DWORD dwMode,
00516                                      IStream **lppStream)
00517 {
00518   WCHAR szPath[MAX_PATH];
00519 
00520   TRACE("(%s,%d,%p)\n", debugstr_a(lpszPath), dwMode, lppStream);
00521 
00522   if (!lpszPath)
00523     return HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND);
00524 
00525   MultiByteToWideChar(0, 0, lpszPath, -1, szPath, MAX_PATH);
00526   return SHCreateStreamOnFileW(szPath, dwMode, lppStream);
00527 }
00528 
00529 /*************************************************************************
00530  * @       [SHLWAPI.184]
00531  *
00532  * Call IStream_Read() on a stream.
00533  *
00534  * PARAMS
00535  *  lpStream [I] IStream object
00536  *  lpvDest  [O] Destination for data read
00537  *  ulSize   [I] Size of data to read
00538  *
00539  * RETURNS
00540  *  Success: S_OK. ulSize bytes have been read from the stream into lpvDest.
00541  *  Failure: An HRESULT error code, or E_FAIL if the read succeeded but the
00542  *           number of bytes read does not match.
00543  */
00544 HRESULT WINAPI SHIStream_Read(IStream *lpStream, LPVOID lpvDest, ULONG ulSize)
00545 {
00546   ULONG ulRead;
00547   HRESULT hRet;
00548 
00549   TRACE("(%p,%p,%d)\n", lpStream, lpvDest, ulSize);
00550 
00551   hRet = IStream_Read(lpStream, lpvDest, ulSize, &ulRead);
00552 
00553   if (SUCCEEDED(hRet) && ulRead != ulSize)
00554     hRet = E_FAIL;
00555   return hRet;
00556 }
00557 
00558 /*************************************************************************
00559  * @       [SHLWAPI.166]
00560  *
00561  * Determine if a stream has 0 length.
00562  *
00563  * PARAMS
00564  *  lpStream [I] IStream object
00565  *
00566  * RETURNS
00567  *  TRUE:  If the stream has 0 length
00568  *  FALSE: Otherwise.
00569  */
00570 BOOL WINAPI SHIsEmptyStream(IStream *lpStream)
00571 {
00572   STATSTG statstg;
00573   BOOL bRet = TRUE;
00574 
00575   TRACE("(%p)\n", lpStream);
00576 
00577   memset(&statstg, 0, sizeof(statstg));
00578 
00579   if(SUCCEEDED(IStream_Stat(lpStream, &statstg, 1)))
00580   {
00581     if(statstg.cbSize.QuadPart)
00582       bRet = FALSE; /* Non-Zero */
00583   }
00584   else
00585   {
00586     DWORD dwDummy;
00587 
00588     /* Try to read from the stream */
00589     if(SUCCEEDED(SHIStream_Read(lpStream, &dwDummy, sizeof(dwDummy))))
00590     {
00591       LARGE_INTEGER zero;
00592       zero.QuadPart = 0;
00593 
00594       IStream_Seek(lpStream, zero, 0, NULL);
00595       bRet = FALSE; /* Non-Zero */
00596     }
00597   }
00598   return bRet;
00599 }
00600 
00601 /*************************************************************************
00602  * @       [SHLWAPI.212]
00603  *
00604  * Call IStream_Write() on a stream.
00605  *
00606  * PARAMS
00607  *  lpStream [I] IStream object
00608  *  lpvSrc   [I] Source for data to write
00609  *  ulSize   [I] Size of data
00610  *
00611  * RETURNS
00612  *  Success: S_OK. ulSize bytes have been written to the stream from lpvSrc.
00613  *  Failure: An HRESULT error code, or E_FAIL if the write succeeded but the
00614  *           number of bytes written does not match.
00615  */
00616 HRESULT WINAPI SHIStream_Write(IStream *lpStream, LPCVOID lpvSrc, ULONG ulSize)
00617 {
00618   ULONG ulWritten;
00619   HRESULT hRet;
00620 
00621   TRACE("(%p,%p,%d)\n", lpStream, lpvSrc, ulSize);
00622 
00623   hRet = IStream_Write(lpStream, lpvSrc, ulSize, &ulWritten);
00624 
00625   if (SUCCEEDED(hRet) && ulWritten != ulSize)
00626     hRet = E_FAIL;
00627 
00628   return hRet;
00629 }
00630 
00631 /*************************************************************************
00632  * @       [SHLWAPI.213]
00633  *
00634  * Seek to the start of a stream.
00635  *
00636  * PARAMS
00637  *  lpStream [I] IStream object
00638  *
00639  * RETURNS
00640  *  Success: S_OK. The current position within the stream is updated
00641  *  Failure: An HRESULT error code.
00642  */
00643 HRESULT WINAPI IStream_Reset(IStream *lpStream)
00644 {
00645   LARGE_INTEGER zero;
00646   TRACE("(%p)\n", lpStream);
00647   zero.QuadPart = 0;
00648   return IStream_Seek(lpStream, zero, 0, NULL);
00649 }
00650 
00651 /*************************************************************************
00652  * @       [SHLWAPI.214]
00653  *
00654  * Get the size of a stream.
00655  *
00656  * PARAMS
00657  *  lpStream [I] IStream object
00658  *  lpulSize [O] Destination for size
00659  *
00660  * RETURNS
00661  *  Success: S_OK. lpulSize contains the size of the stream.
00662  *  Failure: An HRESULT error code.
00663  */
00664 HRESULT WINAPI IStream_Size(IStream *lpStream, ULARGE_INTEGER* lpulSize)
00665 {
00666   STATSTG statstg;
00667   HRESULT hRet;
00668 
00669   TRACE("(%p,%p)\n", lpStream, lpulSize);
00670 
00671   memset(&statstg, 0, sizeof(statstg));
00672 
00673   hRet = IStream_Stat(lpStream, &statstg, 1);
00674 
00675   if (SUCCEEDED(hRet) && lpulSize)
00676     *lpulSize = statstg.cbSize;
00677   return hRet;
00678 }

Generated on Fri May 25 2012 04:24:38 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.