11
11
namespace Files . App . Utils . Cloud
12
12
{
13
13
/// <summary>
14
- /// Provides an utility for Google Drive Cloud detection.
14
+ /// Provides a utility for Google Drive Cloud detection.
15
15
/// </summary>
16
16
public sealed class GoogleDriveCloudDetector : AbstractCloudDetector
17
17
{
@@ -55,9 +55,6 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
55
55
continue ;
56
56
}
57
57
58
- if ( ( long ) reader [ "is_my_drive" ] == 1 )
59
- continue ;
60
-
61
58
// By default, the path will be prefixed with "\\?\" (unless another app has explicitly changed it).
62
59
// \\?\ indicates to Win32 that the filename may be longer than MAX_PATH (see MSDN).
63
60
// Parts of .NET (e.g. the File class) don't handle this very well, so remove this prefix.
@@ -69,12 +66,9 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
69
66
var folder = await StorageFolder . GetFolderFromPathAsync ( path ) ;
70
67
string title = reader [ "title" ] ? . ToString ( ) ?? folder . Name ;
71
68
72
- App . AppModel . GoogleDrivePath = path ;
73
-
74
69
#if DEBUG
75
- Debug . WriteLine ( $ "In GDCD in roots table: App.AppModel.GoogleDrivePath being set to: { path } ") ;
76
- Debug . WriteLine ( "YIELD RETURNING from GoogleDriveCloudDetector#GetProviders (roots): " ) ;
77
- Debug . WriteLine ( $ "name=Google Drive ({ title } ); path={ path } ") ;
70
+ Debug . WriteLine ( "YIELD RETURNING from `GoogleDriveCloudDetector.GetProviders()` (roots): " ) ;
71
+ Debug . WriteLine ( $ "Name: Google Drive ({ title } ); SyncFolder: { path } ") ;
78
72
#endif
79
73
80
74
yield return new CloudProvider ( CloudProviders . GoogleDrive )
@@ -84,6 +78,7 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
84
78
} ;
85
79
}
86
80
81
+ var iconFile = await GetGoogleDriveIconFileAsync ( ) ;
87
82
// Google virtual drive
88
83
reader = cmdMedia . ExecuteReader ( ) ;
89
84
@@ -94,21 +89,13 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
94
89
continue ;
95
90
96
91
if ( ! AddMyDriveToPathAndValidate ( ref path ) )
97
- {
98
- _logger . LogWarning ( $ "Validation failed for { path } (media)") ;
99
92
continue ;
100
- }
101
93
102
94
var folder = await StorageFolder . GetFolderFromPathAsync ( path ) ;
103
95
string title = reader [ "name" ] ? . ToString ( ) ?? folder . Name ;
104
96
105
- App . AppModel . GoogleDrivePath = path ;
106
-
107
- var iconFile = await GetGoogleDriveIconFileAsync ( ) ;
108
-
109
97
#if DEBUG
110
- Debug . WriteLine ( $ "In GDCD in media table: App.AppModel.GoogleDrivePath being set to: { path } ") ;
111
- Debug . WriteLine ( "YIELD RETURNING from GoogleDriveCloudDetector#GetProviders (media): " ) ;
98
+ Debug . WriteLine ( "YIELD RETURNING from `GoogleDriveCloudDetector.GetProviders` (media): " ) ;
112
99
Debug . WriteLine ( $ "name={ title } ; path={ path } ") ;
113
100
#endif
114
101
@@ -126,19 +113,18 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
126
113
await Inspect ( database , "SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY 1" , "root_preferences db, all tables" ) ;
127
114
#endif
128
115
129
- await foreach ( var provider in GetGoogleDriveProvidersFromRegistryAsync ( ) )
116
+ var registryPath = App . AppModel . GoogleDrivePath ;
117
+ if ( ! AddMyDriveToPathAndValidate ( ref registryPath ) )
118
+ yield break ;
119
+ yield return new CloudProvider ( CloudProviders . GoogleDrive )
130
120
{
131
-
132
- #if DEBUG
133
- Debug . WriteLine ( "YIELD RETURNING from GoogleDriveCloudDetector#GetProviders (registry): " ) ;
134
- Debug . WriteLine ( $ "name={ provider . Name } ; path={ provider . SyncFolder } ") ;
135
- #endif
136
-
137
- yield return provider ;
138
- }
121
+ Name = "Google Drive" ,
122
+ SyncFolder = registryPath ,
123
+ IconData = iconFile is not null ? await iconFile . ToByteArrayAsync ( ) : null
124
+ } ;
139
125
}
140
126
141
- private async Task Inspect ( SqliteConnection database , string sqlCommand , string contentsOf )
127
+ private static async Task Inspect ( SqliteConnection database , string sqlCommand , string contentsOf )
142
128
{
143
129
await using var cmdTablesAll = new SqliteCommand ( sqlCommand , database ) ;
144
130
var reader = await cmdTablesAll . ExecuteReaderAsync ( ) ;
@@ -194,12 +180,12 @@ private async Task Inspect(SqliteConnection database, string sqlCommand, string
194
180
return googleDriveRegValueJson ;
195
181
}
196
182
197
- public static async IAsyncEnumerable < ICloudProvider > GetGoogleDriveProvidersFromRegistryAsync ( bool addMyDriveToPath = true )
183
+ public static string ? GetRegistryBasePath ( )
198
184
{
199
185
var googleDriveRegValJson = GetGoogleDriveRegValJson ( ) ;
200
186
201
187
if ( googleDriveRegValJson is null )
202
- yield break ;
188
+ return null ;
203
189
204
190
var googleDriveRegValJsonProperty = googleDriveRegValJson
205
191
. RootElement . EnumerateObject ( )
@@ -210,46 +196,72 @@ public static async IAsyncEnumerable<ICloudProvider> GetGoogleDriveProvidersFrom
210
196
if ( googleDriveRegValJsonProperty . Value . ValueKind == JsonValueKind . Undefined )
211
197
{
212
198
_logger . LogWarning ( $ "Root element of Google Drive registry value for value name '{ _googleDriveRegValName } ' was empty.") ;
213
- yield break ;
199
+ return null ;
214
200
}
215
201
216
202
#if DEBUG
217
203
Debug . WriteLine ( "REGISTRY LOGGING" ) ;
218
204
Debug . WriteLine ( googleDriveRegValJsonProperty . ToString ( ) ) ;
219
205
#endif
220
206
221
- foreach ( var item in googleDriveRegValJsonProperty . Value . EnumerateArray ( ) )
207
+ var item = googleDriveRegValJsonProperty . Value . EnumerateArray ( ) . FirstOrDefault ( ) ;
208
+ if ( item . ValueKind == JsonValueKind . Undefined )
222
209
{
223
- if ( ! item . TryGetProperty ( _googleDriveRegValPropName , out var googleDriveRegValProp ) )
224
- continue ;
210
+ _logger . LogWarning ( $ "Array in the root element of Google Drive registry value for value name '{ _googleDriveRegValName } ' was empty.") ;
211
+ return null ;
212
+ }
225
213
226
- if ( ! googleDriveRegValProp . TryGetProperty ( _googleDriveRegValPropPropName , out var googleDriveRegValPropProp ) )
227
- continue ;
214
+ if ( ! item . TryGetProperty ( _googleDriveRegValPropName , out var googleDriveRegValProp ) )
215
+ {
216
+ _logger . LogWarning ( $ "First element in the Google Drive Registry Root Array did not have property named { _googleDriveRegValPropName } ") ;
217
+ return null ;
218
+ }
228
219
229
- var path = googleDriveRegValPropProp . GetString ( ) ;
230
- if ( path is null )
231
- continue ;
220
+ if ( ! googleDriveRegValProp . TryGetProperty ( _googleDriveRegValPropPropName , out var googleDriveRegValPropProp ) )
221
+ {
222
+ _logger . LogWarning ( $ "Value from { _googleDriveRegValPropName } did not have property named { _googleDriveRegValPropPropName } ") ;
223
+ return null ;
224
+ }
232
225
233
- if ( ! AddMyDriveToPathAndValidate ( ref path , addMyDriveToPath ) )
234
- {
235
- _logger . LogWarning ( $ "Validation failed for { path } (registry)") ;
236
- continue ;
237
- }
226
+ var path = googleDriveRegValPropProp . GetString ( ) ;
227
+ if ( path is not null )
228
+ return ConvertDriveLetterToPathAndValidate ( ref path ) ? path : null ;
238
229
239
- App . AppModel . GoogleDrivePath = path ;
240
- #if DEBUG
241
- Debug . WriteLine ( $ "In GDCD in registry: App.AppModel.GoogleDrivePath being set to: { path } ") ;
242
- #endif
230
+ _logger . LogWarning ( $ "Could not get string from value from { _googleDriveRegValPropPropName } ") ;
231
+ return null ;
232
+ }
243
233
244
- var iconFile = await GetGoogleDriveIconFileAsync ( ) ;
234
+ /// <summary>
235
+ /// If Google Drive is mounted as a drive, then the path found in the registry will be
236
+ /// *just* the drive letter (e.g. just "G" as opposed to "G:\"), and therefore must be
237
+ /// reformatted as a valid path.
238
+ /// </summary>
239
+ private static bool ConvertDriveLetterToPathAndValidate ( ref string path )
240
+ {
241
+ if ( path . Length > 1 )
242
+ return ValidatePath ( path ) ;
245
243
246
- yield return new CloudProvider ( CloudProviders . GoogleDrive )
247
- {
248
- Name = "Google Drive" ,
249
- SyncFolder = path ,
250
- IconData = iconFile is not null ? await iconFile . ToByteArrayAsync ( ) : null ,
251
- } ;
244
+ DriveInfo driveInfo ;
245
+ try
246
+ {
247
+ driveInfo = new DriveInfo ( path ) ;
248
+ }
249
+ catch ( ArgumentException e )
250
+ {
251
+ _logger . LogWarning ( e , $ "Could not resolve drive letter '{ path } ' to a valid drive.") ;
252
+ return false ;
252
253
}
254
+
255
+ path = driveInfo . RootDirectory . Name ;
256
+ return true ;
257
+ }
258
+
259
+ private static bool ValidatePath ( string path )
260
+ {
261
+ if ( Directory . Exists ( path ) )
262
+ return true ;
263
+ _logger . LogWarning ( $ "Invalid path: { path } ") ;
264
+ return false ;
253
265
}
254
266
255
267
private static async Task < StorageFile ? > GetGoogleDriveIconFileAsync ( )
@@ -264,56 +276,30 @@ public static async IAsyncEnumerable<ICloudProvider> GetGoogleDriveProvidersFrom
264
276
return await FilesystemTasks . Wrap ( ( ) => StorageFile . GetFileFromPathAsync ( iconPath ) . AsTask ( ) ) ;
265
277
}
266
278
267
- private static bool AddMyDriveToPathAndValidate ( ref string path , bool addMyDrive = true )
268
- {
269
- // If Google Drive is mounted as a drive, then the path found in the registry will be
270
- // *just* the drive letter (e.g. just "G" as opposed to "G:\"), and therefore must be
271
- // reformatted as a valid path.
272
- if ( path . Length == 1 )
273
- {
274
- DriveInfo temp ;
275
- try
276
- {
277
- temp = new DriveInfo ( path ) ;
278
- }
279
- catch ( ArgumentException e )
280
- {
281
- _logger . LogWarning ( e , $ "Could not resolve drive letter '{ path } ' to a valid drive.") ;
282
- return false ;
283
- }
284
-
285
- path = temp . RootDirectory . Name ;
286
- }
287
-
288
- if ( addMyDrive )
289
- {
290
- // If `path` contains a shortcut named "My Drive", store its target in `shellFolderBaseFirst`.
291
- // This happens when "My Drive syncing options" is set to "Mirror files".
292
- // TODO: Avoid to use Vanara (#15000)
293
- using var shellFolderBase = ShellFolderExtensions . GetShellItemFromPathOrPIDL ( path ) as ShellFolder ;
294
- var shellFolderBaseFirst = Environment . ExpandEnvironmentVariables ( (
295
- shellFolderBase ? . FirstOrDefault ( si =>
296
- si . Name ? . Equals ( "My Drive" ) ?? false ) as ShellLink ) ? . TargetPath
297
- ?? string . Empty ) ;
279
+ private static bool AddMyDriveToPathAndValidate ( ref string path )
280
+ {
281
+ // If `path` contains a shortcut named "My Drive", store its target in `shellFolderBaseFirst`.
282
+ // This happens when "My Drive syncing options" is set to "Mirror files".
283
+ // TODO: Avoid to use Vanara (#15000)
284
+ using var rootFolder = ShellFolderExtensions . GetShellItemFromPathOrPIDL ( path ) as ShellFolder ;
285
+ var myDriveFolder = Environment . ExpandEnvironmentVariables ( (
286
+ rootFolder ? . FirstOrDefault ( si =>
287
+ si . Name ? . Equals ( "My Drive" ) ?? false ) as ShellLink ) ? . TargetPath
288
+ ?? string . Empty ) ;
298
289
299
290
#if DEBUG
300
- Debug . WriteLine ( "INVALID PATHS LOGGER " ) ;
301
- shellFolderBase ? . ForEach ( si => Debug . WriteLine ( si . Name ) ) ;
291
+ Debug . WriteLine ( "SHELL FOLDER LOGGING " ) ;
292
+ rootFolder ? . ForEach ( si => Debug . WriteLine ( si . Name ) ) ;
302
293
#endif
303
294
304
- if ( ! string . IsNullOrEmpty ( shellFolderBaseFirst ) )
305
- {
306
- path = shellFolderBaseFirst ;
307
- return true ;
308
- }
309
-
310
- path = Path . Combine ( path , "My Drive" ) ;
295
+ if ( ! string . IsNullOrEmpty ( myDriveFolder ) )
296
+ {
297
+ path = myDriveFolder ;
298
+ return true ;
311
299
}
312
300
313
- if ( Directory . Exists ( path ) )
314
- return true ;
315
- _logger . LogWarning ( $ "Invalid Google Drive mount point path: { path } ") ;
316
- return false ;
301
+ path = Path . Combine ( path , "My Drive" ) ;
302
+ return ValidatePath ( path ) ;
317
303
}
318
304
}
319
305
}
0 commit comments