Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

332 lines
8.9 KiB

#include "precomp.hxx"
#pragma hdrstop
#include <winnlsp.h> // NORM_STOP_ON_NULL
#include "resource.h"
#include "timewarp.h"
#include "util.h"
DWORD FormatString(LPWSTR *ppszResult, HINSTANCE hInstance, LPCWSTR pszFormat, ...)
{
DWORD dwResult;
va_list args;
LPWSTR pszFormatAlloc = NULL;
if (IS_INTRESOURCE(pszFormat))
{
if (LoadStringAlloc(&pszFormatAlloc, hInstance, PtrToUlong(pszFormat)))
{
pszFormat = pszFormatAlloc;
}
else
{
return 0;
}
}
va_start(args, pszFormat);
dwResult = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
pszFormat,
0,
0,
(LPWSTR)ppszResult,
1,
&args);
va_end(args);
LocalFree(pszFormatAlloc);
return dwResult;
}
HRESULT FormatFriendlyDateName(LPWSTR *ppszResult, LPCWSTR pszName, const FILETIME UNALIGNED *pft, DWORD dwDateFlags)
{
WCHAR szDate[MAX_PATH];
SHFormatDateTime(pft, &dwDateFlags, szDate, ARRAYSIZE(szDate));
if (!FormatString(ppszResult, g_hInstance, MAKEINTRESOURCE(IDS_FOLDER_TITLE_FORMAT), pszName, szDate))
{
DWORD dwErr = GetLastError();
return HRESULT_FROM_WIN32(dwErr);
}
return S_OK;
}
void EliminateGMTPathSegment(LPWSTR pszPath)
{
LPWSTR pszGMT = wcsstr(pszPath, SNAPSHOT_MARKER);
if (pszGMT)
{
ASSERT(pszGMT >= pszPath && pszGMT < (pszPath + lstrlenW(pszPath)));
// It's tempting to just say "pszGMT + SNAPSHOT_NAME_LENGTH" here, but
// we might miss an intervening '\0' on a malformed path.
LPWSTR pszSeparator = wcschr(pszGMT, L'\\');
if (pszSeparator)
{
ASSERT(pszSeparator == pszGMT + SNAPSHOT_NAME_LENGTH);
ASSERT(pszSeparator < (pszGMT + lstrlenW(pszGMT)));
pszSeparator++; // skip '\\'
MoveMemory(pszGMT, pszSeparator, (lstrlenW(pszSeparator)+1)*sizeof(WCHAR));
}
else
{
// Truncate here
*pszGMT = L'\0';
// Remove the previous separator if we can
PathRemoveBackslashW(pszPath);
}
}
}
void EliminatePathPrefix(LPWSTR pszPath)
{
// Note that sometimes the "\\?\" is not at the beginning of the
// path. See CTimeWarpProp::_OnView in twprop.cpp.
LPWSTR pszPrefix = wcsstr(pszPath, L"\\\\?\\");
if (pszPrefix)
{
LPWSTR pszDest;
LPWSTR pszSrc;
ASSERT(pszPrefix >= pszPath && pszPrefix < (pszPath + lstrlenW(pszPath)));
if (CSTR_EQUAL == CompareStringW(LOCALE_SYSTEM_DEFAULT,
SORT_STRINGSORT | NORM_IGNORECASE | NORM_STOP_ON_NULL,
pszPrefix+4, 4,
L"UNC\\", 4))
{
// UNC case: preserve the 2 leading backslashes
pszDest = pszPrefix + 2;
pszSrc = pszPrefix + 8;
}
else
{
pszDest = pszPrefix;
pszSrc = pszPrefix + 4;
}
ASSERT(pszDest >= pszPath && pszSrc > pszDest && pszSrc <= (pszPath + lstrlenW(pszPath)));
MoveMemory(pszDest, pszSrc, (lstrlenW(pszSrc)+1)*sizeof(WCHAR));
}
}
HRESULT GetFSIDListFromTimeWarpPath(PIDLIST_ABSOLUTE *ppidlTarget, LPCWSTR pszPath, DWORD dwFileAttributes)
{
HRESULT hr;
LPWSTR pszDup;
hr = SHStrDup(pszPath, &pszDup);
if (SUCCEEDED(hr))
{
// Note that SHSimpleIDListFromPath (which is exported from shell32)
// is not good enough here. It always uses 0 for attributes, but
// we usually need FILE_ATTRIBUTE_DIRECTORY here.
EliminateGMTPathSegment(pszDup);
hr = SimpleIDListFromAttributes(pszDup, dwFileAttributes, ppidlTarget);
LocalFree(pszDup);
}
return hr;
}
class CFileSysBindData : public IFileSystemBindData
{
public:
CFileSysBindData();
// *** IUnknown methods ***
STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// IFileSystemBindData
STDMETHODIMP SetFindData(const WIN32_FIND_DATAW *pfd);
STDMETHODIMP GetFindData(WIN32_FIND_DATAW *pfd);
private:
~CFileSysBindData();
LONG _cRef;
WIN32_FIND_DATAW _fd;
};
CFileSysBindData::CFileSysBindData() : _cRef(1)
{
ZeroMemory(&_fd, sizeof(_fd));
}
CFileSysBindData::~CFileSysBindData()
{
}
HRESULT CFileSysBindData::QueryInterface(REFIID riid, void **ppv)
{
static const QITAB qit[] = {
QITABENT(CFileSysBindData, IFileSystemBindData), // IID_IFileSystemBindData
{ 0 },
};
return QISearch(this, qit, riid, ppv);
}
STDMETHODIMP_(ULONG) CFileSysBindData::AddRef(void)
{
return InterlockedIncrement(&_cRef);
}
STDMETHODIMP_(ULONG) CFileSysBindData::Release()
{
ASSERT( 0 != _cRef );
ULONG cRef = InterlockedDecrement(&_cRef);
if ( 0 == cRef )
{
delete this;
}
return cRef;
}
HRESULT CFileSysBindData::SetFindData(const WIN32_FIND_DATAW *pfd)
{
_fd = *pfd;
return S_OK;
}
HRESULT CFileSysBindData::GetFindData(WIN32_FIND_DATAW *pfd)
{
*pfd = _fd;
return S_OK;
}
STDAPI SHCreateFileSysBindCtx(const WIN32_FIND_DATAW *pfd, IBindCtx **ppbc)
{
HRESULT hres;
IFileSystemBindData *pfsbd = new CFileSysBindData();
if (pfsbd)
{
if (pfd)
{
pfsbd->SetFindData(pfd);
}
hres = CreateBindCtx(0, ppbc);
if (SUCCEEDED(hres))
{
BIND_OPTS bo = {sizeof(bo)}; // Requires size filled in.
bo.grfMode = STGM_CREATE;
(*ppbc)->SetBindOptions(&bo);
(*ppbc)->RegisterObjectParam(STR_FILE_SYS_BIND_DATA, pfsbd);
}
pfsbd->Release();
}
else
{
*ppbc = NULL;
hres = E_OUTOFMEMORY;
}
return hres;
}
STDAPI SHSimpleIDListFromFindData(LPCWSTR pszPath, const WIN32_FIND_DATAW *pfd, PIDLIST_ABSOLUTE *ppidl)
{
*ppidl = NULL;
IBindCtx *pbc;
HRESULT hr = SHCreateFileSysBindCtx(pfd, &pbc);
if (SUCCEEDED(hr))
{
hr = SHParseDisplayName(pszPath, pbc, ppidl, 0, NULL);
pbc->Release();
}
return hr;
}
STDAPI SimpleIDListFromAttributes(LPCWSTR pszPath, DWORD dwAttributes, PIDLIST_ABSOLUTE *ppidl)
{
WIN32_FIND_DATAW fd = {0};
fd.dwFileAttributes = dwAttributes;
// SHCreateFSIDList(pszPath, &fd, ppidl);
return SHSimpleIDListFromFindData(pszPath, &fd, ppidl);
}
//*************************************************************
//
// SizeofStringResource
//
// Purpose: Find the length (in chars) of a string resource
//
// Parameters: HINSTANCE hInstance - module containing the string
// UINT idStr - ID of string
//
//
// Return: UINT - # of chars in string, not including NULL
//
// Notes: Based on code from user32.
//
//*************************************************************
UINT
SizeofStringResource(HINSTANCE hInstance, UINT idStr)
{
UINT cch = 0;
HRSRC hRes = FindResource(hInstance, (LPTSTR)((LONG_PTR)(((USHORT)idStr >> 4) + 1)), RT_STRING);
if (NULL != hRes)
{
HGLOBAL hStringSeg = LoadResource(hInstance, hRes);
if (NULL != hStringSeg)
{
LPWSTR psz = (LPWSTR)LockResource(hStringSeg);
if (NULL != psz)
{
idStr &= 0x0F;
while(true)
{
cch = *psz++;
if (idStr-- == 0)
break;
psz += cch;
}
}
}
}
return cch;
}
//*************************************************************
//
// LoadStringAlloc
//
// Purpose: Loads a string resource into an alloc'd buffer
//
// Parameters: ppszResult - string resource returned here
// hInstance - module to load string from
// idStr - string resource ID
//
// Return: same as LoadString
//
// Notes: On successful return, the caller must
// LocalFree *ppszResult
//
//*************************************************************
int
LoadStringAlloc(LPWSTR *ppszResult, HINSTANCE hInstance, UINT idStr)
{
int nResult = 0;
UINT cch = SizeofStringResource(hInstance, idStr);
if (cch)
{
cch++; // for NULL
*ppszResult = (LPWSTR)LocalAlloc(LPTR, cch * sizeof(WCHAR));
if (*ppszResult)
nResult = LoadString(hInstance, idStr, *ppszResult, cch);
}
return nResult;
}