📄 istream.c
字号:
{
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 + -