fix(cloud-files): Sauberes Re-Register + FETCH_PLACEHOLDERS-Stub + mehr Log
- CfUnregisterSyncRoot VOR CfRegisterSyncRoot, damit alte Policies (z.B. PARTIAL) nicht durch UPDATE-Flag kleben bleiben - FETCH_PLACEHOLDERS-Stub registriert, der mit leerer Antwort und DISABLE_ON_DEMAND_POPULATION-Flag antwortet. Safety-Net falls Windows trotz FULL-Policy doch danach fragt - log_msg an kritischen Stellen (register, connect, populate), damit wir beim naechsten Timeout sehen wo es haengt Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e55ce106d4
commit
2937082ba2
|
|
@ -102,9 +102,18 @@ pub fn register_sync_root(
|
|||
// struct einbauen koennen. windows-rs verlangt hier nichts weiter.
|
||||
let _ = display_wide;
|
||||
|
||||
// Erst versuchen ohne UPDATE-Flag (frische Registrierung). Bei "schon
|
||||
// registriert"-Fehler nochmal mit UPDATE-Flag. So laeuft es beim ersten
|
||||
// Aktivieren UND bei Folgestarts.
|
||||
// Erst eine eventuell vorhandene Registrierung wegraeumen. Sonst
|
||||
// uebernimmt UPDATE nur einen Teil der Policies und alte PARTIAL-
|
||||
// Population-Einstellungen bleiben aktiv -> Explorer-Timeout.
|
||||
unsafe {
|
||||
let _ = CF::CfUnregisterSyncRoot(PCWSTR(path_wide.as_ptr()));
|
||||
}
|
||||
|
||||
log_msg(mount_point, &format!(
|
||||
"register_sync_root path={} provider={} account={}",
|
||||
mount_point.display(), provider_name, account_id
|
||||
));
|
||||
|
||||
unsafe {
|
||||
if let Err(e) = CF::CfRegisterSyncRoot(
|
||||
PCWSTR(path_wide.as_ptr()),
|
||||
|
|
@ -112,9 +121,8 @@ pub fn register_sync_root(
|
|||
&policies,
|
||||
CF::CF_REGISTER_FLAG_NONE,
|
||||
) {
|
||||
let already = e.code().0 == 0x80070091u32 as i32 // DIR_NOT_EMPTY
|
||||
|| e.code().0 == 0x800710D1u32 as i32; // Already registered
|
||||
if already {
|
||||
log_err(mount_point, &format!("CfRegisterSyncRoot FAILED: {e:?}"));
|
||||
// Als Fallback mit UPDATE-Flag
|
||||
CF::CfRegisterSyncRoot(
|
||||
PCWSTR(path_wide.as_ptr()),
|
||||
&info,
|
||||
|
|
@ -122,13 +130,12 @@ pub fn register_sync_root(
|
|||
CF::CF_REGISTER_FLAG_UPDATE,
|
||||
)
|
||||
.map_err(|e| format!("CfRegisterSyncRoot(UPDATE): {e}"))?;
|
||||
} else {
|
||||
return Err(format!("CfRegisterSyncRoot: {e}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
log_msg(mount_point, "CfRegisterSyncRoot OK");
|
||||
connect_callbacks(mount_point)?;
|
||||
log_msg(mount_point, "callbacks connected");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -308,12 +315,40 @@ fn complete_transfer(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
unsafe extern "system" fn on_fetch_placeholders(
|
||||
info: *const CF::CF_CALLBACK_INFO,
|
||||
_params: *const CF::CF_CALLBACK_PARAMETERS,
|
||||
) {
|
||||
// Safety-Net: wir populieren schon ueber populate_placeholders,
|
||||
// aber falls Windows trotzdem ruft, geben wir leere Antwort.
|
||||
let info = &*info;
|
||||
let mut op_info = CF::CF_OPERATION_INFO::default();
|
||||
op_info.StructSize = std::mem::size_of::<CF::CF_OPERATION_INFO>() as u32;
|
||||
op_info.Type = CF::CF_OPERATION_TYPE_TRANSFER_PLACEHOLDERS;
|
||||
op_info.ConnectionKey = info.ConnectionKey;
|
||||
op_info.TransferKey = info.TransferKey;
|
||||
let mut params = CF::CF_OPERATION_PARAMETERS::default();
|
||||
params.ParamSize = std::mem::size_of::<CF::CF_OPERATION_PARAMETERS>() as u32;
|
||||
let transfer = &mut params.Anonymous.TransferPlaceholders;
|
||||
transfer.CompletionStatus = windows::Win32::Foundation::NTSTATUS(0);
|
||||
transfer.PlaceholderTotalCount = 0;
|
||||
transfer.PlaceholderArray = std::ptr::null_mut();
|
||||
transfer.PlaceholderCount = 0;
|
||||
transfer.EntriesProcessed = 0;
|
||||
transfer.Flags = CF::CF_OPERATION_TRANSFER_PLACEHOLDERS_FLAG_DISABLE_ON_DEMAND_POPULATION;
|
||||
let _ = CF::CfExecute(&op_info, &mut params);
|
||||
}
|
||||
|
||||
fn connect_callbacks(mount_point: &Path) -> Result<(), String> {
|
||||
let callbacks = [
|
||||
CF::CF_CALLBACK_REGISTRATION {
|
||||
Type: CF::CF_CALLBACK_TYPE_FETCH_DATA,
|
||||
Callback: Some(on_fetch_data),
|
||||
},
|
||||
CF::CF_CALLBACK_REGISTRATION {
|
||||
Type: CF::CF_CALLBACK_TYPE_FETCH_PLACEHOLDERS,
|
||||
Callback: Some(on_fetch_placeholders),
|
||||
},
|
||||
// Sentinel: Type = INVALID beendet die Tabelle.
|
||||
CF::CF_CALLBACK_REGISTRATION {
|
||||
Type: CF::CF_CALLBACK_TYPE_NONE,
|
||||
|
|
@ -357,6 +392,9 @@ pub fn populate_placeholders(
|
|||
entries: &[RemoteEntry],
|
||||
) -> Result<(), String> {
|
||||
use std::collections::HashMap;
|
||||
log_msg(mount_point, &format!(
|
||||
"populate_placeholders: {} Eintraege", entries.len()
|
||||
));
|
||||
let by_id: HashMap<i64, &RemoteEntry> = entries.iter().map(|e| (e.id, e)).collect();
|
||||
|
||||
fn rel_path<'a>(
|
||||
|
|
|
|||
Loading…
Reference in New Issue