VirtualBox

source: vbox/trunk/src/VBox/Runtime/common/fs/isomaker.cpp@ 67271

Last change on this file since 67271 was 67271, checked in by vboxsync, 8 years ago

post meeting

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.8 KB
Line 
1/* $Id: isomaker.cpp 67271 2017-06-06 13:30:41Z vboxsync $ */
2/** @file
3 * IPRT - ISO Image Maker.
4 */
5
6/*
7 * Copyright (C) 2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#define LOG_GROUP RTLOGGROUP_FS
32#include "internal/iprt.h"
33#include <iprt/fsvfs.h>
34
35#include <iprt/asm.h>
36#include <iprt/assert.h>
37#include <iprt/err.h>
38#include <iprt/file.h>
39#include <iprt/list.h>
40#include <iprt/log.h>
41#include <iprt/mem.h>
42#include <iprt/string.h>
43#include <iprt/vfs.h>
44#include <iprt/formats/iso9660.h>
45
46#include <internal/magics.h>
47
48
49/*********************************************************************************************************************************
50* Defined Constants And Macros *
51*********************************************************************************************************************************/
52/** Asserts valid handle, returns VERR_INVALID_HANDLE if not. */
53#define RTFSISOMAKER_ASSER_VALID_HANDLE_RET(a_pThis) \
54 do { AssertPtrReturn(a_pThis, VERR_INVALID_HANDLE); \
55 AssertPtrReturn((a_pThis)->uMagic == RTFSISOMAKERINT_MAGIC, VERR_INVALID_HANDLE); \
56 } while (0)
57
58/** The sector size. */
59#define RTFSISOMAKER_SECTOR_SIZE _2K
60/** Maximum number of objects. */
61#define RTFSISOMAKER_MAX_OBJECTS _16M
62
63
64/*********************************************************************************************************************************
65* Structures and Typedefs *
66*********************************************************************************************************************************/
67/** Pointer to an ISO maker object name space node. */
68typedef struct RTFSISOMAKERNAME *PRTFSISOMAKERNAME;
69/** Pointer to a common ISO image maker file system object. */
70typedef struct RTFSISOMAKEROBJ *PRTFSISOMAKEROBJ;
71/** Pointer to a ISO maker file object. */
72typedef struct RTFSISOMAKERFILE *PRTFSISOMAKERFILE;
73
74
75/** @name RTFSISOMAKER_NAMESPACE_XXX - Namespace selector.
76 * @{
77 */
78#define RTFSISOMAKERNAMESPACE_ISO_9660 RT_BIT_32(0) /**< The primary ISO-9660 namespace. */
79#define RTFSISOMAKERNAMESPACE_JOLIET RT_BIT_32(1) /**< The joliet namespace. */
80#define RTFSISOMAKERNAMESPACE_UDF RT_BIT_32(2) /**< The UDF namespace. */
81#define RTFSISOMAKERNAMESPACE_HFS RT_BIT_32(3) /**< The HFS namespace */
82#define RTFSISOMAKERNAMESPACE_ALL UINT32_C(0x0000000f) /**< All namespaces. */
83#define RTFSISOMAKERNAMESPACE_VALID_MASK UINT32_C(0x0000000f) /**< Valid namespace bits. */
84/** @} */
85
86
87/**
88 * Filesystem object type.
89 */
90typedef enum RTFSISOMAKEROBJTYPE
91{
92 RTFSISOMAKEROBJTYPE_INVALID = 0,
93 RTFSISOMAKEROBJTYPE_DIR,
94 RTFSISOMAKEROBJTYPE_FILE,
95 //RTFSISOMAKEROBJTYPE_SYMLINK,
96 RTFSISOMAKEROBJTYPE_END
97} RTFSISOMAKEROBJTYPE;
98
99/**
100 * Extra name space information required for directories.
101 */
102typedef struct RTFSISOMAKERNAMEDIR
103{
104 /** The location of the directory data. */
105 uint64_t offDir;
106 /** The size of the directory. */
107 uint32_t cbDir;
108 /** Number of children. */
109 uint32_t cChildren;
110 /** Sorted array of children. */
111 PRTFSISOMAKERNAME *papChildren;
112
113 /** The translate table file. */
114 PRTFSISOMAKERFILE pTransTblFile;
115} RTFSISOMAKERNAMEDIR;
116/** Pointer to directory specfic name space node info. */
117typedef RTFSISOMAKERNAMEDIR *PRTFSISOMAKERNAMEDIR;
118
119
120/**
121 * ISO maker object namespace node.
122 */
123typedef struct RTFSISOMAKERNAME
124{
125 /** Pointer to the file system object. */
126 PRTFSISOMAKEROBJ pObj;
127 /** Pointer to the partent directory, NULL if root dir. */
128 PRTFSISOMAKERNAME pParent;
129
130 /** Pointer to the directory information if this is a directory, NULL if not a
131 * directory. This is allocated together with this structure, so it doesn't need
132 * freeing. */
133 PRTFSISOMAKERNAMEDIR pDir;
134
135 /** The name specified when creating this namespace node. Helps navigating
136 * the namespace when we mangle or otherwise change the names.
137 * Allocated together with of this structure, no spearate free necessary. */
138 const char *pszSpecNm;
139
140 /** Alternative rock ridge name. */
141 char *pszRockRidgeNm;
142 /** Alternative TRANS.TBL name. */
143 char *pszTransNm;
144 /** Length of pszRockRidgeNm. */
145 uint16_t cchRockRidgeNm;
146 /** Length of pszTransNm. */
147 uint16_t cchTransNm;
148
149 /** The depth in the namespace tree of this name. */
150 uint8_t uDepth;
151 /** Set if pszTransNm is allocated separately. */
152 bool fTransNmAlloced : 1;
153 /** Set if pszTransNm is allocated separately. */
154 bool fRockRidgeNmAlloced : 1;
155
156/** @todo more rock ridge info here. */
157
158 /** The name length. */
159 uint16_t cchName;
160 /** The name. */
161 char szName[RT_FLEXIBLE_ARRAY];
162} RTFSISOMAKERNAME;
163
164
165/**
166 * Common base structure for the file system objects.
167 */
168typedef struct RTFSISOMAKEROBJ
169{
170 /** The linear list entry of the image content. */
171 RTLISTNODE Entry;
172 /** The object index. */
173 uint32_t idxObj;
174 /** The type of this object. */
175 RTFSISOMAKEROBJTYPE enmType;
176
177 /** The primary ISO-9660 name space name. */
178 PRTFSISOMAKERNAME pPrimaryName;
179 /** The joliet name space name. */
180 PRTFSISOMAKERNAME pJolietName;
181 /** The UDF name space name. */
182 PRTFSISOMAKERNAME pUdfName;
183 /** The HFS name space name. */
184 PRTFSISOMAKERNAME pHfsName;
185
186} RTFSISOMAKEROBJ;
187
188
189/**
190 * File source type.
191 */
192typedef enum RTFSISOMAKERSRCTYPE
193{
194 RTFSISOMAKERSRCTYPE_INVALID = 0,
195 RTFSISOMAKERSRCTYPE_PATH,
196 RTFSISOMAKERSRCTYPE_VFS_IO_STREAM,
197 RTFSISOMAKERSRCTYPE_END
198} RTFSISOMAKERSRCTYPE;
199
200/**
201 * ISO maker file object.
202 */
203typedef struct RTFSISOMAKERFILE
204{
205 /** The common bit. */
206 RTFSISOMAKEROBJ Core;
207 /** The file data size. */
208 uint64_t cbData;
209 /** Byte offset of the data in the image. */
210 uint64_t offData;
211
212 /** The type of source object. */
213 RTFSISOMAKERSRCTYPE enmSrcType;
214 /** The source data. */
215 union
216 {
217 /** Path to the source file. */
218 const char *pszSrcPath;
219 /** Source I/O stream (or file). */
220 RTVFSIOSTREAM hVfsIoStr;
221 } u;
222} RTFSISOMAKERFILE;
223
224
225/**
226 * ISO maker directory object.
227 *
228 * Unlike files, the allocation info is name space specific and lives in the
229 * corresponding RTFSISOMAKERNAMEDIR structures.
230 */
231typedef struct RTFSISOMAKERDIR
232{
233 /** The common bit. */
234 RTFSISOMAKEROBJ Core;
235} RTFSISOMAKERDIR;
236/** Pointer to an ISO maker directory object. */
237typedef RTFSISOMAKERDIR *PRTFSISOMAKERDIR;
238
239
240
241/**
242 * Instance data for a ISO image maker.
243 */
244typedef struct RTFSISOMAKERINT
245{
246 /** Magic value (RTFSISOMAKERINT_MAGIC). */
247 uint32_t uMagic;
248 /** Reference counter. */
249 uint32_t volatile cRefs;
250
251 /** @name Name space configuration.
252 * @{ */
253 /** Set after we've been fed the first bit of content.
254 * This means that the namespace configuration has been finalized and can no
255 * longer be changed because it's simply too much work to do adjustments
256 * after having started to add files. */
257 bool fSeenContent;
258 /** The ISO level (1-3), default is 3.
259 * @todo support mkisofs level 4 (ISO-9660:1990, version 2). */
260 uint8_t uIsoLevel;
261 /** The ISO rock ridge level: 1 - enabled; 2 - with ER tag.
262 * Linux behaves a little different when seeing the ER tag. */
263 uint8_t uRockRidgeLevel;
264 /** The joliet UCS level (1, 2, or 3), 0 if joliet is not enabled. */
265 uint8_t uJolietLevel;
266 /** The joliet rock ridge level: 1 - enabled; 2 - with ER tag.
267 * @note Nobody seems to do rock ridge with joliet, so this is highly
268 * expermental and here just because we can. */
269 uint8_t uJolietRockRidgeLevel;
270 /** Enables UDF.
271 * @remarks not yet implemented. */
272 bool fUdf;
273 /** Enables HFS
274 * @remarks not yet implemented. */
275 bool fHfs;
276 /** @} */
277
278 /** The root of the primary ISO-9660 name space. */
279 PRTFSISOMAKERNAME pPrimaryIsoRoot;
280 /** The root of the joliet name space. */
281 PRTFSISOMAKERNAME pJolietRoot;
282 /** The root of the UDF name space. */
283 PRTFSISOMAKERNAME pUdfRoot;
284 /** The root of the hybrid HFS name space. */
285 PRTFSISOMAKERNAME pHfsRoot;
286
287 /** The list of objects (RTFSISOMAKEROBJ). */
288 RTLISTANCHOR ObjectHead;
289
290 /** The total image size. */
291 uint64_t cbTotal;
292
293} RTFSISOMAKERINT;
294/** Pointer to an ISO maker instance. */
295typedef RTFSISOMAKERINT *PRTFSISOMAKERINT;
296
297
298/*********************************************************************************************************************************
299* Structures and Typedefs *
300*********************************************************************************************************************************/
301/**
302 * Help for iterating over namespaces.
303 */
304static const struct
305{
306 /** The RTFSISOMAKERNAMESPACE_XXX indicator. */
307 uint32_t fNamespace;
308 /** Offset into RTFSISOMAKERINT of the root member. */
309 uintptr_t offRoot;
310 /** Offset into RTFSISOMAKERNAMESPACE of the name member. */
311 uintptr_t offName;
312 /** Namespace name for debugging purposes. */
313 const char *pszName;
314} g_aRTFsIosNamespaces[] =
315{
316 { RTFSISOMAKERNAMESPACE_ISO_9660, RT_OFFSETOF(RTFSISOMAKERINT, pPrimaryIsoRoot), RT_OFFSETOF(RTFSISOMAKEROBJ, pPrimaryName), "iso-9660" },
317 { RTFSISOMAKERNAMESPACE_JOLIET, RT_OFFSETOF(RTFSISOMAKERINT, pJolietRoot), RT_OFFSETOF(RTFSISOMAKEROBJ, pJolietName), "joliet" },
318 { RTFSISOMAKERNAMESPACE_UDF, RT_OFFSETOF(RTFSISOMAKERINT, pUdfRoot), RT_OFFSETOF(RTFSISOMAKEROBJ, pUdfName), "udf" },
319 { RTFSISOMAKERNAMESPACE_HFS, RT_OFFSETOF(RTFSISOMAKERINT, pHfsRoot), RT_OFFSETOF(RTFSISOMAKEROBJ, pHfsName), "hfs" },
320};
321
322
323/**
324 * Creates an ISO creator instance.
325 *
326 * @returns IPRT status code.
327 * @param phIsoMaker Where to return the handle to the new ISO maker.
328 */
329RTDECL(int) RTFsIsoMakerCreate(PRTFSISOMAKER phIsoMaker)
330{
331 PRTFSISOMAKERINT pThis = (PRTFSISOMAKERINT)RTMemAllocZ(sizeof(*pThis));
332 if (pThis)
333 {
334 pThis->uMagic = RTFSISOMAKERINT_MAGIC;
335 pThis->cRefs = 1;
336 //pThis->fSeenContent = false;
337 pThis->uIsoLevel = 3;
338 pThis->uRockRidgeLevel = 1;
339 pThis->uJolietLevel = 3;
340 //pThis->uJolietRockRidgeLevel = 0;
341 RTListInit(&pThis->ObjectHead);
342 pThis->cbTotal = _32K /* The system area size. */
343 + RTFSISOMAKER_SECTOR_SIZE /* Primary volume descriptor. */
344 + RTFSISOMAKER_SECTOR_SIZE /* Secondary volume descriptor for joliet. */
345 + RTFSISOMAKER_SECTOR_SIZE /* Terminator descriptor. */;
346 *phIsoMaker = pThis;
347 return VINF_SUCCESS;
348 }
349 return VERR_NO_MEMORY;
350}
351
352
353/**
354 * Recursively destroy a name space tree.
355 * @param pRoot The root node.
356 */
357static void rtFsIsoMakerDestroyTree(PRTFSISOMAKERNAME pRoot)
358{
359 Assert(!pRoot->pParent);
360 PRTFSISOMAKERNAME pCur = pRoot;
361
362 for (;;)
363 {
364 if ( pCur->pDir
365 && pCur->pDir->cChildren)
366 pCur = pCur->pDir->papChildren[pCur->pDir->cChildren - 1];
367 else
368 {
369 RTMemFree(pCur->pszRockRidgeNm);
370 pCur->pszRockRidgeNm = NULL;
371 RTMemFree(pCur->pszTransNm);
372 pCur->pszTransNm = NULL;
373 PRTFSISOMAKERNAME pNext = pCur->pParent;
374 RTMemFree(pCur);
375
376 /* Unlink from parent, we're the last entry. */
377 if (pNext)
378 {
379 Assert(pNext->pDir->cChildren > 0);
380 pNext->pDir->cChildren--;
381 Assert(pNext->pDir->papChildren[pNext->pDir->cChildren] == pCur);
382 pNext->pDir->papChildren[pNext->pDir->cChildren] = NULL;
383 pCur = pNext;
384 }
385 else
386 {
387 Assert(pRoot == pCur);
388 break;
389 }
390 }
391 }
392}
393
394
395/**
396 * Destroys an ISO maker instance.
397 *
398 * @param pThis The ISO maker instance to destroy.
399 */
400static void rtFsIsoMakerDestroy(PRTFSISOMAKERINT pThis)
401{
402 rtFsIsoMakerDestroyTree(pThis->pPrimaryIsoRoot);
403 rtFsIsoMakerDestroyTree(pThis->pJolietRoot);
404 rtFsIsoMakerDestroyTree(pThis->pUdfRoot);
405 rtFsIsoMakerDestroyTree(pThis->pHfsRoot);
406
407 PRTFSISOMAKEROBJ pCur;
408 PRTFSISOMAKEROBJ pNext;
409 RTListForEachSafe(&pThis->ObjectHead, pCur, pNext, RTFSISOMAKEROBJ, Entry)
410 {
411 RTListNodeRemove(&pCur->Entry);
412 RTMemFree(pCur);
413 }
414}
415
416
417/**
418 * Retains a references to an ISO maker instance.
419 *
420 * @returns New reference count on success, UINT32_MAX if invalid handle.
421 * @param hIsoMaker The ISO maker handle.
422 */
423RTDECL(uint32_t) RTFsIsoMakerRetain(RTFSISOMAKER hIsoMaker)
424{
425 PRTFSISOMAKERINT pThis = hIsoMaker;
426 AssertPtrReturn(pThis, UINT32_MAX);
427 AssertReturn(pThis->uMagic == RTFSISOMAKERINT_MAGIC, UINT32_MAX);
428 uint32_t cRefs = ASMAtomicIncU32(&pThis->cRefs);
429 Assert(cRefs > 1);
430 Assert(cRefs < _64K);
431 return cRefs;
432}
433
434
435/**
436 * Releases a references to an ISO maker instance.
437 *
438 * @returns New reference count on success, UINT32_MAX if invalid handle.
439 * @param hIsoMaker The ISO maker handle. NIL is ignored.
440 */
441RTDECL(uint32_t) RTFsIsoMakerRelease(RTFSISOMAKER hIsoMaker)
442{
443 PRTFSISOMAKERINT pThis = hIsoMaker;
444 uint32_t cRefs;
445 if (pThis == NIL_RTFSISOMAKER)
446 cRefs = 0;
447 else
448 {
449 AssertPtrReturn(pThis, UINT32_MAX);
450 AssertReturn(pThis->uMagic == RTFSISOMAKERINT_MAGIC, UINT32_MAX);
451 cRefs = ASMAtomicDecU32(&pThis->cRefs);
452 Assert(cRefs < _64K);
453 if (!cRefs)
454 rtFsIsoMakerDestroy(pThis);
455 }
456 return cRefs;
457}
458
459
460/**
461 * Sets the ISO-9660 level.
462 *
463 * @returns IPRT status code
464 * @param hIsoMaker The ISO maker handle.
465 * @param uIsoLevel The level, 1-3.
466 */
467RTDECL(int) RTFsIsoMakerSetIso9660Level(RTFSISOMAKER hIsoMaker, uint8_t uIsoLevel)
468{
469 PRTFSISOMAKERINT pThis = hIsoMaker;
470 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
471 AssertReturn(uIsoLevel <= 3, VERR_INVALID_PARAMETER);
472 AssertReturn(uIsoLevel > 0, VERR_INVALID_PARAMETER); /* currently not possible to disable this */
473 AssertReturn(!pThis->fSeenContent, VERR_WRONG_ORDER);
474
475 pThis->uIsoLevel = uIsoLevel;
476 return VINF_SUCCESS;
477}
478
479
480/**
481 * Sets the joliet level.
482 *
483 * @returns IPRT status code
484 * @param hIsoMaker The ISO maker handle.
485 * @param uJolietLevel The joliet UCS-2 level 1-3, or 0 to disable
486 * joliet.
487 */
488RTDECL(int) RTFsIsoMakerSetJolietUcs2Level(RTFSISOMAKER hIsoMaker, uint8_t uJolietLevel)
489{
490 PRTFSISOMAKERINT pThis = hIsoMaker;
491 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
492 AssertReturn(uJolietLevel <= 3, VERR_INVALID_PARAMETER);
493 AssertReturn(!pThis->fSeenContent, VERR_WRONG_ORDER);
494
495 if (pThis->uJolietLevel != uJolietLevel)
496 {
497 if (uJolietLevel == 0)
498 pThis->cbTotal -= RTFSISOMAKER_SECTOR_SIZE;
499 else if (pThis->uJolietLevel == 0)
500 pThis->cbTotal += RTFSISOMAKER_SECTOR_SIZE;
501 pThis->uJolietLevel = uJolietLevel;
502 }
503 return VINF_SUCCESS;
504}
505
506
507/**
508 * Sets the rock ridge support level (on the primary ISO-9660 namespace).
509 *
510 * @returns IPRT status code
511 * @param hIsoMaker The ISO maker handle.
512 * @param uLevel 0 if disabled, 1 to just enable, 2 to enable and
513 * write the ER tag.
514 */
515RTDECL(int) RTFsIsoMakerSetRockRidgeLevel(RTFSISOMAKER hIsoMaker, uint8_t uLevel)
516{
517 PRTFSISOMAKERINT pThis = hIsoMaker;
518 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
519 AssertReturn(!pThis->fSeenContent, VERR_WRONG_ORDER);
520 AssertReturn(uLevel <= 2, VERR_INVALID_PARAMETER);
521
522 pThis->uRockRidgeLevel = uLevel;
523 return VINF_SUCCESS;
524}
525
526
527/**
528 * Sets the rock ridge support level on the joliet namespace (experimental).
529 *
530 * @returns IPRT status code
531 * @param hIsoMaker The ISO maker handle.
532 * @param uLevel 0 if disabled, 1 to just enable, 2 to enable and
533 * write the ER tag.
534 */
535RTDECL(int) RTFsIsoMakerSetJolietRockRidgeLevel(RTFSISOMAKER hIsoMaker, uint8_t uLevel)
536{
537 PRTFSISOMAKERINT pThis = hIsoMaker;
538 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
539 AssertReturn(!pThis->fSeenContent, VERR_WRONG_ORDER);
540 AssertReturn(uLevel <= 2, VERR_INVALID_PARAMETER);
541
542 pThis->uJolietRockRidgeLevel = uLevel;
543 return VINF_SUCCESS;
544}
545
546
547/*
548 *
549 * Object level config
550 * Object level config
551 * Object level config
552 *
553 */
554
555
556DECL_NO_INLINE(static, PRTFSISOMAKEROBJ) rtFsIsoMakerIndexToObj(PRTFSISOMAKERINT pThis, uint32_t idxObj)
557{
558 PRTFSISOMAKEROBJ pObj;
559 RTListForEachReverse(&pThis->ObjectHead, pObj, RTFSISOMAKEROBJ, Entry)
560 {
561 if (pObj->idxObj == idxObj)
562 return pObj;
563 }
564 return NULL;
565}
566
567
568DECLINLINE(PRTFSISOMAKEROBJ) rtFsIsoMakerIndexToObj(PRTFSISOMAKERINT pThis, uint32_t idxObj)
569{
570 PRTFSISOMAKEROBJ pObj = RTListGetLast(&pThis->ObjectHead, RTFSISOMAKEROBJ, Entry);
571 if (!pObj || RT_LIKELY(pObj->idxObj == idxObj))
572 return pObj;
573 return rtFsIsoMakerIndexToObjSlow(pThis, idxObj)
574}
575
576
577static int rtTFsIsoMakerObjSetPathInOne(RTFSISOMAKER hIsoMaker, uint32_t idxEntry,
578 uint32_t fNamespace, const char *pszPath)
579{
580
581}
582
583
584/**
585 * Sets the path (name) of an object in the selected namespaces.
586 *
587 * The name will be transformed as necessary.
588 *
589 * The initial implementation does not allow this function to be called more
590 * than once on an object.
591 *
592 * @returns IPRT status code.
593 * @param hIsoMaker The ISO maker handle.
594 * @param idxObj The configuration index of to name.
595 * @param fNamespaces The namespaces to apply the path to
596 * (RTFSISOMAKERNAMESPACE_XXX).
597 * @param pszPath The ISO-9660 path.
598 */
599RTDECL(int) RTFsIsoMakerObjSetPath(RTFSISOMAKER hIsoMaker, uint32_t idxObj, uint32_t fNamespaces, const char *pszPath)
600{
601 /*
602 * Validate and translate input.
603 */
604 PRTFSISOMAKERINT pThis = hIsoMaker;
605 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
606 AssertReturn(!(fNamespaces & ~RTFSISOMAKERNAMESPACE_VALID_MASK), VERR_INVALID_FLAGS);
607 AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
608 AssertReturn(RTPATH_IS_SLASH(pszPath == '/'), VERR_INVALID_NAME);
609 PRTFSISOMAKEROBJ pObj = rtFsIsoMakerIndexToObj(pThis, idxObj);
610 AssertReturn(pObj, VERR_OUT_OF_RANGE);
611
612 /*
613 * Execute requested actions.
614 */
615 int rc = VINF_SUCCESS;
616 for (uint32_t i = 0; i < RT_ELEMENTS(g_aRTFsIosNamespaces); i++)
617 if (fNamespace & g_aRTFsIosNamespaces[i].fNamespace)
618 {
619 int rc2 = rtTFsIsoMakerObjSetPathInOne(pThis, pEntry, g_aRTFsIosNamespaces[i].fNamespace, pszPath,
620 (PRTFSISOMAKERNAME *)((uintptr_t)pThis + g_aRTFsIosNamespaces[i].offRoot),
621 (PRTFSISOMAKERNAMESPACE *)((uintptr_t)pEntry + g_aRTFsIosNamespaces[i].offName));
622 if (RT_SUCCESS(rc2) || RT_FAILURE(rc))
623 continue;
624 rc = rc2;
625 }
626 return rc;
627}
628
629
630/**
631 * Initalizes the common part of a file system object and links it into global
632 * chain.
633 *
634 * @returns IPRT status code
635 * @param pThis The ISO maker instance.
636 * @param pObj The common object.
637 * @param enmType The object type.
638 */
639static void rtFsIsoMakerInitCommonObj(PRTFSISOMAKERINT pThis, PRTFSISOMAKEROBJ pObj, RTFSISOMAKEROBJTYPE enmType)
640{
641 AssertReturn(pThis->cObjects < RTFSISOMAKER_MAX_OBJECTS, VERR_OUT_OF_RANGE);
642 pObj->enmType = enmType;
643 pObj->pPrimaryName = NULL;
644 pObj->pJolietName = NULL;
645 pObj->pUdfName = NULL;
646 pObj->pHfsName = NULL;
647 pObj->idxObj = pThis->cObjects++;
648 RTListAppend(&pThis->ObjectHead, &pObj->Entry);
649 return VINF_SUCCESS;
650}
651
652
653/**
654 * Adds an unnamed directory to the image.
655 *
656 * The directory must explictly be entered into the desired namespaces.
657 *
658 * @returns IPRT status code
659 * @param hIsoMaker The ISO maker handle.
660 * @param pidxObj Where to return the configuration index of the
661 * directory.
662 * @sa RTFsIsoMakerAddDir, RTFsIsoMakerObjSetPath
663 */
664RTDECL(int) RTFsIsoMakerAddUnnamedDir(RTFSISOMAKER hIsoMaker, uint32_t *pidxObj)
665{
666 PRTFSISOMAKERINT pThis = hIsoMaker;
667 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
668 AssertPtrReturn(pidxObj, VERR_INVALID_POINTER);
669
670 PRTFSISOMAKERDIR pDir = (PRTFSISOMAKERDIR)RTMemAllocZ(sizeof(*pDir));
671 AssertReturn(pDir, VERR_NO_MEMORY);
672 int rc = rtFsIsoMakerInitCommonObj(&pDir->Core, RTFSISOMAKEROBJTYPE_DIR);
673 if (RT_SUCCESS(rc))
674 {
675 *pidxObj = pObj->idxObj;
676 return VINF_SUCCESS;
677 }
678 RTMemFree(pDir);
679 return rc;
680}
681
682
683/**
684 * Adds a directory to the image in all namespaces and default attributes.
685 *
686 * @returns IPRT status code
687 * @param hIsoMaker The ISO maker handle.
688 * @param pszDir The path (UTF-8) to the directory in the ISO.
689 *
690 * @param pidxObj Where to return the configuration index of the
691 * directory. Optional.
692 * @sa RTFsIsoMakerAddUnnamedDir, RTFsIsoMakerObjSetPath
693 */
694RTDECL(int) RTFsIsoMakerAddDir(RTFSISOMAKER hIsoMaker, const char *pszDir, uint32_t *pidxObj)
695{
696 PRTFSISOMAKERINT pThis = hIsoMaker;
697 RTFSISOMAKER_ASSER_VALID_HANDLE_RET(pThis);
698 AssertPtrReturn(pszDir, VERR_INVALID_POINTER);
699 AssertReturn(RTPATH_IS_SLASH(pszPath == '/'), VERR_INVALID_NAME);
700
701 uint32_t idxObj;
702 int rc = RTFsIsoMakerAddUnnamedDir(hIsoMaker, &idxObj);
703 if (RT_SUCCESS(rc))
704 {
705 rc = RTFsIsoMakerObjSetPath(hIsoMaker, idxObj, RTFSISOMAKERNAMESPACE_ALL);
706 if (RT_SUCCESS(rc))
707 {
708 if (pidxObj)
709 *pidxObj = idxObj;
710 }
711 /** @todo else: back out later? */
712 }
713 return rc;
714}
715
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette