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.
|
// struct einbauen koennen. windows-rs verlangt hier nichts weiter.
|
||||||
let _ = display_wide;
|
let _ = display_wide;
|
||||||
|
|
||||||
// Erst versuchen ohne UPDATE-Flag (frische Registrierung). Bei "schon
|
// Erst eine eventuell vorhandene Registrierung wegraeumen. Sonst
|
||||||
// registriert"-Fehler nochmal mit UPDATE-Flag. So laeuft es beim ersten
|
// uebernimmt UPDATE nur einen Teil der Policies und alte PARTIAL-
|
||||||
// Aktivieren UND bei Folgestarts.
|
// 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 {
|
unsafe {
|
||||||
if let Err(e) = CF::CfRegisterSyncRoot(
|
if let Err(e) = CF::CfRegisterSyncRoot(
|
||||||
PCWSTR(path_wide.as_ptr()),
|
PCWSTR(path_wide.as_ptr()),
|
||||||
|
|
@ -112,23 +121,21 @@ pub fn register_sync_root(
|
||||||
&policies,
|
&policies,
|
||||||
CF::CF_REGISTER_FLAG_NONE,
|
CF::CF_REGISTER_FLAG_NONE,
|
||||||
) {
|
) {
|
||||||
let already = e.code().0 == 0x80070091u32 as i32 // DIR_NOT_EMPTY
|
log_err(mount_point, &format!("CfRegisterSyncRoot FAILED: {e:?}"));
|
||||||
|| e.code().0 == 0x800710D1u32 as i32; // Already registered
|
// Als Fallback mit UPDATE-Flag
|
||||||
if already {
|
CF::CfRegisterSyncRoot(
|
||||||
CF::CfRegisterSyncRoot(
|
PCWSTR(path_wide.as_ptr()),
|
||||||
PCWSTR(path_wide.as_ptr()),
|
&info,
|
||||||
&info,
|
&policies,
|
||||||
&policies,
|
CF::CF_REGISTER_FLAG_UPDATE,
|
||||||
CF::CF_REGISTER_FLAG_UPDATE,
|
)
|
||||||
)
|
.map_err(|e| format!("CfRegisterSyncRoot(UPDATE): {e}"))?;
|
||||||
.map_err(|e| format!("CfRegisterSyncRoot(UPDATE): {e}"))?;
|
|
||||||
} else {
|
|
||||||
return Err(format!("CfRegisterSyncRoot: {e}"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log_msg(mount_point, "CfRegisterSyncRoot OK");
|
||||||
connect_callbacks(mount_point)?;
|
connect_callbacks(mount_point)?;
|
||||||
|
log_msg(mount_point, "callbacks connected");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,12 +315,40 @@ fn complete_transfer(
|
||||||
Ok(())
|
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> {
|
fn connect_callbacks(mount_point: &Path) -> Result<(), String> {
|
||||||
let callbacks = [
|
let callbacks = [
|
||||||
CF::CF_CALLBACK_REGISTRATION {
|
CF::CF_CALLBACK_REGISTRATION {
|
||||||
Type: CF::CF_CALLBACK_TYPE_FETCH_DATA,
|
Type: CF::CF_CALLBACK_TYPE_FETCH_DATA,
|
||||||
Callback: Some(on_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.
|
// Sentinel: Type = INVALID beendet die Tabelle.
|
||||||
CF::CF_CALLBACK_REGISTRATION {
|
CF::CF_CALLBACK_REGISTRATION {
|
||||||
Type: CF::CF_CALLBACK_TYPE_NONE,
|
Type: CF::CF_CALLBACK_TYPE_NONE,
|
||||||
|
|
@ -357,6 +392,9 @@ pub fn populate_placeholders(
|
||||||
entries: &[RemoteEntry],
|
entries: &[RemoteEntry],
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
use std::collections::HashMap;
|
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();
|
let by_id: HashMap<i64, &RemoteEntry> = entries.iter().map(|e| (e.id, e)).collect();
|
||||||
|
|
||||||
fn rel_path<'a>(
|
fn rel_path<'a>(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue