2025-04-27 07:49:33 -04:00

849 lines
32 KiB
C++

#include <objbase.h>
#include <assert.h>
#include "shlwapi.h"
#include "shellstg.h"
#include "mischlpr.h"
#include "strutil.h"
#include "resource.h"
#include <stdio.h>
#define DEBUG
//#define TRACE(a) (fprintf(stderr,"%d %s\n",GetTickCount(),a))
#define TRACE(a)
///////////////////////////////////////
CShellStorageImpl::CShellStorageImpl (): _plistPIDL(NULL), _pwszTitleExamining(NULL), _pwszTitleConnecting(NULL),
_pwszTitleSending(NULL), _pwszTitleTo(NULL), _ppd(NULL)
{
TRACE("CShellStorage::CShellStorage");
}
///////////////////////////////////////
CShellStorageImpl::~CShellStorageImpl ()
{
TRACE("CShellStorage::~CShellStorage");
}
///////////////////////////////////////
STDMETHODIMP CShellStorageImpl::Init(HWND hwnd, LPWSTR pwszServer, BOOL fShowProgressDialog)
{
HRESULT hr = S_OK;
TRACE("CShellStorage::Init");
_hwnd = hwnd;
_hinstShellStg = GetModuleHandle(L"shellstg");
if (!_hinstShellStg)
{
hr = E_FAIL;
}
else
{
WCHAR wszLoad[MAX_PATH];
_pwszTitleExamining = NULL;
_pwszTitleConnecting = NULL;
_pwszTitleSending = NULL;
_pwszTitleTo = NULL;
if (LoadStringW(_hinstShellStg, IDS_EXAMINING, wszLoad, sizeof(wszLoad)))
_pwszTitleExamining = DuplicateStringW(wszLoad);
if (LoadStringW(_hinstShellStg, IDS_CONNECTING, wszLoad, sizeof(wszLoad)))
_pwszTitleConnecting = DuplicateStringW(wszLoad);
if (LoadStringW(_hinstShellStg, IDS_UPLOADING, wszLoad, sizeof(wszLoad)))
_pwszTitleSending = DuplicateStringW(wszLoad);
if (LoadStringW(_hinstShellStg, IDS_SERVERTO, wszLoad, sizeof(wszLoad)))
_pwszTitleTo = DuplicateStringW(wszLoad);
if (LoadStringW(_hinstShellStg, IDS_SERVERNEWFOLDER, wszLoad, sizeof(wszLoad)))
_pwszTitleNewFolder = DuplicateStringW(wszLoad);
_plistPIDL = new CGenericList();
_pwszServer = DuplicateStringW(pwszServer);
if (!_pwszTitleExamining || !_pwszTitleConnecting ||
!_pwszTitleSending || !_pwszTitleTo ||
!_pwszTitleNewFolder ||
!_plistPIDL || !_pwszServer)
{
hr = E_OUTOFMEMORY;
}
else
{
if (fShowProgressDialog)
{
// set up the progress dialog
hr = CoCreateInstance(CLSID_ProgressDialog, NULL, CLSCTX_INPROC_SERVER, IID_IProgressDialog, (LPVOID*)&_ppd);
// BUGBUG: catch all these return values
hr = _ppd->SetAnimation(_hinstShellStg, IDA_FTPUPLOAD);
if (SUCCEEDED(hr))
{
_ppd->SetTitle(_pwszTitleExamining);
if (SUCCEEDED(hr))
{
hr = _ppd->StartProgressDialog(NULL, NULL, PROGDLG_AUTOTIME, NULL);if (SUCCEEDED(hr))
{
}
}
}
}
}
}
return hr;
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::AddIDListReference(LPVOID rgpidl[],
DWORD cpidl,
BOOL fRecursive)
{
HRESULT hr = S_OK;
TRACE("CShellStorage::AddIDListReference");
if (!rgpidl || cpidl <= 0)
hr = E_INVALIDARG;
else
{
for (DWORD i = 0; i < cpidl; i++)
{
if (!rgpidl[i])
{
hr = E_INVALIDARG;
break;
}
else
{
// add the pidl
DWORD cb = ((LPSHITEMID)rgpidl[i])->cb;
LPITEMIDLIST pidl = ILClone((LPITEMIDLIST)rgpidl[i]);
if (!pidl)
{
hr = E_OUTOFMEMORY;
}
else
{
WCHAR wszTag[2];
wszTag[0] = fRecursive ? 'R' : 'S';
wszTag[1] = '\0';
hr = _plistPIDL->Add(wszTag, pidl, cb);
}
}
}
}
return hr;
}
///////////////////////////////////
STDMETHODIMP CShellStorageImpl::CreateStream(const WCHAR * UNREF_PARAM(pwcsName), //Points to the name of the new stream
DWORD UNREF_PARAM(grfMode), //Access mode for the new stream
DWORD UNREF_PARAM(reserved1), //Reserved; must be zero
DWORD UNREF_PARAM(reserved2), //Reserved; must be zero
IStream ** UNREF_PARAM(ppstm)) //Points to new stream object
{
return E_NOTIMPL; // not the first pass
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::OpenStream(const WCHAR * UNREF_PARAM(pwcsName), //Points to name of stream to open
void * UNREF_PARAM(reserved1), //Reserved; must be NULL
DWORD UNREF_PARAM(grfMode), //Access mode for the new stream
DWORD UNREF_PARAM(reserved2), //Reserved; must be zero
IStream ** UNREF_PARAM(ppstm)) //Address of output variable
// that receives the IStream interface pointer
{
return E_NOTIMPL; // not the first pass
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::CreateStorage(const WCHAR * UNREF_PARAM(pwcsName), //Points to the name of the new storage object
DWORD UNREF_PARAM(grfMode), //Access mode for the new storage object
DWORD UNREF_PARAM(reserved1), //Reserved; must be zero
DWORD UNREF_PARAM(reserved2), //Reserved; must be zero
IStorage ** UNREF_PARAM(ppstg)) //Points to new storage object
{
return E_NOTIMPL; // not the first pass
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::OpenStorage(const WCHAR * UNREF_PARAM(pwcsName), //Points to the name of the
// storage object to open
IStorage * UNREF_PARAM(pstgPriority), //Must be NULL.
DWORD UNREF_PARAM(grfMode), //Access mode for the new storage object
SNB UNREF_PARAM(snbExclude), //Must be NULL.
DWORD UNREF_PARAM(reserved), //Reserved; must be zero
IStorage ** UNREF_PARAM(ppstg)) //Points to opened storage object
{
return E_NOTIMPL; // not the first pass
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::_IncrementULargeInteger(ULARGE_INTEGER* a,
ULARGE_INTEGER* b)
{
a->HighPart+=b->HighPart;
DWORD dwNewLow = a->LowPart + b->LowPart;
if ((dwNewLow < a->LowPart) ||( dwNewLow < b->LowPart))
{
a->HighPart+=1; // rollover in low
}
a->LowPart = dwNewLow;
return S_OK;
}
STDMETHODIMP CShellStorageImpl::_IncrementByteCount(LPITEMIDLIST pidl,
ULARGE_INTEGER* pcbTotal)
{
HRESULT hr = S_OK;
LPCITEMIDLIST pidlRelative;
IShellFolder* pshfParent = NULL;
hr = SHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&pshfParent, &pidlRelative);
if (SUCCEEDED(hr))
{
WIN32_FIND_DATA wfdData;
hr = SHGetDataFromIDList(pshfParent, pidlRelative, SHGDFIL_FINDDATA, &wfdData, sizeof(wfdData));
if (SUCCEEDED(hr))
{
ULARGE_INTEGER ulwfdData;
ulwfdData.HighPart = wfdData.nFileSizeHigh;
ulwfdData.LowPart = wfdData.nFileSizeLow;
hr = this->_IncrementULargeInteger(pcbTotal, &ulwfdData);
}
}
return hr;
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::_ExaminePIDLListRecursive(LPITEMIDLIST pidl,
IShellFolder* pshfDesk,
UINT* pcbElts,
ULARGE_INTEGER* pcbTotal)
{
HRESULT hr = S_OK;
SHFILEINFO sfi;
TRACE("CShellStorage::_FlattenPIDLListRecursive");
if (!SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_ATTRIBUTES | SHGFI_DISPLAYNAME))
{
hr = E_FAIL;
}
else
{
*pcbElts = *pcbElts + 1;
hr = this->_IncrementByteCount(pidl, pcbTotal);
if (SUCCEEDED(hr))
{
if (_ppd)
{
WCHAR wszTempLine1[MAX_PATH];
WCHAR wszTempLine2[MAX_PATH];
swprintf(wszTempLine1, L"Found %d files", *pcbElts);
if (pcbTotal->HighPart > 0)
{
// BUGBUG: need to format lowpart correctly so it'll have the right width
swprintf(wszTempLine2, L"Total %d%d bytes", pcbTotal->HighPart, pcbTotal->LowPart);
}
else
{
swprintf(wszTempLine2, L"Total %d bytes", pcbTotal->LowPart);
}
hr = this->_UpdateProgressDialog(NULL, NULL, NULL, wszTempLine1, wszTempLine2);
}
if (SUCCEEDED(hr) && hr != S_FALSE)
{
if ((sfi.dwAttributes & SFGAO_FILESYSTEM) && (sfi.dwAttributes & SFGAO_FOLDER))
{
// if this is a folder, we need to enumerate its contents and add those too
IShellFolder* pshf = NULL;
LPENUMIDLIST penumIDList = NULL;
LPITEMIDLIST pidlRelative = NULL;
LPITEMIDLIST pidlAbsolute = NULL;
hr = pshfDesk->BindToObject(pidl, NULL, IID_IShellFolder, (LPVOID*)&pshf);
if (SUCCEEDED(hr))
{
hr = pshf->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &penumIDList);
if (SUCCEEDED(hr))
{
BOOL fDone = FALSE;
while (!fDone)
{
DWORD cFetched;
hr = penumIDList->Next(1, &pidlRelative, &cFetched);
if (SUCCEEDED(hr))
{
if (hr == S_FALSE || cFetched != 1)
{
hr = S_OK;
fDone = TRUE;
}
else
{
pidlAbsolute = ILCombine((LPCITEMIDLIST)pidl, pidlRelative);
if (!pidlAbsolute)
{
hr = E_FAIL;
}
else
{
hr = this->_ExaminePIDLListRecursive(pidlAbsolute,
pshfDesk,
pcbElts,
pcbTotal);
}
}
}
if (FAILED(hr) || hr == S_FALSE)
{
fDone=TRUE;
}
}
}
pshf->Release();
}
}
}
}
}
return hr;
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::_ExaminePIDLList(UINT* pcElts,
ULARGE_INTEGER* pcbTotal)
{
HRESULT hr = S_OK;
UINT cEltsTopLevel;
LPWSTR pwszTag;
LPITEMIDLIST pidl;
UINT cbPIDL;
IShellFolder* pshfDesk = NULL;
hr = _plistPIDL->Size(&cEltsTopLevel);
if (SUCCEEDED(hr))
{
for (UINT i = 0; i < cEltsTopLevel; i++)
{
hr = _plistPIDL->GetTagByDex (i, &pwszTag);
if (SUCCEEDED(hr))
{
hr = _plistPIDL->FindByDex(i, (LPVOID*)&pidl, &cbPIDL);
if (SUCCEEDED(hr))
{
if (*pwszTag == 'R')
{
// add to the new list recursively
if (!pshfDesk)
{
hr = SHGetDesktopFolder(&pshfDesk);
}
if (SUCCEEDED(hr))
{
hr = _ExaminePIDLListRecursive(pidl, pshfDesk, pcElts, pcbTotal);
}
}
else
{
if (SUCCEEDED(hr))
{
// increment count of elements to copy
*pcElts = *pcElts + 1;
// if a file, get size and add to pcbTotal
hr = this->_IncrementByteCount(pidl, pcbTotal);
WCHAR wszTempLine1[MAX_PATH];
WCHAR wszTempLine2[MAX_PATH];
swprintf(wszTempLine1, L"Found %d files", *pcElts);
swprintf(wszTempLine2, L"Total %d%d bytes", pcbTotal->HighPart, pcbTotal->LowPart);
hr = this->_UpdateProgressDialog(NULL, NULL, NULL, wszTempLine1, wszTempLine2);
}
}
}
}
if (FAILED(hr) || hr == S_FALSE)
{
break;
}
}
}
return hr;
}
/////////////////////////////////////
HRESULT CShellStorageImpl::_UpdateProgressDialog(ULARGE_INTEGER* pcbNewComplete,
ULARGE_INTEGER* pcbComplete,
ULARGE_INTEGER* pcbTotal,
LPWSTR pwszLine1,
LPWSTR pwszLine2)
{
HRESULT hr = S_OK;
static BOOL fSending = FALSE;
assert(_ppd); // should not call if we aren't using the dialog
// first, check if user has cancelled
if (_ppd->HasUserCancelled())
{
hr = S_FALSE;
}
else
{
if (SUCCEEDED(hr))
{
hr = _ppd->SetLine(1, pwszLine1, TRUE, NULL);
if (SUCCEEDED(hr))
{
hr = _ppd->SetLine(2, pwszLine2, TRUE, NULL);
if (pcbNewComplete && pcbComplete && pcbTotal)
{
if (SUCCEEDED(hr))
{
// -- update title if appropriate, "Connecting" --> "Sending"
if (!fSending)
{
hr = _ppd->SetTitle(_pwszTitleSending);
fSending = TRUE;
}
if (SUCCEEDED(hr))
{
hr = this->_IncrementULargeInteger(pcbComplete, pcbNewComplete);
if (SUCCEEDED(hr))
{
hr = _ppd->SetProgress64(pcbComplete->QuadPart, pcbTotal->QuadPart);
}
}
}
}
}
}
}
return hr;
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::_CopyPidlToStream(LPITEMIDLIST pidl,
IStream* pstream,
ULARGE_INTEGER* pcbComplete,
ULARGE_INTEGER* pcbTotal,
UINT cchRootPath)
{
HRESULT hr = S_OK;
WCHAR wszPath[MAX_PATH];
WCHAR wszLine2[MAX_PATH];
BOOL fLine2Init = FALSE;
DWORD cbRead, cbWritten;
TRACE("CShellStorage::_CopyPidlToStream");
if (!SHGetPathFromIDList(pidl, wszPath))
{
hr = E_FAIL;
}
else
{
HANDLE hFile = CreateFile(wszPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
hr = E_FAIL;
}
else
{
do
{
BYTE lpv[4096];
if (ReadFile(hFile, lpv, 4096, &cbRead, NULL))
{
if (cbRead > 0)
{
hr = pstream->Write(lpv, cbRead, &cbWritten);
if (SUCCEEDED(hr))
{
if (cbRead != cbWritten)
{
hr = E_FAIL;
}
else
{
if (_ppd)
{
// update progress dialog
if (!fLine2Init)
{
lstrcpy(wszLine2, _pwszTitleTo);
lstrcat(wszLine2, wszPath + cchRootPath);
fLine2Init = TRUE;
}
ULARGE_INTEGER ulcbWritten;
ulcbWritten.HighPart = 0;
ulcbWritten.LowPart = cbWritten;
hr = this->_UpdateProgressDialog(&ulcbWritten, pcbComplete, pcbTotal, wszPath, wszLine2);
}
}
}
}
}
}
while (cbRead > 0 && SUCCEEDED(hr) && hr != S_FALSE);
CloseHandle(hFile);
}
}
return hr;
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::_CopyPidlContentsToStorage(LPITEMIDLIST pidl,
IStorage* pstgDest,
ULARGE_INTEGER* pcbComplete,
ULARGE_INTEGER* pcbTotal,
BOOL fRecursive,
UINT cchRootPath)
{
HRESULT hr = S_OK;
TRACE("CShellStorage::_FlattenPIDLListRecursive");
IShellFolder* pshfDesk = NULL; // BUGBUG, don't get this every time
IShellFolder* pshf = NULL;
LPENUMIDLIST penumIDList = NULL;
LPITEMIDLIST pidlRelative = NULL;
LPITEMIDLIST pidlAbsolute = NULL;
SHGetDesktopFolder(&pshfDesk);
hr = pshfDesk->BindToObject(pidl, NULL, IID_IShellFolder, (LPVOID*)&pshf);
if (SUCCEEDED(hr))
{
hr = pshf->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &penumIDList);
if (SUCCEEDED(hr))
{
BOOL fDone = FALSE;
while (!fDone)
{
DWORD cFetched;
hr = penumIDList->Next(1, &pidlRelative, &cFetched);
if (SUCCEEDED(hr))
{
if (hr == S_FALSE || cFetched != 1)
{
hr = S_OK;
fDone = TRUE;
}
else
{
pidlAbsolute = ILCombine((LPCITEMIDLIST)pidl, pidlRelative);
if (!pidlAbsolute)
{
hr = E_FAIL;
}
else
{
hr = this->_CopyPidlToStorage(pidlAbsolute,
pstgDest,
pcbComplete,
pcbTotal,
fRecursive,
cchRootPath);
}
}
}
if (FAILED(hr) || hr == S_FALSE)
{
fDone=TRUE;
}
}
}
pshf->Release();
}
pshfDesk->Release();
return hr;
}
STDMETHODIMP CShellStorageImpl::_CopyPidlToStorage(LPITEMIDLIST pidl,
IStorage* pstgDest,
ULARGE_INTEGER* pcbComplete,
ULARGE_INTEGER* pcbTotal,
BOOL fRecursive,
UINT cchRootPath)
{
HRESULT hr = S_OK;
SHFILEINFO sfi;
IStorage* newStorage = NULL;
IStream* newStream = NULL;
TRACE("CShellStorage::_CopyPidlToStorage");
if (!SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_ATTRIBUTES | SHGFI_DISPLAYNAME))
{
hr = E_FAIL;
}
else
{
if (sfi.dwAttributes & SFGAO_FILESYSTEM) // we only support filesystem items for now
{
if (sfi.dwAttributes & SFGAO_FOLDER)
{
// folder
hr = pstgDest->CreateStorage(sfi.szDisplayName, 0, 0, 0, &newStorage);
if (FAILED(hr))
{ // if we can't create, try to open an existing storage there
hr = pstgDest->OpenStorage(sfi.szDisplayName, NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, 0, &newStorage);
}
if (SUCCEEDED(hr))
{
WCHAR wszTitle[MAX_PATH];
WCHAR wszPath[MAX_PATH];
if (!SHGetPathFromIDList(pidl, wszPath))
{
hr = E_FAIL;
}
else
{
lstrcpy(wszTitle, _pwszTitleNewFolder);
lstrcat(wszTitle, wszPath + cchRootPath);
hr = this->_UpdateProgressDialog(NULL, NULL, NULL, wszTitle, L"");
if (SUCCEEDED(hr))
{
if (fRecursive)
{
hr = this->_CopyPidlContentsToStorage(pidl, newStorage, pcbComplete, pcbTotal, TRUE, cchRootPath);
}
}
newStorage->Release();
}
}
}
else
{
// file
hr = pstgDest->CreateStream(sfi.szDisplayName, STGM_TRANSACTED, 0, 0, &newStream);
if (SUCCEEDED(hr))
{
hr = _CopyPidlToStream(pidl, newStream, pcbComplete, pcbTotal, cchRootPath);
if (SUCCEEDED(hr) && hr != S_FALSE)
{
hr = newStream->Commit(0);
}
newStream->Release();
}
}
}
}
return hr;
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::CopyTo(DWORD UNREF_PARAM(ciidExclude), //Number of elements in rgiidExclude
IID const * UNREF_PARAM(rgiidExclude), //Array of interface identifiers (IIDs)
SNB UNREF_PARAM(snbExclude), //Points to a block of stream
// names in the storage object
IStorage* pstgDest) //Points to destination storage object
{
// here's where all the magic happens
// ISSUE: we don't support exclusion at the moment
HRESULT hr;
UINT cElts = 0;
ULARGE_INTEGER cbTotal = {0}; // total size in bytes of all files to be transmitted
ULARGE_INTEGER cbComplete = {0};
TRACE("CShellStorage::CopyTo");
// examine list of pidls (maybe recursive), and find total size and number of elements
hr = this->_ExaminePIDLList(&cElts, &cbTotal);
if (_ppd && hr == S_FALSE)
{
// we just cancelled, but that doesn't mean failure
_ppd->StopProgressDialog();
hr = S_OK;
}
else if (SUCCEEDED(hr))
{
if (_ppd)
{
_ppd->SetTitle(_pwszTitleConnecting);
this->_UpdateProgressDialog(NULL, NULL, NULL, L"", L"");
}
UINT cEltsTopLevel;
_plistPIDL->Size(&cEltsTopLevel); // BUGBUG: check ret val
if (SUCCEEDED(hr))
{
for (UINT i = 0; i < cEltsTopLevel; i++)
{
LPITEMIDLIST pidl;
UINT cbPIDL;
hr = _plistPIDL->FindByDex(i, (LPVOID*)&pidl, &cbPIDL);
if (SUCCEEDED(hr))
{
LPWSTR pwszTag = NULL;
hr = _plistPIDL->GetTagByDex (i, &pwszTag);
if (SUCCEEDED(hr))
{
WCHAR wszPath[MAX_PATH];
if (!SHGetPathFromIDList(pidl, wszPath))
{
hr = E_FAIL;
}
else
{
SHFILEINFO sfi;
if (!SHGetFileInfo((LPCTSTR)pidl, 0, &sfi, sizeof(sfi),
SHGFI_PIDL | SHGFI_DISPLAYNAME))
{
hr = E_FAIL;
}
else
{
UINT cchRootPath = lstrlen(wszPath) - lstrlen(sfi.szDisplayName);
if (*pwszTag == 'R')
hr = this->_CopyPidlToStorage(pidl, pstgDest, &cbComplete, &cbTotal, TRUE, cchRootPath);
else
hr = this->_CopyPidlToStorage(pidl, pstgDest, &cbComplete, &cbTotal, FALSE, cchRootPath);
}
}
}
}
if (FAILED(hr))
{
break;
}
}
if (_ppd)
{
hr = _ppd->StopProgressDialog();
}
}
}
return hr;
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::MoveElementTo(const WCHAR * UNREF_PARAM(pwcsName), //Name of the element to be moved
IStorage * UNREF_PARAM(pstgDest), //Points to destination storage object
const WCHAR* UNREF_PARAM(pwcsNewName), //Points to new name of element in destination
DWORD UNREF_PARAM(grfFlags)) //Specifies a copy or a move
{
return E_NOTIMPL; // not the first pass
}
/////////////////////////////////////
// IStorage::EnumElements
STDMETHODIMP CShellStorageImpl::EnumElements(DWORD UNREF_PARAM(reserved1), //Reserved; must be zero
void * UNREF_PARAM(reserved2), //Reserved; must be NULL
DWORD UNREF_PARAM(reserved3), //Reserved; must be zero
IEnumSTATSTG ** UNREF_PARAM(ppenum)) //Address of output variable that
// receives the IEnumSTATSTG interface pointer
{
return E_NOTIMPL; // not the first pass
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::DestroyElement(const WCHAR* UNREF_PARAM(pwcsName)) //Points to the name of the element to be removed
{
return E_NOTIMPL; // not the first pass
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::RenameElement(const WCHAR * UNREF_PARAM(pwcsOldName), //Points to the name of the
// element to be changed
const WCHAR * UNREF_PARAM(pwcsNewName)) //Points to the new name for
// the specified element
{
return E_NOTIMPL; // not the first pass
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::SetStateBits(DWORD UNREF_PARAM(grfStateBits), //Specifies new values of bits
DWORD UNREF_PARAM(grfMask)) //Specifies mask that indicates which
// bits are significant
{
return E_NOTIMPL; // not the first pass
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CShellStorageImpl::Commit(DWORD UNREF_PARAM(grfCommitFlags)) //Specifies how changes are to be committed
{
return E_NOTIMPL; // first pass, we do everything synchronously to the server
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::Revert(void)
{
return E_NOTIMPL; // first pass, we do everything synchronously to the server
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::SetElementTimes(const WCHAR * UNREF_PARAM(pwcsName), //Points to name of element to be changed
FILETIME const * UNREF_PARAM(pctime), //New creation time for element, or NULL
FILETIME const * UNREF_PARAM(patime), //New access time for element, or NULL
FILETIME const * UNREF_PARAM(pmtime)) //New modification time for element, or NULL
{
return E_NOTIMPL; // not the first time around
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::SetClass(REFCLSID UNREF_PARAM(clsid)) //Class identifier to be assigned to the storage object
{
return E_NOTIMPL; // not the first pass
}
/////////////////////////////////////
STDMETHODIMP CShellStorageImpl::Stat(STATSTG* UNREF_PARAM(pstatstg), //Location for STATSTG structure
DWORD UNREF_PARAM(grfStatFlag)) //Values taken from the STATFLAG enumeration
{
return E_NOTIMPL; // not the first pass
}