Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

393 lines
14 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995
//
// File: synquery.cpp
//
// Contents: COFSFolder::SynchronousQuery - Runs a synchronous filesystem
// query
//
// History: 6-29-95 DavePl,JonBe Created
//
//--------------------------------------------------------------------------
#include "precomp.h"
//
// The maximum number of rows fetched at once through pRowset->GetData()
//
#define MAX_FETCHED_AT_ONCE 100
GUID guidSystem = PSGUID_STORAGE;
//
// Buffer into which we read data from the rowsets
//
typedef WCHAR NAMEBUF[MAX_PATH]; // Longest allowable NT filesystem path
typedef WCHAR SNAMEBUF[13]; // 8+1+3+1 => 8.3 name plus NULL
struct SRowBuf
{
FILETIME ftLastWriteTime;
LONGLONG llFileSize;
DWORD dwFileAttributes;
NAMEBUF awchName;
SNAMEBUF awchShortName;
};
DBBINDING aOutColumns[] =
{
{ DBCOLUMNPART_VALUE, 0, 0, VT_FILETIME, NULL, NULL, offsetof(SRowBuf, ftLastWriteTime), SIZEOF(FILETIME), {0,0,0}, 0, 0 },
{ DBCOLUMNPART_VALUE, 0, 0, DBTYPE_I8, NULL, NULL, offsetof(SRowBuf, llFileSize), SIZEOF(LONGLONG), {0,0,0}, 0, 0 },
{ DBCOLUMNPART_VALUE, 0, 0, DBTYPE_I4, NULL, NULL, offsetof(SRowBuf, dwFileAttributes), SIZEOF(DWORD), {0,0,0}, 0, 0 },
{ DBCOLUMNPART_VALUE, 0, 0, DBTYPE_WSTR, NULL, NULL, offsetof(SRowBuf, awchName), MAX_PATH * SIZEOF(WCHAR), {0,0,0}, 0, 0 },
{ DBCOLUMNPART_VALUE, 0, 0, DBTYPE_WSTR, NULL, NULL, offsetof(SRowBuf, awchShortName), 13 * SIZEOF(WCHAR), {0,0,0}, 0, 0 }
};
const int cOutColumns = ARRAYSIZE(aOutColumns);
//+-------------------------------------------------------------------------
//
// Member: SynchronousQuery
//
// Synopsis: Given an enumerator and a path, runs a query to locate
// all filesystem objects at that path and adds them all
// (as pidls) to the enumerator
//
// Notes:
//
//--------------------------------------------------------------------------
HRESULT COFSFolder::SynchronousQuery(TCHAR* szFolder,
DWORD grfFlags,
CEnumOLEDB* pEnumOLEDB)
{
HRESULT hr = NOERROR;
CPropertyRestriction * prst = NULL;
IOldQuery * pQuery = NULL;
IRowset * pRowset = NULL;
IAccessor * pIAccessor = NULL;
IColumnsInfo * pIColumnsInfo = NULL;
HACCESSOR hAccessor = NULL;
ULONG cHiddenFiles = 0; // Count of hidden files. Used to update
// folder's count at end of enumeration
DWORD dwSize = 0; // Total size of files enumerated. Used to
// update folder's size at end of enumeration
TRY
{
// BUGBUG Scope
const DBID dbcolLastWriteTime = {PSGUID_STORAGE, DBKIND_GUID_PROPID, (LPWSTR)PID_STG_WRITETIME};
const DBID dbcolSize = {PSGUID_STORAGE, DBKIND_GUID_PROPID, (LPWSTR)PID_STG_SIZE};
const DBID dbcolAttributes = {PSGUID_STORAGE, DBKIND_GUID_PROPID, (LPWSTR)PID_STG_ATTRIBUTES};
const DBID dbcolName = {PSGUID_STORAGE, DBKIND_GUID_PROPID, (LPWSTR)PID_STG_NAME};
const DBID dbcolShortName = {PSGUID_STORAGE, DBKIND_GUID_PROPID, (LPWSTR)PID_STG_SHORTNAME};
CFullPropSpec psWriteTime (guidSystem, PID_STG_WRITETIME);
CFullPropSpec psSize (guidSystem, PID_STG_SIZE);
CFullPropSpec psAttributes(guidSystem, PID_STG_ATTRIBUTES);
CFullPropSpec psName (guidSystem, PID_STG_NAME);
CFullPropSpec psShortName (guidSystem, PID_STG_SHORTNAME);
CRestriction *prstQuery = 0;
pQuery = EvalQuery4(szFolder, 0);
if (NULL == pQuery)
{
hr = E_FAIL;
dprintf(TEXT("COFSFolder::SynchronousQuery - EvalQuery4 failed"));
LEAVE;
}
//
// Columns returned by the query
//
CColumns cols(cOutColumns);
VERIFY( cols.Add(psWriteTime, 0) );
VERIFY( cols.Add(psSize, 1) );
VERIFY( cols.Add(psAttributes, 2) );
VERIFY( cols.Add(psName, 3) );
VERIFY( cols.Add(psShortName, 4) );
//
// Make a restriction
//
prst = new CPropertyRestriction();
if (NULL == prst)
{
hr = E_OUTOFMEMORY;
LEAVE;
}
prstQuery = prst;
prst->SetRelation( PRRE );
prst->SetProperty( psName );
prst->SetValue ( L"*" );
hr = pQuery->ExecuteQuery(QUERY_SHALLOW, // Depth
prstQuery->CastToStruct(), // Restriction
cols.CastToStruct(), // Output
0, // Sort
eSequentialCursor, // Flags
IID_IRowset, // IID for i/f to return
(IUnknown **)&pRowset ); // Return interface
LEAVE_IF( FAILED(hr) );
// map the column ids from guid form to column numbers needed to
// create the accessor
DBID aDbCols[cOutColumns];
aDbCols[0] = dbcolLastWriteTime;
aDbCols[1] = dbcolSize;
aDbCols[2] = dbcolAttributes;
aDbCols[3] = dbcolName;
aDbCols[4] = dbcolShortName;
hr = pRowset->QueryInterface(IID_IColumnsInfo, (void**)&pIColumnsInfo);
LEAVE_IF( FAILED(hr) );
hr = pRowset->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
LEAVE_IF( FAILED(hr) );
LONG aColIds[cOutColumns];
hr = pIColumnsInfo->MapColumnIDs(cOutColumns,aDbCols,aColIds);
LEAVE_IF( FAILED(hr) );
for (ULONG c = 0; c < cOutColumns; c++)
{
aOutColumns[c].iColumn = aColIds[c];
}
hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA,
cOutColumns,
aOutColumns,
0,
0,
&hAccessor);
LEAVE_IF( FAILED(hr) );
// Now go through the whole rowset and put those items that match our
// criteria (as determined by grfFlags) in the enumerator ptr array
ULONG cFetched = 0;
while ((0 != cFetched) ||
(DB_S_ENDOFROWSET != hr))
{
ULONG cThisTime = MAX_FETCHED_AT_ONCE;
HROW aHRows[MAX_FETCHED_AT_ONCE],*pHRows = aHRows;
hr = pRowset->GetNextRows(DB_INVALID_HCHAPTER, // no chapter
0, // no offset
cThisTime, // # requested
&cFetched, // # fetched
&pHRows); // put them here
if (0 != cFetched)
{
for (ULONG x = 0; x < cFetched; x++)
{
SRowBuf Row;
if (FAILED(hr = pRowset->GetData(aHRows[x],hAccessor,&Row)))
{
ASSERT( 0 && "pRowset->GetData failed" );
continue;
}
BOOL fFound = FALSE;
WIN32_FIND_DATA finddata;
//
// Fill out the WIN32_FIND_DATA structure from the data we got back in the row buffer
//
ZeroMemory(&finddata, sizeof(finddata));
finddata.dwFileAttributes = Row.dwFileAttributes;
// Note that ftLastAccess and ftCreate are not used by fstreex.c
finddata.ftLastWriteTime.dwLowDateTime = Row.ftLastWriteTime.dwLowDateTime;
finddata.ftLastWriteTime.dwHighDateTime = Row.ftLastWriteTime.dwHighDateTime;
finddata.nFileSizeHigh = (ULONG) (Row.llFileSize >> 32);
finddata.nFileSizeLow = (ULONG) (Row.llFileSize & 0xFFFFFFFF);
finddata.dwReserved0 = 0;
finddata.dwReserved1 = 0;
lstrcpynW(finddata.cFileName, Row.awchName, MAX_PATH);
lstrcpynW(finddata.cAlternateFileName, Row.awchShortName, ARRAYSIZE(Row.awchShortName));
//
// BUGBUG Overflow problems here
//
dwSize += finddata.nFileSizeLow;
//
// Object is a folder, but we aren't looking for folders, so skip it
//
if (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (0 == (grfFlags & SHCONTF_FOLDERS))
{
cHiddenFiles++;
continue;
}
}
else
{
//
// Object is a non-folder, but we are not enumerating for
// non-folders
//
if (0 == (grfFlags & SHCONTF_NONFOLDERS))
{
cHiddenFiles++;
continue;
}
}
if (0 == (grfFlags & SHCONTF_INCLUDEHIDDEN))
{
//
// If object is hidden, but we aren't looking for hidden
// objects, skip it
//
if (finddata.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
{
cHiddenFiles++;
continue;
}
//
// If we are looking in the recent docs dir, but we can't
// find this item in the recent docs MRU, skip it
//
if (grfFlags & SHCONTF_RECENTDOCSDIR)
{
if (FALSE == FindLinkInRecentDocsMRU(finddata.cFileName))
{
cHiddenFiles++;
continue;
}
}
//
// If this is a non-folder object, and is one of the types
// (based on its extension) that we are hiding, skip it
//
if (0 == (finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
&& _SHFindExcludeExt(finddata.cFileName) >= 0)
{
cHiddenFiles++;
continue;
}
}
//
// Object matches all of our criteria for one that should be
// displayed in this view, so we can stop looking
//
fFound = TRUE;
//
// We are done looking. If we found an object to be displayed, create
// an IDList and hand it back. Otherwise, we have looked at all of
// the objects in this folder, and we are done. We take that
// opportunity to update the hidden count and size summation in the
// folder itself.
//
if (fFound)
{
LPIDFOLDER pidf = CFSFolder_FillIDFolder(&finddata,
szFolder,
0L);
if (pidf)
{
hr = pEnumOLEDB->AddElement((LPITEMIDLIST)pidf);
if (FAILED(hr))
{
dprintf(TEXT("COFSFolder::SynchronousQuery -- pEnumOLEDB->AddElement (%lx)\n"), hr);
VERIFY(SUCCEEDED( pRowset->ReleaseRows(cFetched, aHRows, 0, 0) ));
LEAVE;
}
}
else
{
dprintf(TEXT("COFSFolder::SynchronousQuery -- CFSFolder_FillIDFolder failed\n"));
VERIFY(SUCCEEDED( pRowset->ReleaseRows(cFetched, aHRows, 0, 0) ));
LEAVE;
}
}
}
VERIFY(SUCCEEDED( pRowset->ReleaseRows(cFetched, aHRows, 0, 0) ));
}
}
}
FINALLY
{
//
// Normal cleanup
//
if (pIColumnsInfo)
{
pIColumnsInfo->Release();
}
if (pIAccessor)
{
if (hAccessor)
{
VERIFY(SUCCEEDED( pIAccessor->ReleaseAccessor(hAccessor) ));
}
pIAccessor->Release();
}
if (pRowset)
{
pRowset->Release();
}
if (grfFlags & SHCONTF_RECENTDOCSDIR)
{
CloseRecentDocMRU();
}
if (pQuery)
{
pQuery->Release();
}
delete prst;
//
// Only update folders hidden count and size if the enum was successful
//
if (SUCCEEDED(hr))
{
m_cHiddenFiles = cHiddenFiles;
m_dwSize = dwSize;
}
else
{
dprintf(TEXT("OLEDBSHL: Abnormal Exit from COFSFolder::SynchronousQuery, hr = %lx\n"), hr);
}
return hr;
}
}