@@ -285,10 +285,45 @@ int wim_read ( struct vdisk_file *file, struct wim_header *header,
285
285
return 0 ;
286
286
}
287
287
288
+ /**
289
+ * Get number of images
290
+ *
291
+ * @v file Virtual file
292
+ * @v header WIM header
293
+ * @v count Count of images to fill in
294
+ * @ret rc Return status code
295
+ */
296
+ int wim_count ( struct vdisk_file * file , struct wim_header * header ,
297
+ unsigned int * count ) {
298
+ struct wim_lookup_entry entry ;
299
+ size_t offset ;
300
+ int rc ;
301
+
302
+ /* Count metadata entries */
303
+ for ( offset = 0 ; ( offset + sizeof ( entry ) ) <= header -> lookup .len ;
304
+ offset += sizeof ( entry ) ) {
305
+
306
+ /* Read entry */
307
+ if ( ( rc = wim_read ( file , header , & header -> lookup , & entry ,
308
+ offset , sizeof ( entry ) ) ) != 0 )
309
+ return rc ;
310
+
311
+ /* Check for metadata entries */
312
+ if ( entry .resource .zlen__flags & WIM_RESHDR_METADATA ) {
313
+ (* count )++ ;
314
+ DBG2 ( "...found image %d metadata at +%#zx\n" ,
315
+ * count , offset );
316
+ }
317
+ }
318
+
319
+ return 0 ;
320
+ }
321
+
288
322
/**
289
323
* Get WIM image metadata
290
324
*
291
325
* @v file Virtual file
326
+ * @v header WIM header
292
327
* @v index Image index, or 0 to use boot image
293
328
* @v meta Metadata to fill in
294
329
* @ret rc Return status code
@@ -318,8 +353,8 @@ int wim_metadata ( struct vdisk_file *file, struct wim_header *header,
318
353
/* Look for our target entry */
319
354
if ( entry .resource .zlen__flags & WIM_RESHDR_METADATA ) {
320
355
found ++ ;
321
- DBG ( "...found image %d metadata at +%#zx\n" ,
322
- found , offset );
356
+ DBG2 ( "...found image %d metadata at +%#zx\n" ,
357
+ found , offset );
323
358
if ( found == index ) {
324
359
memcpy ( meta , & entry .resource ,
325
360
sizeof ( * meta ) );
@@ -339,23 +374,23 @@ int wim_metadata ( struct vdisk_file *file, struct wim_header *header,
339
374
* @v file Virtual file
340
375
* @v header WIM header
341
376
* @v meta Metadata
342
- * @v offset Directory offset
343
377
* @v name Name
378
+ * @v offset Directory offset (will be updated)
344
379
* @v direntry Directory entry to fill in
345
380
* @ret rc Return status code
346
381
*/
347
382
static int wim_direntry ( struct vdisk_file * file , struct wim_header * header ,
348
- struct wim_resource_header * meta , size_t offset ,
349
- const wchar_t * name ,
383
+ struct wim_resource_header * meta ,
384
+ const wchar_t * name , size_t * offset ,
350
385
struct wim_directory_entry * direntry ) {
351
386
wchar_t name_buf [ wcslen ( name ) + 1 /* NUL */ ];
352
387
int rc ;
353
388
354
389
/* Search directory */
355
- for ( ; ; offset += direntry -> len ) {
390
+ for ( ; ; * offset += direntry -> len ) {
356
391
357
392
/* Read length field */
358
- if ( ( rc = wim_read ( file , header , meta , direntry , offset ,
393
+ if ( ( rc = wim_read ( file , header , meta , direntry , * offset ,
359
394
sizeof ( direntry -> len ) ) ) != 0 )
360
395
return rc ;
361
396
@@ -366,7 +401,7 @@ static int wim_direntry ( struct vdisk_file *file, struct wim_header *header,
366
401
}
367
402
368
403
/* Read fixed-length portion of directory entry */
369
- if ( ( rc = wim_read ( file , header , meta , direntry , offset ,
404
+ if ( ( rc = wim_read ( file , header , meta , direntry , * offset ,
370
405
sizeof ( * direntry ) ) ) != 0 )
371
406
return rc ;
372
407
@@ -376,7 +411,7 @@ static int wim_direntry ( struct vdisk_file *file, struct wim_header *header,
376
411
377
412
/* Read name */
378
413
if ( ( rc = wim_read ( file , header , meta , & name_buf ,
379
- ( offset + sizeof ( * direntry ) ),
414
+ ( * offset + sizeof ( * direntry ) ),
380
415
sizeof ( name_buf ) ) ) != 0 )
381
416
return rc ;
382
417
@@ -390,23 +425,21 @@ static int wim_direntry ( struct vdisk_file *file, struct wim_header *header,
390
425
}
391
426
392
427
/**
393
- * Get file resource
428
+ * Get directory entry for a path
394
429
*
395
430
* @v file Virtual file
396
431
* @v header WIM header
397
432
* @v meta Metadata
398
- * @v path Path to file
399
- * @v resource File resource to fill in
433
+ * @v path Path to file/directory
434
+ * @v offset Directory entry offset to fill in
435
+ * @v direntry Directory entry to fill in
400
436
* @ret rc Return status code
401
437
*/
402
- int wim_file ( struct vdisk_file * file , struct wim_header * header ,
438
+ int wim_path ( struct vdisk_file * file , struct wim_header * header ,
403
439
struct wim_resource_header * meta , const wchar_t * path ,
404
- struct wim_resource_header * resource ) {
440
+ size_t * offset , struct wim_directory_entry * direntry ) {
405
441
wchar_t path_copy [ wcslen ( path ) + 1 /* WNUL */ ];
406
442
struct wim_security_header security ;
407
- struct wim_directory_entry direntry ;
408
- struct wim_lookup_entry entry ;
409
- size_t offset ;
410
443
wchar_t * name ;
411
444
wchar_t * next ;
412
445
int rc ;
@@ -417,22 +450,48 @@ int wim_file ( struct vdisk_file *file, struct wim_header *header,
417
450
return rc ;
418
451
419
452
/* Get root directory offset */
420
- offset = ( ( security .len + sizeof ( uint64_t ) - 1 ) &
421
- ~( sizeof ( uint64_t ) - 1 ) );
453
+ direntry -> subdir = ( ( security .len + sizeof ( uint64_t ) - 1 ) &
454
+ ~( sizeof ( uint64_t ) - 1 ) );
422
455
423
456
/* Find directory entry */
424
457
name = memcpy ( path_copy , path , sizeof ( path_copy ) );
425
458
do {
426
459
next = wcschr ( name , L'\\' );
427
460
if ( next )
428
461
* next = L'\0' ;
429
- if ( ( rc = wim_direntry ( file , header , meta , offset , name ,
430
- & direntry ) ) != 0 )
462
+ * offset = direntry -> subdir ;
463
+ if ( ( rc = wim_direntry ( file , header , meta , name , offset ,
464
+ direntry ) ) != 0 )
431
465
return rc ;
432
- offset = direntry .subdir ;
433
466
name = ( next + 1 );
434
467
} while ( next );
435
468
469
+ return 0 ;
470
+ }
471
+
472
+ /**
473
+ * Get file resource
474
+ *
475
+ * @v file Virtual file
476
+ * @v header WIM header
477
+ * @v meta Metadata
478
+ * @v path Path to file
479
+ * @v resource File resource to fill in
480
+ * @ret rc Return status code
481
+ */
482
+ int wim_file ( struct vdisk_file * file , struct wim_header * header ,
483
+ struct wim_resource_header * meta , const wchar_t * path ,
484
+ struct wim_resource_header * resource ) {
485
+ struct wim_directory_entry direntry ;
486
+ struct wim_lookup_entry entry ;
487
+ size_t offset ;
488
+ int rc ;
489
+
490
+ /* Find directory entry */
491
+ if ( ( rc = wim_path ( file , header , meta , path , & offset ,
492
+ & direntry ) ) != 0 )
493
+ return rc ;
494
+
436
495
/* File matching file entry */
437
496
for ( offset = 0 ; ( offset + sizeof ( entry ) ) <= header -> lookup .len ;
438
497
offset += sizeof ( entry ) ) {
@@ -455,3 +514,34 @@ int wim_file ( struct vdisk_file *file, struct wim_header *header,
455
514
DBG ( "Cannot find file %ls\n" , path );
456
515
return -1 ;
457
516
}
517
+
518
+ /**
519
+ * Get length of a directory
520
+ *
521
+ * @v file Virtual file
522
+ * @v header WIM header
523
+ * @v meta Metadata
524
+ * @v offset Directory offset
525
+ * @v len Directory length to fill in (excluding terminator)
526
+ * @ret rc Return status code
527
+ */
528
+ int wim_dir_len ( struct vdisk_file * file , struct wim_header * header ,
529
+ struct wim_resource_header * meta , size_t offset ,
530
+ size_t * len ) {
531
+ struct wim_directory_entry direntry ;
532
+ int rc ;
533
+
534
+ /* Search directory */
535
+ for ( * len = 0 ; ; * len += direntry .len ) {
536
+
537
+ /* Read length field */
538
+ if ( ( rc = wim_read ( file , header , meta , & direntry ,
539
+ ( offset + * len ),
540
+ sizeof ( direntry .len ) ) ) != 0 )
541
+ return rc ;
542
+
543
+ /* Check for end of this directory */
544
+ if ( ! direntry .len )
545
+ return 0 ;
546
+ }
547
+ }
0 commit comments