Skip to content

Commit 12a50c8

Browse files
author
yerudako
committed
(cgallred) Fix-enumeration-handling
1 parent 3417d3a commit 12a50c8

File tree

3 files changed

+34
-21
lines changed

3 files changed

+34
-21
lines changed

simpleProviderManaged/ActiveEnumeration.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ public ActiveEnumeration(List<ProjectedFileInfo> fileInfos)
1919
this.MoveNext();
2020
}
2121

22+
/// <summary>
23+
/// Indicates whether the current item is the first one in the enumeration.
24+
/// </summary>
25+
public bool IsCurrentFirst { get; private set; }
26+
2227
/// <summary>
2328
/// true if Current refers to an element in the enumeration, false if Current is past the end of the collection
2429
/// </summary>
@@ -54,6 +59,8 @@ public void RestartEnumeration(
5459
public bool MoveNext()
5560
{
5661
this.IsCurrentValid = this.fileInfoEnumerator.MoveNext();
62+
this.IsCurrentFirst = false;
63+
5764
while (this.IsCurrentValid && this.IsCurrentHidden())
5865
{
5966
this.IsCurrentValid = this.fileInfoEnumerator.MoveNext();
@@ -139,6 +146,7 @@ private bool IsCurrentHidden()
139146
private void ResetEnumerator()
140147
{
141148
this.fileInfoEnumerator = this.fileInfos.GetEnumerator();
149+
this.IsCurrentFirst = true;
142150
}
143151
}
144152
}

simpleProviderManaged/EnvironmentHelper.cs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,16 @@ public static class EnvironmentHelper
1111
{
1212
public static bool IsFullSymlinkSupportAvailable()
1313
{
14-
if (System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription.StartsWith(".NET Core"))
15-
{
16-
// Using registry instead of OSVersion due to https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversionexa?redirectedfrom=MSDN.
17-
// This code can be replaced with Environment.OSVersion on .NET Core 5 and higher.
18-
int build = Convert.ToInt32(Microsoft.Win32.Registry.GetValue(
19-
@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion",
20-
"CurrentBuild",
21-
0));
14+
// Using registry instead of OSVersion due to https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getversionexa?redirectedfrom=MSDN.
15+
// This code can be replaced with Environment.OSVersion on .NET Core 5 and higher.
16+
int build = Convert.ToInt32(Microsoft.Win32.Registry.GetValue(
17+
@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion",
18+
"CurrentBuild",
19+
0));
2220

23-
if (build >= 19041)
24-
{
25-
return true;
26-
}
21+
if (build >= 19041)
22+
{
23+
return true;
2724
}
2825

2926
return false;

simpleProviderManaged/SimpleProvider.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ internal HResult GetDirectoryEnumerationCallback(
370370
// Find the requested enumeration. It should have been put there by StartDirectoryEnumeration.
371371
if (!this.activeEnumerations.TryGetValue(enumerationId, out ActiveEnumeration enumeration))
372372
{
373+
Log.Fatal(" GetDirectoryEnumerationCallback {Result}", HResult.InternalError);
373374
return HResult.InternalError;
374375
}
375376

@@ -389,7 +390,6 @@ internal HResult GetDirectoryEnumerationCallback(
389390
enumeration.TrySaveFilterString(filterFileName);
390391
}
391392

392-
bool entryAdded = false;
393393
HResult hr = HResult.Ok;
394394

395395
while (enumeration.IsCurrentValid)
@@ -402,27 +402,35 @@ internal HResult GetDirectoryEnumerationCallback(
402402
break;
403403
}
404404

405+
// A provider adds entries to the enumeration buffer until it runs out, or until adding
406+
// an entry fails. If adding an entry fails, the provider remembers the entry it couldn't
407+
// add. ProjFS will call the GetDirectoryEnumerationCallback again, and the provider
408+
// must resume adding entries, starting at the last one it tried to add. SimpleProvider
409+
// remembers the entry it couldn't add simply by not advancing its ActiveEnumeration.
405410
if (AddFileInfoToEnum(enumResult, fileInfo, targetPath))
406411
{
407-
entryAdded = true;
408412
enumeration.MoveNext();
409413
}
410414
else
411415
{
412-
if (entryAdded)
413-
{
414-
hr = HResult.Ok;
415-
}
416-
else
416+
// If we could not add the very first entry in the enumeration, a provider must
417+
// return InsufficientBuffer.
418+
if (enumeration.IsCurrentFirst)
417419
{
418420
hr = HResult.InsufficientBuffer;
419421
}
420-
421422
break;
422423
}
423424
}
424425

425-
Log.Information("<---- GetDirectoryEnumerationCallback {Result}", hr);
426+
if (hr == HResult.Ok)
427+
{
428+
Log.Information("<---- GetDirectoryEnumerationCallback {Result}", hr);
429+
}
430+
else
431+
{
432+
Log.Error("<---- GetDirectoryEnumerationCallback {Result}", hr);
433+
}
426434
return hr;
427435
}
428436

0 commit comments

Comments
 (0)