I'm working with the cfapi and are attempting to extend the sample project available here https://github.com/Microsoft/Windows-classic-samples/tree/master/Samples/CloudMirror
Specifically we are looking to implement the CF_CALLBACK_TYPE_FETCH_PLACEHOLDERS to provide directory content on-demand. Our callbacks are registered like so:-
CF_CALLBACK_REGISTRATION FakeCloudProvider::s_MirrorCallbackTable[] =
{
{ CF_CALLBACK_TYPE_FETCH_PLACEHOLDERS, FakeCloudProvider::OnFetchPlaceholders },
{ CF_CALLBACK_TYPE_FETCH_DATA, FakeCloudProvider::OnFetchData },
{ CF_CALLBACK_TYPE_CANCEL_FETCH_DATA, FakeCloudProvider::OnCancelFetchData },
CF_CALLBACK_REGISTRATION_END
};
The OnFetchPlaceholders method calls CfExecute() to respond to the callback with an array of placeholders for the associated files in the server directory.
CF_OPERATION_INFO opInfo = { 0 };
CF_OPERATION_PARAMETERS opParams = { 0 };
opInfo.StructSize = sizeof(opInfo);
opInfo.Type = CF_OPERATION_TYPE_TRANSFER_PLACEHOLDERS;
opInfo.ConnectionKey = callbackInfo->ConnectionKey;
opInfo.TransferKey = callbackInfo->TransferKey;
opParams.ParamSize = sizeof(opParams);
opParams.TransferPlaceholders.CompletionStatus = status;
opParams.TransferPlaceholders.Flags = CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_NONE;
opParams.TransferPlaceholders.PlaceholderArray = placeholders;
opParams.TransferPlaceholders.PlaceholderCount = placeholdersCount;
opParams.TransferPlaceholders.PlaceholderTotalCount.QuadPart = placeholdersCount;
winrt::check_hresult(CfExecute(&opInfo, &opParams));
Unexpectedly, with just three files in the server directory and no subdirectories the OnFetchPlacehodlers function is called many times in quick succession (457 times in the test I just carried out) - to the extent where Explorer stops responding for a while. Strangely the number of times that the method is called seems to vary between about 200 and 500 but there doesn't seem to be any discernible pattern.
I've tried setting the flag CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_DISABLE_ON_DEMAND_POPULATION
in the callback and when I do this we are only called once but once set we are never asked again for the placeholders even if we have new ones to provide.
I believe folder only needs to be populated once during the first access, then you will need use other methods to make it's contents in sync(e.g. pull the server periodically).
In my experience with the API, if you do not disable the on-demand population, every access to this folder by the explorer.exe or SearchProtocolHost.exe ( the Windows Index Service) will trigger a new FetchPlaceholders callback, which I believe is the reason why the callback got triggered repeatedly, this not only impact the system performance, will also increase the loads of your server.
If you do need "revoke" the CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_DISABLE_ON_DEMAND_POPULATION, just call the CfUpdatePlacehoder API and pass in the CF_UPDATE_FLAG_ENABLE_ON_DEMAND_POPULATION flag, this will re-enable the on-demand population, and any future access to this folder will trigger the FETCH_PLACEHOLDERS callback again.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With