BOOL BuildDirectoryBagOValues()

in src/wfgoto.cpp [295:398]


BOOL BuildDirectoryBagOValues(BagOValues<PDNODE> *pbov, vector<PDNODE> *pNodes, LPCTSTR szRoot, PDNODE pNodeParent, DWORD scanEpoc)
{
	LFNDTA lfndta;
	WCHAR szPath[MAXPATHLEN];
	LPWSTR szEndPath;

	lstrcpy(szPath, szRoot);
	if (lstrlen(szPath) + 1 >= COUNTOF(szPath))
	{
		// path too long
		return TRUE;
	}

	AddBackslash(szPath);
	szEndPath = szPath + lstrlen(szPath);

	if (pNodeParent == nullptr)
	{
		// create first one; assume directory; "name" is full path starting with <drive>:
		// normally name is just directory name by itself
		pNodeParent = CreateNode(nullptr, szPath, FILE_ATTRIBUTE_DIRECTORY);
		if (pNodeParent == nullptr)
		{
			// out of memory
			return TRUE;
		}

		pNodes->push_back(pNodeParent);
		pbov->Add(szPath, pNodeParent);
	}

	if (lstrlen(szPath) + lstrlen(szStarDotStar) >= COUNTOF(szPath))
	{
		// path too long
		return TRUE;
	}

	// add *.* to end of path
	lstrcat(szPath, szStarDotStar);

	BOOL bFound = WFFindFirst(&lfndta, szPath, ATTR_DIR);

	while (bFound)
	{
		if (g_driveScanEpoc != scanEpoc)
		{
			// new scan started; abort this one
			WFFindClose(&lfndta);
			return FALSE;
		}

		// for all directories at this level, insert into BagOValues
        // do not insert the directories '.' or '..'; or insert empty directory names (cf. issue #194)

		if ((lfndta.fd.dwFileAttributes & ATTR_DIR) == 0 || ISDOTDIR(lfndta.fd.cFileName) || lfndta.fd.cFileName[0] == CHAR_NULL)
		{
			bFound = WFFindNext(&lfndta);
			continue;
		}

		PDNODE pNodeChild = CreateNode(pNodeParent, lfndta.fd.cFileName, lfndta.fd.dwFileAttributes);
		if (pNodeChild == nullptr)
		{
			// out of memory
			break;
		}
		pNodes->push_back(pNodeChild);

		// if spaces, each word individually (and not whole thing)
		vector<wstring> words = SplitIntoWords(lfndta.fd.cFileName);

		for (auto word : words)
		{
			// TODO: how to mark which word is primary to avoid double free?
			pbov->Add(word, pNodeChild);
		}

		//
		// Construct the path to this new subdirectory.
		//
		*szEndPath = CHAR_NULL;
		if (lstrlen(szPath) + 1 + lstrlen(lfndta.fd.cFileName) >= COUNTOF(szPath))
		{
			// path too long
			return TRUE;
		}

		AddBackslash(szPath);
		lstrcat(szPath, lfndta.fd.cFileName);         // cFileName is ANSI now

		// add directories in subdir
		if (!BuildDirectoryBagOValues(pbov, pNodes, szPath, pNodeChild, scanEpoc))
		{
			WFFindClose(&lfndta);
			return FALSE;
		}

		bFound = WFFindNext(&lfndta);
	}

	WFFindClose(&lfndta);

	return TRUE;
}