UDF_API.c
上传用户:super_houu
上传日期:2008-09-21
资源大小:4099k
文件大小:122k
源码类别:

DVD

开发平台:

Others

  1. /****************************************************************************************
  2.  *  Copyright (c) 2002 ZORAN Corporation, All Rights Reserved
  3.  *  THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
  4.  *
  5.  *  File: $Workfile: UDF_API.c $             
  6.  *
  7.  * Description:
  8.  * ============
  9.  * 
  10.  * 
  11.  * Log:
  12.  * ====
  13.  * $Revision: 12 $
  14.  * Last Modified by $Author: Mikex $ at $Modtime: 04-03-20 21:00 $ 
  15.  ****************************************************************************************
  16.  * Updates:
  17.  ****************************************************************************************
  18.  * $Log: /I76/I76_Common/I76_Reference/Playcore/FileSys/UDF/UDF_API.c $
  19.  * 
  20.  * 12    04-03-20 21:00 Mikex
  21.  * Cut the file name longer than 128 bytes.
  22.  * example: if the file name length is 130
  23.  * origenal: abc...xyz.mp3
  24.  * before:   abc...xyz.m
  25.  * now:       abc...x.mp3
  26.  * 
  27.  * 11    12/22/03 7:52p Leslie
  28.  * Allow the file length is zero, and don't return false.
  29.  * 
  30.  * 10    11/19/03 10:24a Leslie
  31.  * Convert the file ID lower-case to upper-case to compare.
  32.  * signature: MikeX_1119_2003
  33.  * 
  34.  * 9     11/07/03 5:57a Leslie
  35.  * changed the search BEA01 identifier mode
  36.  * MikeX_1105_2003
  37.  * 
  38.  * 8     03-03-31 16:46 Hannahh
  39.  * To clean the warnings
  40.  * 
  41.  * 7     2/07/03 10:45p Tomasp
  42.  * - changed SW feature selection to compilation switch
  43.  * 
  44.  * 6     03-01-10 12:20 Leslie
  45.  * Add builtin unicode support
  46.  * 
  47.  * 4     4/06/02 15:30 Nirm
  48.  * - Fixed a bug in _initializeUDF102(): Partition-Size is expressed in
  49.  * Sectors, not Bytes.
  50.  * 
  51.  * 3     9/05/02 16:16 Nirm
  52.  * - Expanded UDF_getDVDFileInfo() functionality, to increase efficiency.
  53.  * 
  54.  * 2     23/04/02 9:30 Nirm
  55.  * - Added dependency in "Config.h".
  56.  * 
  57.  * 1     30/01/02 18:12 Nirm
  58.  ****************************************************************************************/
  59. /////////////////////////////////////////////////////////////////////////////
  60. // UDF_API.c - Implementation of the UDF-2.00 File-System For DVD Players
  61. //
  62. // Author: Nir Milstein
  63. #include "Config.h" // Global Configuration - do not remove!
  64. #ifdef FILESYSTEM_SUPPORT_UDF
  65. #ifdef _DEBUG
  66. #undef IFTRACE
  67. #define IFTRACE if (gTraceFileSys)
  68. #include "DebugDbgMain.h"
  69. #endif
  70. #include "Includemath-macro.h"
  71. #include "PlaycoreFileSysFileSystem_Impl.h"
  72. #include "PlaycoreFileSysUDFUDF_API.h"
  73. #include "PlaycoreFileSysUDFECMA167.h"
  74. #include "PlaycoreFileSysUDFUDF_102.h"
  75. #include "PlaycoreFileSysUDFUDF_200.h"
  76. #include "PlaycoreAuxCacheAuxCache.h"
  77. #include "PlaycoreScPadscmgr.h"
  78. #include "PlaycoreCoremaincoregdef.h"
  79. #include "PlaycoreFileSysFileSystem.h"
  80. #ifdef DVD_VR_SUPPORT
  81. #include "PlaycoreFileSysUDFdvd_vr.h"
  82. #include "PlaycoreDataStructuresArray.h"
  83. #include "Drivedrv_api.h"
  84. #include "KernelEventDef.h"
  85. #include "PlaycoreNav_VrVr_nm.h"
  86. #include "PlaycoreScPadScllmgr.h"
  87. #endif
  88. /////////////////////////////////////////////////////////////////////////////
  89. // Constants
  90. #define DIRECTORY_FILEIDLIST_SZ 256
  91. #define FILE_EXTENT_LENGTH               0xFFFFFFFFUL
  92. /////////////////////////////////////////////////////////////////////////////
  93. // Macros
  94. #ifdef MOTOROLA
  95. #define LE_WORD(wLittleEndian) (WORD)((wLittleEndian << 8) | (wLittleEndian >> 8))
  96. #define LE_DWORD(dwLittleEndian) (DWORD)((dwLittleEndian >> 24) | 
  97.  ((dwLittleEndian >> 8) & 0xFF00) | 
  98.  ((dwLittleEndian & 0xFF00) << 8) | 
  99.  ((dwLittleEndian & 0xFF) << 24))
  100. #else
  101. #define LE_WORD(wLittleEndian) (WORD)wLittleEndian
  102. #define LE_DWORD(dwLittleEndian) (DWORD)dwLittleEndian
  103. #endif //MOTOROLA
  104. /////////////////////////////////////////////////////////////////////////////
  105. // Globals and Singletons
  106. /*
  107. //static struct UDFInfo_TAG {
  108. typedef struct {
  109. // Revision Number
  110. UINT16 uRevision;
  111. // Session information
  112. DWORD dwSessionStartLBN;
  113. // Volume information
  114. DWORD dwLBA_Offset;
  115. DWORD dwMainPartitionLocation;
  116. // Short_ad sadMainPartitionUnallocSpaceBitmap;
  117. #ifdef UDF_SUPPORT_UDF201
  118. BOOL bUseSparingManagement;
  119. struct SparingTable *pMainPartitionSparingTable;
  120. UINT16 uSparingPacketLength;
  121. #endif //UDF_SUPPORT_UDF201
  122. DWORD dwRootDirICB;
  123. DWORD dwCurrDirICB;
  124. // Current Working-Directory storage
  125. BOOL  bCWDStored;
  126. DWORD dwCWDStorage;
  127. }UDFInfo_TAG;// g_UDFInfo;
  128. */
  129. UDFInfo_TAG * g_pUDFInfo;
  130. #ifdef DVD_VR_SUPPORT
  131. DWORD g_DVDVR_SparingTableSize=0;
  132. CONST DWORD g_DVDVR_SpringTableAddr=((DWORD)SC_BASE_ADDR>>1) + ((DWORD)SC_DVDVR_NAV_ADDR);
  133. #endif
  134. #define IS_SHORT_ALLOC_DESC(pEntry) (ICB_FLAGS_AD_SHORT== (pEntry->icbTag.wFlags & ICB_FLAGS_ALLOC_MASK))
  135. #define IS_LONG_ALLOC_DESC(pEntry)   (ICB_FLAGS_AD_LONG== (pEntry->icbTag.wFlags & ICB_FLAGS_ALLOC_MASK))
  136. #define IS_EXTENDED_ALLOC_DESC(pEntry)   (ICB_FLAGS_AD_EXTENDED== (pEntry->icbTag.wFlags & ICB_FLAGS_ALLOC_MASK))
  137. #define IS_IN_ICB_ALLOC_DESC(pEntry) (ICB_FLAGS_AD_IN_ICB== (pEntry->icbTag.wFlags & ICB_FLAGS_ALLOC_MASK))
  138. /////////////////////////////////////////////////////////////////////////////
  139. // Internal Structures / Types
  140. typedef struct UDF_DirectorySearchInfo_TAG {
  141. // Directory Location and Size related
  142. DWORD dwDirICB; // Location of the Directory
  143. DWORD dwDirectorySize; // In Bytes
  144. // Search Criteria related
  145. LPWSTR pszFileID; // The Pattern/Name to search for
  146. UINT8  uFileCharacteristicsMask; // A Mask to apply to File-Characteristics
  147. UINT8  uFileCharacteristics; // The required File-Characteristics
  148. // Search Status/Position related
  149. WORD   hFileIDDescList;
  150. UINT32 cbDescListOffset; // In Bytes from the Directory's start
  151. UINT32 cbCurrDescOffset; // In Bytes from the Directory's start
  152. } DirectorySearchInfo;
  153. /////////////////////////////////////////////////////////////////////////////
  154. // Forward-Declarations of Private-Services
  155. static BOOL _initializeUDF102(void);
  156. static BOOL _initializeUDF200(void);
  157. static DWORD _absoluteLBA(DWORD dwMainPartitionLBA);
  158. static UINT16 _findFirstFileIDDesc(LPCWSTR i_pszFileID, UINT8 uFileCharacteristicsMask, 
  159.    UINT8 uFileCharacteristics, 
  160.    struct FileIDDesc **o_pFileIDDescPtr);
  161. static BOOL _fileIDDescList_getBytes(DirectorySearchInfo *io_pInfo, UINT32 cbOffset, 
  162.  UINT8 cbBytesCnt, BYTE *o_pDestBuffer);
  163. static BOOL _findNextFileIDDesc(UINT16 uSearchID, struct FileIDDesc **o_pFileIDDescPtr);
  164. static BOOL _findClose(UINT16 uSearchID);
  165. static BOOL _getFileAttributes(const struct FileIDDesc *i_pFileIDDesc,
  166.    FindData *o_pFindData);
  167. LPWSTR _str2wcs(LPCSTR pszSource, LPWSTR pszDest, unsigned int cbDestSize);
  168. /////////////////////////////////////////////////////////////////////////////
  169. // Detection
  170. /////////////////////////////////////////////////////////////////////////////
  171. // UDF_isResident()
  172. //
  173. // Description: Tests a given LBN to detect whether or not an instance of
  174. // UDF is resident on the Medium at that location.
  175. //
  176. // Input: dwCandidateLBN - The candidate LBN to test.
  177. // Output: o_pUDFRevision - Receives the Revision of the found instance.
  178. // In/Out: None
  179. // Return: TRUE if a UDF instance was found at the specified LBN;
  180. // FALSE otherwise.
  181. //
  182. // Remarks:
  183. // The method assumes that the given LBN is the beginning of a
  184. // Volume-Recognition Sequence, and searches for the Standard-ID associated
  185. // with UDF.
  186. BOOL UDF_isResident(DWORD dwCandidateLBN, UINT16 *o_pUDFRevision)
  187. {
  188. struct GenericVolumeStructureDesc_Base gvsdVolumeDesc;
  189. BOOL isUDFFS=TRUE;
  190. Tag Anchor_Des;
  191. DWORD TrackLBN = dwCandidateLBN;
  192. dbg_printf(("UDF_isResident(0x%08x, ..) calling.n", dwCandidateLBN));
  193. {//<<<MikeX_1105_2003: Check the BEA01 position
  194. BYTE number;
  195. for(number=0;number<16;number++)
  196. {
  197. if (! AuxCache_GetBytes((dwCandidateLBN + number + VOLUME_RECOGNITION_SEQUENCE_START_LSN), 0, 
  198.    sizeof(gvsdVolumeDesc), (BYTE*)&gvsdVolumeDesc))
  199. {
  200. dbg_printf(("WARNING: UDF_isResident() Failed [0]n"));
  201. isUDFFS = FALSE;
  202. }
  203. // Check for an ISO-9660 Standard-ID
  204. if (0 == strncmp((LPCSTR)gvsdVolumeDesc.aStandardID, STANDARD_ID_CD001, STANDARD_ID_LEN))
  205. continue;
  206. if (0 == strncmp((LPCSTR)gvsdVolumeDesc.aStandardID, STANDARD_ID_BEA01, STANDARD_ID_LEN))
  207. break;
  208. dbg_printf(("WARNING: UDF_isResident() Failed [0]n"));
  209. return FALSE;
  210. }
  211. dwCandidateLBN += number;
  212. }//MikeX_1105_2003>>>
  213. // Load the first Volume-Structure Descriptor within the Volume-Recognition-Sequence
  214. if (! AuxCache_GetBytes((dwCandidateLBN + VOLUME_RECOGNITION_SEQUENCE_START_LSN), 0, 
  215.    sizeof(gvsdVolumeDesc), (BYTE*)&gvsdVolumeDesc))
  216. {
  217. dbg_printf(("WARNING: UDF_isResident() Failed [1]n"));
  218. return FALSE;
  219. }
  220. // Test for a Beginning of Extended Area
  221. if (0 != strncmp((LPCSTR)gvsdVolumeDesc.aStandardID, STANDARD_ID_BEA01, STANDARD_ID_LEN))
  222. isUDFFS = FALSE;
  223. // The Medium contains UDF; now check which Revision of UDF
  224. if (! AuxCache_GetBytes((dwCandidateLBN + VOLUME_RECOGNITION_SEQUENCE_START_LSN + 1), 0,
  225.    sizeof(gvsdVolumeDesc), (BYTE*)&gvsdVolumeDesc)) 
  226. {
  227. dbg_printf(("WARNING: UDF_isResident() Failed [2]n"));
  228. return FALSE;
  229. }
  230. if (0 == strncmp((LPCSTR)gvsdVolumeDesc.aStandardID, STANDARD_ID_NSR02, STANDARD_ID_LEN))
  231. *o_pUDFRevision= 0x0102;
  232. else if (0 == strncmp((LPCSTR)gvsdVolumeDesc.aStandardID, STANDARD_ID_NSR03, STANDARD_ID_LEN))
  233. #ifndef DVD_VR_SUPPORT
  234. *o_pUDFRevision= 0x0102;//MikeX_0524_2004_A:patch for some special discs which used UDF 1.02 with NSR03.
  235. #else
  236. *o_pUDFRevision= 0x0200;
  237. #endif
  238. else
  239. *o_pUDFRevision= 0x0000;
  240. //MikeX_0617_2004_A: Patch!!! Can play the DVD disc without PVD.
  241. if(!isUDFFS)
  242. {
  243. if (!AuxCache_GetBytes((TrackLBN + FIRST_ANCHOR_POINT_LSN), 0, sizeof(Tag), (BYTE*)&Anchor_Des))
  244. {
  245. dbg_printf(("WARNING: UDF_isResident() Failed [3]n"));
  246. return FALSE;
  247. }
  248. if (Anchor_Des.uTagID == 0x0002)
  249. {
  250. BYTE checksum=0;
  251. int i;
  252. for(i=0; i<16; i++)
  253. {
  254. if (i != 4)
  255. {
  256. checksum += ((BYTE*)&Anchor_Des)[i];
  257. }
  258. }
  259. if (checksum == Anchor_Des.uTagChecksum)
  260. {
  261. isUDFFS = TRUE;
  262. }
  263. if (Anchor_Des.uDescriptorVersion == 0x0002)
  264. {
  265. *o_pUDFRevision = 0x0102;
  266. }
  267. else if (Anchor_Des.uDescriptorVersion == 0x0003)
  268. {
  269. *o_pUDFRevision = 0x0102;
  270. }
  271. else
  272. {
  273. *o_pUDFRevision = 0x0000;
  274. }
  275. }
  276. }
  277. return isUDFFS;
  278. }
  279. /////////////////////////////////////////////////////////////////////////////
  280. // Construction / Destruction
  281. /////////////////////////////////////////////////////////////////////////////
  282. // UDF_construct()
  283. //
  284. // Description: Constructs the File-System, and allocates system resources
  285. // needed for correct operation.
  286. //
  287. // Input: dwSessionStartLBN - The Start-LBN of the current Session;
  288. // uRevision - The UDF-Revision to support.
  289. // Output: None
  290. // In/Out: None
  291. // Return: None
  292. //
  293. // Remarks:
  294. // This method must be called prior to initialization of the File-System.
  295. void UDF_construct(DWORD dwSessionStartLBN, UINT16 uRevision)
  296. {
  297. dbg_printf(("UDF_construct(0x%08x, %04x) calling.n", dwSessionStartLBN, uRevision));
  298. if( g_pUDFInfo != NULL)
  299. {
  300. free(g_pUDFInfo);
  301. }
  302. g_pUDFInfo = (FileInfo *)malloc(sizeof(FileInfo));
  303. if(NULL == g_pUDFInfo)
  304. {
  305. tr_printf(("ISO9660_construct() failed--alloc memory for g_pUDFInfo failed.n"));
  306. return;
  307. }
  308. // Record the Session-Start Address
  309. g_pUDFInfo->dwSessionStartLBN= dwSessionStartLBN;
  310. // Record the UDF-Revision to support
  311. g_pUDFInfo->uRevision= uRevision;
  312. // Reset the Search-Info Pool
  313. if (! _FileSys_resetSearchInfoPool(sizeof(DirectorySearchInfo))) {
  314. tr_printf(("FATAL: UDF_construct() Failed [1]n"));
  315. }
  316. return;
  317. }
  318. /////////////////////////////////////////////////////////////////////////////
  319. // UDF_destruct()
  320. //
  321. // Description: Destructs the File-System, and frees system resources
  322. // allocated during the operation.
  323. //
  324. // Input: None
  325. // Output: None
  326. // In/Out: None
  327. // Return: None
  328. //
  329. // Remarks:
  330. // This method should be called when the File-System is no longer needed.
  331. void UDF_destruct(void)
  332. {
  333. dbg_printf(("UDF_destruct() calling.n"));
  334. #ifdef DVD_VR_SUPPORT
  335. // Destroy Partition Sparing Table.
  336. if( (UINT32)NULL != g_pUDFInfo->pMainPartitionSparingTable && FALSE != g_pUDFInfo->bUseSparingManagement )
  337. {
  338. Array_destruct((UINT32)(g_pUDFInfo->pMainPartitionSparingTable));
  339. g_pUDFInfo->pMainPartitionSparingTable = (UINT32)NULL;
  340. g_DVDVR_SparingTableSize=0;
  341. }
  342. g_pUDFInfo->bUseSparingManagement= FALSE;
  343. #endif
  344. if(NULL != g_pUDFInfo)
  345. {
  346. free(g_pUDFInfo);
  347. g_pUDFInfo = NULL;
  348. }
  349. return;
  350. }
  351. /////////////////////////////////////////////////////////////////////////////
  352. // Initialization
  353. /////////////////////////////////////////////////////////////////////////////
  354. // UDF_initialize()
  355. //
  356. // Description: Initializes the File-System and switches to the Root 
  357. // directory.
  358. //
  359. // Input: bLongFilenameSupport - Determines whether or not Long-Filenames
  360. //    Support is enabled.
  361. // Output: None
  362. // In/Out: None
  363. // Return: TRUE if the File-System was successfully initialized; FALSE
  364. // otherwise.
  365. //
  366. // Remarks:
  367. // 1. In case of failure, none of the Navigation or Queries methods may
  368. //    be used.
  369. // 2. The parameter bLongFilenameSupport is ignored, since UDF always
  370. //    supports Long Filenames.
  371. #pragma argsused
  372. BOOL UDF_initialize(BOOL bLongFilenameSupport)
  373. {
  374. dbg_printf(("UDF_initialize() calling.n"));
  375. if (0x0102 == g_pUDFInfo->uRevision)
  376. return _initializeUDF102();
  377. if (0x0200 <= g_pUDFInfo->uRevision)
  378. return _initializeUDF200();
  379. tr_printf(("FATAL: UDF_initialize() Failed [1]: Unsupported Revision.n"));
  380. return FALSE;
  381. }
  382. /////////////////////////////////////////////////////////////////////////////
  383. // Navigation
  384. /////////////////////////////////////////////////////////////////////////////
  385. // UDF_goToRootDir()
  386. //
  387. // Description: Sets the current working-directory to the Root directory.
  388. //
  389. // Input: None
  390. // Output: None
  391. // In/Out: None
  392. // Return: TRUE if the current working-directory was successfully switched
  393. // to the Root; FALSE otherwise.
  394. //
  395. // Remarks: None
  396. BOOL UDF_goToRootDir(void)
  397. {
  398. dbg_printf(("UDF_goToRootDir() calling.n"));
  399. g_pUDFInfo->dwCurrDirICB= g_pUDFInfo->dwRootDirICB;
  400. return TRUE;
  401. }
  402. /////////////////////////////////////////////////////////////////////////////
  403. // UDF_changeDir()
  404. //
  405. // Description: Changes the current working-directory to a desired directory.
  406. //
  407. // Input: i_pszDestDirName - A string holding the name of the destination
  408. //    Directory.
  409. // Output: None
  410. // In/Out: None
  411. // Return: TRUE if the current working-directory was successfully changed;
  412. // FALSE otherwise.
  413. //
  414. // Remarks:
  415. // 1. The destination Directory must be a direct descendant of the current
  416. //    working-directory.
  417. // 2. Only a single directory may be specified inside i_pszDestDirName.
  418. //    I.e., i_pszDestDirName is treated as a name of a single directory
  419. //    (directory hierarchy cannot be specified).
  420. BOOL UDF_changeDir(LPCWSTR i_pszDestDirName)
  421. {
  422. UINT16 hFileIDFind;
  423. struct FileIDDesc *pDestDirDesc;
  424. dbg_printf(("UDF_changeDir() calling.n"));
  425. // Try to locate a File-ID Descriptor corresponding to the required Directory
  426. hFileIDFind= _findFirstFileIDDesc(i_pszDestDirName, (FILE_CHAR_DIRECTORY | FILE_CHAR_PARENT),
  427.   FILE_CHAR_DIRECTORY, &pDestDirDesc);
  428. if (NULL == hFileIDFind)
  429. return FALSE;
  430. // The appropriate Directory was found: record the location of its ICB for
  431. // future use.
  432. g_pUDFInfo->dwCurrDirICB= LE_DWORD((pDestDirDesc->ladICB).lbaExtentLocation.uLogicalBlockNumber);
  433. // Free the Directory-Record and terminate the search
  434. free(pDestDirDesc);
  435. _findClose(hFileIDFind);
  436. return TRUE;
  437. }
  438. /////////////////////////////////////////////////////////////////////////////
  439. // UDF_goUp()
  440. //
  441. // Description: Moves up one level in the Directories hierarchy.
  442. //
  443. // Input: None
  444. // Output: None
  445. // In/Out: None
  446. // Return: TRUE if the current working-directory was successfully changed;
  447. // FALSE otherwise.
  448. //
  449. // Remarks:
  450. // This method changes the current working-directory to its direct parent
  451. // in the Directories hierarchy. If the current working-directory is already
  452. // the Root when this method is called, no change is made.
  453. BOOL UDF_goUp(void)
  454. {
  455. UINT16 hFileIDFind;
  456. struct FileIDDesc *pParentDirDesc;
  457. dbg_printf(("UDF_goUp() calling.n"));
  458. // Try to locate a File-ID Descriptor corresponding to the Parent Directory
  459. hFileIDFind= _findFirstFileIDDesc(L"", FILE_CHAR_PARENT,
  460.   FILE_CHAR_PARENT, &pParentDirDesc);
  461. if (NULL == hFileIDFind)
  462. return FALSE;
  463. // The Parent Directory was found: record the location of its ICB for
  464. // future use.
  465. g_pUDFInfo->dwCurrDirICB= ((pParentDirDesc->ladICB).lbaExtentLocation.uLogicalBlockNumber);
  466. // Free the Directory-Record and terminate the search
  467. free(pParentDirDesc);
  468. _findClose(hFileIDFind);
  469. return TRUE;
  470. }
  471. /////////////////////////////////////////////////////////////////////////////
  472. // UDF_storeWorkingDirectory()
  473. //
  474. // Description: Stores the position of the Current Working Directory.
  475. //
  476. // Input: None
  477. // Output: None
  478. // In/Out: None
  479. // Return: None
  480. //
  481. // Remarks:
  482. // The position of the Current Directory is unconditionally stored, and may
  483. // be later recalled via UDF_recallWorkingDirectory().
  484. // This method is useful for peeking into different directories, and then
  485. // restoring the original Working-Directory.
  486. void UDF_storeWorkingDirectory(void)
  487. {
  488. // Store the Working-Directory and set the Storage indicator
  489. g_pUDFInfo->dwCWDStorage= g_pUDFInfo->dwCurrDirICB;
  490. g_pUDFInfo->bCWDStored= TRUE;
  491. return;
  492. }
  493. /////////////////////////////////////////////////////////////////////////////
  494. // UDF_recallWorkingDirectory()
  495. //
  496. // Description: Recalls the position of the Current Working Directory.
  497. //
  498. // Input: None
  499. // Output: None
  500. // In/Out: None
  501. // Return: None
  502. //
  503. // Remarks:
  504. // The position of the Current Directory is stored only if it has been
  505. // previously stored via UDF_storeWorkingDirectory().
  506. void UDF_recallWorkingDirectory(void)
  507. {
  508. // Restore the Working-Directory
  509. if (g_pUDFInfo->bCWDStored)
  510. g_pUDFInfo->dwCurrDirICB= g_pUDFInfo->dwCWDStorage;
  511. // Clear the Storage indicator
  512. g_pUDFInfo->bCWDStored= FALSE;
  513. return;
  514. }
  515. /////////////////////////////////////////////////////////////////////////////
  516. // Queries
  517. /////////////////////////////////////////////////////////////////////////////
  518. // UDF_getVolumeName()
  519. //
  520. // Description: Retrieves the Name of the Primary-Volume on the Medium.
  521. //
  522. // Input: None
  523. // Output: None
  524. // In/Out: None
  525. // Return: A pointer to a constant String, containing the Volume-Name.
  526. //
  527. // Remarks:
  528. // The returned String must not be modified or freed by the caller.
  529. void UDF_getVolumeName(LPCWSTR volumeName)
  530. {
  531. sc_GetBytes(SC_VOLUME_ID_ADDR, 0, FILESYSTEM_MAX_VOLUME_NAME*sizeof(WCHAR), (BYTE*)volumeName);
  532. return; 
  533. }
  534. /////////////////////////////////////////////////////////////////////////////
  535. // UDF_fileExists()
  536. //
  537. // Description: Tests whether a certain file exists in the current working-
  538. // directory, or not.
  539. //
  540. // Input: i_pszFilename - A string holding the name of the File to test.
  541. // Output: None
  542. // In/Out: None
  543. // Return: TRUE if the requested File exists in the current working-directory;
  544. // FALSE otherwise.
  545. //
  546. // Remarks:
  547. // A return value of FALSE may also indicate that the currently-selected
  548. // File-System is unknown. The user is responsible for verifying correctness
  549. // by assuring that the File-System type was selected and the File-System 
  550. // successfully initialized.
  551. BOOL UDF_fileExists(LPCWSTR i_pszFilename)
  552. {
  553. UINT16 hFileIDFind;
  554. struct FileIDDesc *pDestDirDesc;
  555. dbg_printf(("UDF_fileExists() calling.n"));
  556. // Try to locate a File-ID Descriptor corresponding to the required File; Specify
  557. // that the required file must be non-directory, not hidden, not a Parent, and undeleted.
  558. hFileIDFind= _findFirstFileIDDesc(i_pszFilename, 
  559.   (FILE_CHAR_DIRECTORY | FILE_CHAR_PARENT | FILE_CHAR_HIDDEN | FILE_CHAR_DELETED),
  560.   0x0, &pDestDirDesc);
  561. if (NULL == hFileIDFind)
  562. return FALSE;
  563. // Free the Directory-Record and terminate the search
  564. free(pDestDirDesc);
  565. _findClose(hFileIDFind);
  566. return TRUE;
  567. }
  568. /////////////////////////////////////////////////////////////////////////////
  569. // UDF_fileLocation()
  570. //
  571. // Description: Retrieves the location of a certain file (its start address).
  572. //
  573. // Input: i_pszFilename - A string holding the name of the requested File.
  574. // Output: o_pFileLocation - Points to a DWORD to receive the File's start
  575. //   address.
  576. // In/Out: None
  577. // Return: TRUE if the requested File was located and its address retrieved;
  578. // FALSE otherwise.
  579. //
  580. // Remarks:
  581. // 1. A return value of FALSE indicates that the requested File does not
  582. //    exist in the current working-directory.
  583. // 2. The File's start-address is given in terms of the Medium's native
  584. //    addressing system. E.g., for Optical-Storage Media, the returned
  585. //    address is expressed in terms of Logical-Block-Number (LBN).
  586. BOOL UDF_fileLocation(LPCWSTR i_pszFilename, DWORD *o_pFileLocation)
  587. {
  588. BOOL bSuccess;
  589. UINT16 hFileIDFind;
  590. FindData fdFileInfo;
  591. struct FileIDDesc *pFileDesc;
  592. dbg_printf(("UDF_fileLocation() calling.n"));
  593. // Try to locate a File-ID Descriptor corresponding to the required File; Specify
  594. // that the required file must be non-directory, not hidden, not a Parent, and undeleted.
  595. hFileIDFind= _findFirstFileIDDesc(i_pszFilename,
  596.   (FILE_CHAR_DIRECTORY | FILE_CHAR_PARENT /*| FILE_CHAR_HIDDEN */| FILE_CHAR_DELETED),
  597.   0x0, &pFileDesc);
  598. if (NULL == hFileIDFind)
  599. return FALSE;
  600. bSuccess= _getFileAttributes(pFileDesc, &fdFileInfo);
  601. // Free the File-Record and terminate the search
  602. free(pFileDesc);
  603. _findClose(hFileIDFind);
  604. // Prepare the result
  605. if (bSuccess)
  606. *o_pFileLocation= fdFileInfo.dwStartAddr;
  607. else
  608. *o_pFileLocation= NULL;
  609. return bSuccess;
  610. }
  611. /////////////////////////////////////////////////////////////////////////////
  612. // UDF_getDVDFileInfo()
  613. //
  614. // Description: Retrieves DVD-Specific information about some file.
  615. //
  616. // Input: i_pszFilename - A string holding the name of the requested File,
  617. // or a pattern to match.
  618. // eType - An enumerator indicating the Type of DVD Information to
  619. // retrieve.
  620. // Output: o_pFileInfo - Points to a DVDFileInfo structure, to receive the
  621. //   File's DVD-information upon successful completion;
  622. // o_pFindData - Points to a FindData structure, to receive the File's
  623. //   details upon successful completion. May be NULL.
  624. // In/Out: None
  625. // Return: TRUE if the requested file was found and the required DVD
  626. // information was successfully retrieved;
  627. // FALSE if the file couldn't be found, or if the file has no
  628. // associated DVD information of the requested type.
  629. //
  630. // Remarks:
  631. // - The value of o_pFindData may be NULL, in which case the FindData
  632. //   is not retrieved.
  633. BOOL UDF_getDVDFileInfo(LPCWSTR i_pszFilename, enDVD_FileInfoType eType, 
  634. DVDFileInfo *o_pFileInfo, FindData *o_pFindData)
  635. {
  636. BOOL bSuccess;
  637. DWORD  dwFileEntryAddr;
  638. UINT16 hFileIDFind;
  639. LPCSTR pszAttrID;
  640. struct FileIDDesc *pFileDesc;
  641. struct TerminalEntry *pEntry;
  642. struct ExtendedAttributeHeaderDesc *pExtAttrHdr;
  643. struct ImplUseExtendedAttribute *pCurrExtAttr;
  644. UINT32 dwExtAttrsPos;
  645. UINT32 dwEndOfExtAttrs;
  646. dbg_printf(("UDF_getDVDFileInfo() calling.n"));
  647. // Try to locate a File-ID Descriptor corresponding to the required File; Specify
  648. // that the required file must not be a Parent, must not be a Directory, and should 
  649. // be undeleted.
  650. hFileIDFind= _findFirstFileIDDesc(i_pszFilename,
  651.   (FILE_CHAR_PARENT | FILE_CHAR_DIRECTORY | FILE_CHAR_DELETED),
  652.   0x0, &pFileDesc);
  653. if (NULL == hFileIDFind)
  654. return FALSE;
  655. dwFileEntryAddr= _absoluteLBA(LE_DWORD(pFileDesc->ladICB.lbaExtentLocation.uLogicalBlockNumber));
  656. // If necessary, fill-in the Find-Data information for this file
  657. if ((NULL != o_pFindData) &&
  658. ! _getFileAttributes(pFileDesc, o_pFindData)) 
  659. {
  660. dbg_printf(("WARNING: UDF_findFirstFile() Failed [1]n"));
  661. memset(o_pFindData, 0, sizeof(FindData));
  662. }
  663. // Free the File-Record and terminate the search
  664. free(pFileDesc);
  665. _findClose(hFileIDFind);
  666. // Load the File's File-Entry. Use a Terminal-Entry at first, just to peek
  667. // into the type of Descriptor that is at hand (File-Entry / Extended-File-Entry).
  668. pEntry= (struct TerminalEntry *)malloc(sizeof(struct TerminalEntry));
  669. if (NULL == pEntry) {
  670. tr_printf(("FATAL: UDF_findFirstFile() Failed [2]: Low system resourcesn"));
  671. return FALSE;
  672. }
  673. // Read the File-Entry
  674. if (! AuxCache_GetBytes(dwFileEntryAddr, 0, sizeof(struct TerminalEntry), (BYTE*)pEntry)) {
  675. dbg_printf(("WARNING: UDF_findFirstFile() Failed [3]: Low system resourcesn"));
  676. free(pEntry);
  677. return FALSE;
  678. }
  679. // Compute the Extended-Attributes Header Descriptor Entry according to the Descriptor type,
  680. // and extract it.
  681. dwExtAttrsPos= 0;
  682. if (TAG_ID_FILE_ENTRY == LE_WORD(pEntry->tgDescTag.uTagID)) {
  683. // Retrieve the Length of Extended Attributes and establish their boundaries
  684. UINT32 cbLengthOfExtAttrs;
  685. if (AuxCache_GetBytes(dwFileEntryAddr, FILE_ENTRY_L_EXTATTR_OFFSET,
  686.  sizeof(cbLengthOfExtAttrs), (BYTE*)&cbLengthOfExtAttrs))
  687. {
  688. dwExtAttrsPos= FILE_ENTRY_EXTATTRS_OFFSET;
  689. dwEndOfExtAttrs= (dwExtAttrsPos + LE_DWORD(cbLengthOfExtAttrs));
  690. }
  691. }
  692. else if (TAG_ID_EXT_FILE_ENTRY == LE_WORD(pEntry->tgDescTag.uTagID)) {
  693. // Retrieve the Length of Extended Attributes and establish their boundaries
  694. UINT32 cbLengthOfExtAttrs;
  695. if (AuxCache_GetBytes(dwFileEntryAddr, EXT_FILE_ENTRY_L_EXTATTR_OFFSET,
  696.  sizeof(cbLengthOfExtAttrs), (BYTE*)&cbLengthOfExtAttrs))
  697. {
  698. dwExtAttrsPos= EXT_FILE_ENTRY_EXTATTRS_OFFSET;
  699. dwEndOfExtAttrs= (dwExtAttrsPos + LE_DWORD(cbLengthOfExtAttrs));
  700. }
  701. }
  702. // Now examine the Extended-Attributes Header Descriptor, and extract the first
  703. // Implementation Extended-Attribute.
  704. pExtAttrHdr= (struct ExtendedAttributeHeaderDesc *)pEntry;
  705. if (! AuxCache_GetBytes(dwFileEntryAddr, dwExtAttrsPos, 
  706.    sizeof(struct ExtendedAttributeHeaderDesc), (BYTE*)pExtAttrHdr))
  707. {
  708. dbg_printf(("WARNING: UDF_findFirstFile() Failed [4]n"));
  709. dwExtAttrsPos= 0;
  710. }
  711. if ((0 == dwExtAttrsPos) || 
  712. (TAG_ID_EXT_ATTR_HDR_DESC != LE_WORD(pExtAttrHdr->tgDescTag.uTagID)))
  713. {
  714. dbg_printf(("WARNING: UDF_findFirstFile() Failed [5]n"));
  715. free(pEntry);
  716. return FALSE;
  717. }
  718. // Adjust the dwExtAttrsPos to point at the beginning of the 
  719. // Implementation Extended-Attributes.
  720. dwExtAttrsPos += LE_DWORD(pExtAttrHdr->cbImplAttrLocation);
  721. free(pEntry);
  722. // Prepare the Attribute-ID to look for
  723. switch (eType)
  724. {
  725. case eFreeEASpace:
  726. pszAttrID= UDF_ID_DVD_FREE_EA;
  727. break;
  728. case eCGMS:
  729. pszAttrID= UDF_ID_DVD_IMPL;
  730. break;
  731. }
  732. // Allocate a single Implementation-Use Extended Attribute
  733. pCurrExtAttr= (struct ImplUseExtendedAttribute *)malloc(sizeof(struct ImplUseExtendedAttribute));
  734. if (NULL == pCurrExtAttr) {
  735. dbg_printf(("WARNING: UDF_findFirstFile() Failed [6]: Low system resourcesn"));
  736. return FALSE;
  737. }
  738. // Iterate over the various Implementation Attributes, until an Attribute is found,
  739. // which matches the required Type.
  740. while (dwExtAttrsPos < dwEndOfExtAttrs) {
  741. if (! AuxCache_GetBytes(dwFileEntryAddr, dwExtAttrsPos, 
  742.    sizeof(struct ImplUseExtendedAttribute), (BYTE*)pCurrExtAttr))
  743. {
  744. break;
  745. }
  746. if ((ATTR_TYPE_IMPL == LE_DWORD(pCurrExtAttr->uAttrType)) &&
  747. (0 == strcmp(pszAttrID, (LPCSTR)pCurrExtAttr->ridImplID.aIdentifier)))
  748. break;
  749. // Continue to the next Attribute
  750. dwExtAttrsPos += LE_DWORD(pCurrExtAttr->cbAttrLength);
  751. }
  752. free(pCurrExtAttr);
  753. // Check if the requested Attribute was found, or not
  754. if (dwExtAttrsPos < dwEndOfExtAttrs) {
  755. dwExtAttrsPos += sizeof(struct ImplUseExtendedAttribute);
  756. // Extract the requested information from the Attribute
  757. switch (eType)
  758. {
  759. case eFreeEASpace:
  760. {
  761. struct ExtendedAttrImplUse_DVD_FreeEASpace freeEASpace;
  762. if (AuxCache_GetBytes(dwFileEntryAddr, dwExtAttrsPos, sizeof(freeEASpace), 
  763.  (BYTE*)&freeEASpace)) 
  764. {
  765. o_pFileInfo->eInfoType= eFreeEASpace;
  766. o_pFileInfo->Info.cbFreeEASpace= (UINT16)LE_DWORD(freeEASpace.uFreeEASpace);
  767. }
  768. }
  769. break;
  770. case eCGMS:
  771. {
  772. struct ExtendedAttrImplUse_DVD_CGMS cgmsInfo;
  773. if (AuxCache_GetBytes(dwFileEntryAddr, dwExtAttrsPos, sizeof(cgmsInfo), 
  774.  (BYTE*)&cgmsInfo)) 
  775. {
  776. o_pFileInfo->eInfoType= eCGMS;
  777. o_pFileInfo->Info.cmiCGMS.ucCGMSInfo= cgmsInfo.ucCGMSInfo;
  778. o_pFileInfo->Info.cmiCGMS.uDataStructureType= cgmsInfo.uDataStructureType;
  779. memcpy(o_pFileInfo->Info.cmiCGMS.aProtectionSystemInfo, 
  780.    cgmsInfo.aProtectionSystemInfo, 4);
  781. }
  782. }
  783. break;
  784. }
  785. bSuccess= TRUE;
  786. }
  787. else
  788. bSuccess= FALSE;
  789. return bSuccess;
  790. }
  791. /////////////////////////////////////////////////////////////////////////////
  792. // UDF_findFirstFile()
  793. //
  794. // Description: Initiates a search for a certain file, or collection of
  795. // files.
  796. //
  797. // Input: i_pszFilename - A string holding the name of the requested File,
  798. // or a pattern to match.
  799. // Output: o_pFindData - Points to a FindData structure, to receive the File's
  800. //   details upon successful completion of the search.
  801. // In/Out: None
  802. // Return: A UINT32 which serves as the Handle to this search. This value
  803. // must be saved for later use with other find-related methods.
  804. // NULL is returned if the search fails.
  805. //
  806. // Remarks:
  807. // 1. The user must save the returned Handle in order to supply it to future
  808. //    calls to any of the other find-related methods.
  809. // 2. If the returned Handle is NULL, then no File matching the supplied
  810. //    name/pattern could be located in the current working-directory.
  811. // 3. The search is limited to the current working-directory only.
  812. // 4. The following patterns may be supplied in i_pszFilename:
  813. // - An empty string ("") - matches any File/Sub-Directory;
  814. // - Some non-empty string: treated as a Filename/Sub-Directory prefix.
  815. //   For a string of length N, only the first N characters are used
  816. //   for matching.
  817. //   For example: supplying a value of i_pszFilename="A" would retrieve
  818. //   the first File/Sub-Directory whose name begins with a Captial 'A',
  819. //   if such a File/Sub-Directory exists.
  820. // 5. The search is Case-Sensitive.
  821. // 6. UDF_findClose() must be called when no additional searches are needed.
  822. UINT16 UDF_findFirstFile(LPCWSTR i_pszPattern, FindData *o_pFindData)
  823. {
  824. UINT16 hFileIDFind;
  825. struct FileIDDesc *pFileDesc;
  826. dbg_printf(("UDF_findFirstFile() calling.n"));
  827. // Try to locate a File-ID Descriptor corresponding to the required File; Specify
  828. // that the required file must not be a Parent, and should be undeleted.
  829. hFileIDFind= _findFirstFileIDDesc(i_pszPattern,
  830.   (FILE_CHAR_PARENT | FILE_CHAR_DELETED),
  831.   0x0, &pFileDesc);
  832. if (NULL == hFileIDFind)
  833. return NULL;
  834. if (! _getFileAttributes(pFileDesc, o_pFindData)) {
  835. _findClose(hFileIDFind);
  836. hFileIDFind= NULL;
  837. }
  838. free(pFileDesc);
  839. return hFileIDFind;
  840. }
  841. /////////////////////////////////////////////////////////////////////////////
  842. // UDF_findNextFile()
  843. //
  844. // Description: Continues a search that was previously initiated using a call
  845. // to UDF_findFirstFile().
  846. //
  847. // Input: hFindFile - A Handle to a file-search, that was returned from 
  848. // a previous call to UDF_findFirstFile().
  849. // Output: o_pFindData - Points to a FindData structure, to receive the File's
  850. //   details upon successful completion of the search.
  851. // In/Out: None
  852. // Return: TRUE if the search succeeded, and an additional File matching
  853. // the Filename/pattern was found. In this case, the supplied
  854. // o_pFindData contains updated information of the found File.
  855. // FALSE is returned if no more Files/Sub-Directories matching the
  856. // supplied Filename/pattern could be found. In this case, the
  857. // supplied o_pFindData is invalid.
  858. //
  859. // Remarks:
  860. // 1. This method continues a previous search from the point it left off.
  861. // 2. The search relates to the Directory that was the current working-
  862. //    directory at the time the search was initiated via UDF_findFirstFile().
  863. // 3. The search uses the same Filename/pattern as was originally supplied
  864. //    to UDF_findFirstFile().
  865. // 4. UDF_findClose() must be called when no additional searches are needed.
  866. BOOL UDF_findNextFile(UINT16 hFindFile, FindData *o_pFindData)
  867. {
  868. BOOL bSuccess;
  869. struct FileIDDesc *pFileDesc;
  870. dbg_printf(("UDF_findNextFile() calling.n"));
  871. if (! _findNextFileIDDesc(hFindFile, &pFileDesc))
  872. return FALSE;
  873. bSuccess= _getFileAttributes(pFileDesc, o_pFindData);
  874. free(pFileDesc);
  875. return bSuccess;
  876. }
  877. /////////////////////////////////////////////////////////////////////////////
  878. // UDF_findClose()
  879. //
  880. // Description: Terminates a file-search.
  881. //
  882. // Input: hFindFile - A Handle to a file-search, that was returned from 
  883. // a previous call to UDF_findFirstFile().
  884. // Output: None
  885. // In/Out: None
  886. // Return: TRUE if the search was successfully terminated; FALSE othewise.
  887. //
  888. // Remarks:
  889. // Any search that is initiated via UDF_findFirstFile() must be terminated
  890. // using a call to this method, in order to allow for proper release of
  891. // resources that were allocated for that search.
  892. BOOL UDF_findClose(UINT16 hFileFind)
  893. {
  894. dbg_printf(("UDF_findClose() calling.n"));
  895. return _findClose(hFileFind);
  896. }
  897. #ifdef DVD_VR_SUPPORT
  898. BYTE* g_pCache=NULL;
  899. DWORD currSector=0L;
  900. DWORD currOffset = 0L;
  901. #define CACHE_SIZE 512
  902. BOOL _GetBytefromCache(DWORD sectorNum, DWORD offset, WORD size, BYTE* buff)
  903. {
  904. if( (sectorNum != currSector) || (offset < currOffset) || (offset +size > currOffset + CACHE_SIZE))
  905. {
  906. if(!AuxCache_GetBytes(sectorNum, offset, CACHE_SIZE, g_pCache) )
  907. return FALSE;
  908. currSector = sectorNum;
  909. currOffset = offset;
  910. }
  911. memcpy( buff, g_pCache+offset - currOffset, size);
  912. return TRUE;
  913. }
  914. BOOL _get_extent_descriptor(DWORD array,DWORD location)
  915. {
  916. DWORD length=0;
  917. WORD upperBound;
  918. DWORD dwAllocDesPos = 24;
  919. {
  920. WORD wDescriptorID;
  921. if ( (!AuxCache_GetBytes(_absoluteLBA(location), 0, sizeof(WORD), (BYTE*)&wDescriptorID)) || (LE_WORD(wDescriptorID) != TAG_ID_ALLOC_EXTENT_DESC) )
  922. {
  923. dbg_printf(("WARNING: _get_extent_descriptor() Failed [1]n"));
  924. return FALSE;
  925. }
  926. }
  927. upperBound = Array_getSize(array);
  928. if (_GetBytefromCache(_absoluteLBA(location), ALLOCATION_EXTENT_LENGTH_OFFSET, sizeof(DWORD), (BYTE*)&length))
  929. {
  930. Extent_ad CrtExtentAD;
  931. length /= sizeof(Extent_ad);
  932. Array_reconstruct(array, (WORD)(length + Array_getCapacity(array) - 1));
  933. {
  934. Array_getAt(array, 0, &CrtExtentAD);
  935. CrtExtentAD.dwExtentLength += length -1;
  936. Array_setAt(array, 0, &CrtExtentAD);
  937. }
  938. length = (DWORD)Array_getCapacity(array);
  939. for(;upperBound < (WORD)length; upperBound++)
  940. {
  941. if (!_GetBytefromCache(_absoluteLBA(location), dwAllocDesPos, sizeof(Extent_ad), (BYTE*)&CrtExtentAD))
  942. {
  943. dbg_printf(("WARNING: _get_extent_descriptor() Failed [2]n"));
  944. return FALSE;
  945. }
  946. if( (CrtExtentAD.dwExtentLength >> 30) == 3)
  947. _get_extent_descriptor(array, CrtExtentAD.dwExtentLocation);
  948. else
  949. Array_setAt(array, upperBound, &CrtExtentAD);
  950. dwAllocDesPos += sizeof(Extent_ad);
  951. }
  952. }
  953. return TRUE;
  954. }
  955. /////////////////////////////////////////////////////////////////////////////
  956. // UDF_getDVDVRFileExtent()
  957. //
  958. // Description: cache real-time file entry extents table to scratch-pad
  959. //
  960. // Input: i_pszFilename - A string holding the name of the requested File,
  961. // or a pattern to match.
  962. // Output: o_pFileExtentList - Points to the array which cache the extents table
  963. // In/Out: None
  964. // Return: TRUE if the requested file was found and the extents table was 
  965. // successfully retrieved;
  966. // FALSE if the file couldn't be found, or if the file has no
  967. // extents table.
  968. //
  969. // Remarks:
  970. // - The value of o_pFileExtentList may be NULL, in which case the extents table
  971. //   is not retrieved.
  972. BOOL UDF_getDVDVRFileExtent(LPCWSTR i_pszFilename, DWORD* o_pFileExtentList)
  973. {
  974. BOOL bSuccess=TRUE;
  975. DWORD  dwFileEntryAddr;
  976. UINT16 hFileIDFind;
  977. struct FileIDDesc *pFileDesc;
  978. struct TerminalEntry *pEntry;
  979. DWORD dwFileExtentCacheAddr = g_DVDVR_SpringTableAddr + g_DVDVR_SparingTableSize;
  980. UINT32 dwAllocDesPos=0;
  981. UINT32 dwEndOfAllocDes=0;
  982. UINT32 dwFileExtentCnt;
  983. Extent_ad CrtExtentAD;
  984. int iCnt;
  985. dbg_printf(("UDF_getDVDVRFileExtent() calling.n"));
  986. // Try to locate a File-ID Descriptor corresponding to the required File; Specify
  987. // that the required file must not be a Parent, must not be a Directory, and should 
  988. // be undeleted.
  989. hFileIDFind= _findFirstFileIDDesc(i_pszFilename,
  990.   (FILE_CHAR_PARENT | FILE_CHAR_DIRECTORY | FILE_CHAR_DELETED),
  991.   0x0, &pFileDesc);
  992. if (NULL == hFileIDFind)
  993. return FALSE;
  994. dwFileEntryAddr= _absoluteLBA(LE_DWORD(pFileDesc->ladICB.lbaExtentLocation.uLogicalBlockNumber));
  995. // Free the File-Record and terminate the search
  996. free(pFileDesc);
  997. _findClose(hFileIDFind);
  998. // Load the File's File-Entry. Use a Terminal-Entry at first, just to peek
  999. // into the type of Descriptor that is at hand (File-Entry / Extended-File-Entry).
  1000. pEntry= (struct TerminalEntry *)malloc(sizeof(struct TerminalEntry));
  1001. if (NULL == pEntry) {
  1002. tr_printf(("FATAL: UDF_getDVDVRFileExtent() Failed [1]: Low system resourcesn"));
  1003. return FALSE;
  1004. }
  1005. // Read the File-Entry
  1006. if (! AuxCache_GetBytes(dwFileEntryAddr, 0, sizeof(struct TerminalEntry), (BYTE*)pEntry)) {
  1007. dbg_printf(("WARNING: UDF_getDVDVRFileExtent() Failed [2]: Low system resourcesn"));
  1008. free(pEntry);
  1009. return FALSE;
  1010. }
  1011. if (TAG_ID_FILE_ENTRY == LE_WORD(pEntry->tgDescTag.uTagID)) {
  1012. // Retrieve the Length of Extended Attributes and establish their boundaries
  1013. UINT32 cbLengthOfExtAttrs,cbLengthOfAllocDes;
  1014. if (AuxCache_GetBytes(dwFileEntryAddr, FILE_ENTRY_L_EXTATTR_OFFSET,
  1015.  sizeof(cbLengthOfExtAttrs), (BYTE*)&cbLengthOfExtAttrs))
  1016. dwAllocDesPos= FILE_ENTRY_EXTATTRS_OFFSET+LE_DWORD(cbLengthOfExtAttrs);
  1017. else
  1018. bSuccess=FALSE;
  1019. if (AuxCache_GetBytes(dwFileEntryAddr, FILE_ENTRY_L_ALLOCDESC_OFFSET,
  1020.  sizeof(cbLengthOfAllocDes), (BYTE*)&cbLengthOfAllocDes))
  1021. dwEndOfAllocDes= (dwAllocDesPos + LE_DWORD(cbLengthOfAllocDes));
  1022. else
  1023. bSuccess=FALSE;
  1024. }
  1025. else if (TAG_ID_EXT_FILE_ENTRY == LE_WORD(pEntry->tgDescTag.uTagID)) {
  1026. // Retrieve the Length of Extended Attributes and establish their boundaries
  1027. UINT32 cbLengthOfExtAttrs,cbLengthOfAllocDes;
  1028. if (AuxCache_GetBytes(dwFileEntryAddr, EXT_FILE_ENTRY_L_EXTATTR_OFFSET,
  1029.  sizeof(cbLengthOfExtAttrs), (BYTE*)&cbLengthOfExtAttrs))
  1030. dwAllocDesPos= EXT_FILE_ENTRY_EXTATTRS_OFFSET+LE_DWORD(cbLengthOfExtAttrs);
  1031. else
  1032. bSuccess=FALSE;
  1033. if (AuxCache_GetBytes(dwFileEntryAddr, EXT_FILE_ENTRY_L_ALLOCDESC_OFFSET,
  1034.  sizeof(cbLengthOfAllocDes), (BYTE*)&cbLengthOfAllocDes))
  1035. dwEndOfAllocDes= (dwAllocDesPos + LE_DWORD(cbLengthOfAllocDes));
  1036. else
  1037. bSuccess=FALSE;
  1038. }
  1039. free(pEntry);
  1040. if(!bSuccess)
  1041. return FALSE;
  1042. g_pCache = (BYTE*)malloc(CACHE_SIZE);
  1043. if(g_pCache == NULL)
  1044. {
  1045. tr_printf(("FATAL: UDF_getDVDVRFileExtent() Failed [3]: Low system resourcesn"));
  1046. return FALSE;
  1047. }
  1048. dwFileExtentCnt=(dwEndOfAllocDes-dwAllocDesPos+sizeof(Extent_ad)-1)/sizeof(Extent_ad);
  1049. *o_pFileExtentList=Array_constructEx(dwFileExtentCnt+1, sizeof(Extent_ad), &dwFileExtentCacheAddr);
  1050. if(*o_pFileExtentList == (DWORD)NULL)
  1051. {
  1052. tr_printf(("FATAL: UDF_getDVDVRFileExtent() Failed [4]: Low system resourcesn"));
  1053. free(g_pCache);
  1054. return FALSE;
  1055. }
  1056. CrtExtentAD.dwExtentLength=dwFileExtentCnt;
  1057. CrtExtentAD.dwExtentLocation=0;
  1058. Array_setAt(*o_pFileExtentList, 0, &CrtExtentAD);
  1059. for(iCnt=1;iCnt<=dwFileExtentCnt;iCnt++)
  1060. {
  1061. if (!_GetBytefromCache(dwFileEntryAddr, dwAllocDesPos, sizeof(Extent_ad), (BYTE*)&CrtExtentAD))
  1062. {
  1063. dbg_printf(("WARNING: UDF_getDVDVRFileExtent() Failed [5]: Low system resourcesn"));
  1064. free(g_pCache);
  1065. return FALSE;
  1066. }
  1067. if( (CrtExtentAD.dwExtentLength >> 30) == 3)
  1068. _get_extent_descriptor(*o_pFileExtentList, CrtExtentAD.dwExtentLocation);
  1069. else
  1070. Array_setAt(*o_pFileExtentList, iCnt, &CrtExtentAD);
  1071. dwAllocDesPos += sizeof(Extent_ad);
  1072. }
  1073. Array_getAt(*o_pFileExtentList, 0, &CrtExtentAD);
  1074. g_DVDVR_SparingTableSize += (CrtExtentAD.dwExtentLength +1)*2;
  1075. free(g_pCache);
  1076. return bSuccess;
  1077. }
  1078. /////////////////////////////////////////////////////////////////////////////
  1079. // _readSectors()
  1080. //
  1081. // Description: read a sector by sparing table.
  1082. //
  1083. // Input: LBN: start Logical Block Number
  1084. // dwOff: start bytes offset
  1085. // dwSize: the bytes number want to read
  1086. //
  1087. // Output: o_pBuff: point to the output data
  1088. // In/Out: None
  1089. // Return: TRUE if reading was successfully; FALSE othewise.
  1090. //
  1091. // Remarks:
  1092. //
  1093. BOOL _readSectors(DWORD LBN, DWORD dwOff, DWORD dwSize, BYTE* o_pBuff)
  1094. {
  1095. while( dwSize > 0 )
  1096. {
  1097. WORD dwReadSize = MIN(dwSize, LOGICAL_BLOCK_SIZE - dwOff%LOGICAL_BLOCK_SIZE);
  1098. if(!AuxCache_GetBytes( _absoluteLBA( LBN+dwOff / LOGICAL_BLOCK_SIZE ), 
  1099. dwOff % LOGICAL_BLOCK_SIZE, dwReadSize, o_pBuff))
  1100. return FALSE;
  1101. dwOff += dwReadSize;
  1102. o_pBuff += dwReadSize;
  1103. dwSize -= dwReadSize;
  1104. }
  1105. return TRUE;
  1106. }
  1107. /////////////////////////////////////////////////////////////////////////////
  1108. // UDF_ReadFile()
  1109. //
  1110. // Description: read some bytes from a file
  1111. //
  1112. // Input: pFileHandle - points to the file extents table
  1113. // dwOffset - the start byte offset in the file
  1114. // dwSize - the bytes number want to read
  1115. //
  1116. // Output: o_pBuffer - Points to the buffer of the output data
  1117. // In/Out: None
  1118. // Return: TRUE if read successfully,FALSE otherwise
  1119. //
  1120. // Remarks:
  1121. // - The pFileHandle should not be NULL, and the dwSize should over the file size.
  1122. BOOL UDF_ReadFile(DWORD pFileHandle, DWORD dwOffset, DWORD dwSize, BYTE* o_pBuffer)
  1123. {
  1124. int i=1;
  1125. Extent_ad tempExtent;
  1126. DWORD dwFileExtentCnt,dwFileCrtOffset=0;
  1127. if((DWORD)NULL==pFileHandle)
  1128. {
  1129. tr_printf(("FATAL: UDF_ReadFile() Failed [1]: pFileHandle is NULL.n"));
  1130. return FALSE;
  1131. }
  1132. Array_getAt(pFileHandle, 0, (BYTE*)(&tempExtent));
  1133. dwFileExtentCnt=tempExtent.dwExtentLength;
  1134. while( i<=dwFileExtentCnt && dwSize>0 && Array_getAt(pFileHandle, i, (BYTE*)(&tempExtent)) )
  1135. {
  1136. tempExtent.dwExtentLength &= ~ALLOCATION_EXTENT_INTERPRETATION;
  1137. if( tempExtent.dwExtentLength == 0 || tempExtent.dwExtentLocation == 0 )
  1138. return FALSE; // It should not run to here.
  1139. if( dwOffset <= dwFileCrtOffset + tempExtent.dwExtentLength )
  1140. {
  1141. DWORD dwReadSize;
  1142. dwReadSize = MIN( dwSize, dwFileCrtOffset+tempExtent.dwExtentLength-dwOffset );
  1143. if(!_readSectors(tempExtent.dwExtentLocation, dwOffset - dwFileCrtOffset, dwReadSize, o_pBuffer))
  1144. return FALSE;
  1145. dwOffset += dwReadSize;
  1146. o_pBuffer += dwReadSize;
  1147. dwSize -= dwReadSize;
  1148. }
  1149. dwFileCrtOffset += tempExtent.dwExtentLength;
  1150. i++;
  1151. }
  1152. if( dwSize > 0 )
  1153. {
  1154. tr_printf(("FATAL: UDF_ReadFile() Failed [2]: Over range.n"));
  1155. return FALSE;
  1156. }
  1157. return TRUE;
  1158. }
  1159. extern DWORD g_pDVDVR_PlayQueue;
  1160. extern BYTE g_DVDVR_PlayQueue_Head;
  1161. extern BYTE g_DVDVR_PlayQueue_Tail;
  1162. extern BYTE g_DVDVR_PlayQueue_Size;
  1163. extern BYTE g_DVDVR_ExtentsInFE;
  1164. extern DVDVR_PLAY_QUEUE_NODE g_lastPlayExtent;
  1165. extern BOOL g_ExtentIsPlaying;
  1166. /////////////////////////////////////////////////////////////////////////////
  1167. // UDF_TransferExtentToFE()
  1168. //
  1169. // Description: transfer extent to the Front End
  1170. //
  1171. // Input: None
  1172. // Output: None
  1173. // In/Out: None
  1174. // Return: TRUE if transfer successfully,FALSE otherwise
  1175. //
  1176. // Remarks:
  1177. BOOL UDF_TransferExtentToFE()
  1178. {
  1179. DVDVR_PLAY_QUEUE_NODE node;
  1180. dbg_printf(("UDF_TransferExtentToFE()n"));
  1181. while((g_DVDVR_ExtentsInFE<MAX_PLAY_EXTENT_IN_FE)&&(g_DVDVR_PlayQueue_Size>0)&&gns.dvdvr.bIsSegFinishDone)
  1182. {
  1183. Array_getAt(g_pDVDVR_PlayQueue, g_DVDVR_PlayQueue_Head, (BYTE*)(&node));
  1184. if( drv_play_dvd( node.dwStartLBN, node.dwLength, DRVF_PLAY_DVD_AV_DATA ) )
  1185. {
  1186. {
  1187. DWORD sta=node.dwStartLBN;
  1188. drv_lsn2psn(&sta);
  1189. DEC_LL_SetDVDStartEndSector( sta, node.dwLength );
  1190. }
  1191. gns.dvdvr.bIsDriveDone=FALSE;
  1192. g_DVDVR_PlayQueue_Head = ( g_DVDVR_PlayQueue_Head+1 ) % DVDVR_PLAY_QUEUE_SIZE;
  1193. g_DVDVR_PlayQueue_Size--;
  1194. g_DVDVR_ExtentsInFE++;
  1195. g_lastPlayExtent.dwStartLBN = node.dwStartLBN;
  1196. g_lastPlayExtent.dwLength = node.dwLength;
  1197. g_ExtentIsPlaying = TRUE;
  1198. }
  1199. else
  1200. return FALSE;
  1201. }
  1202. return TRUE;
  1203. }
  1204. /////////////////////////////////////////////////////////////////////////////
  1205. // UDF_TransferExtentToFE()
  1206. //
  1207. // Description: add a new extent to the Play Queue.
  1208. //
  1209. // Input: dwStart - start LBN of the extent
  1210. // dwLength - sector number of the extent
  1211. // Output: None
  1212. // In/Out: None
  1213. // Return: TRUE if transfer successfully,FALSE otherwise
  1214. //
  1215. // Remarks:
  1216. // - If the Front End haven't extent to be played, then transfer this extent to the Front End.
  1217. BOOL _addExtentToPlayQueue(DWORD dwStart, DWORD dwLength)
  1218. {
  1219. DVDVR_PLAY_QUEUE_NODE node;
  1220. dbg_printf(("_addExtentToPlayQueue(0x%08lx, 0x%08lx)n",dwStart, dwLength));
  1221. if( g_DVDVR_PlayQueue_Size >= DVDVR_PLAY_QUEUE_SIZE )
  1222. {
  1223. tr_printf(("FATAL: _addExtentToPlayQueue() Failed [1]: Play quere was full.n"));
  1224. return FALSE;
  1225. }
  1226. node.dwStartLBN=dwStart;
  1227. node.dwLength=dwLength;
  1228. Array_setAt(g_pDVDVR_PlayQueue, g_DVDVR_PlayQueue_Tail, (BYTE*)(&node));
  1229. g_DVDVR_PlayQueue_Tail= (g_DVDVR_PlayQueue_Tail+1) % DVDVR_PLAY_QUEUE_SIZE;
  1230. g_DVDVR_PlayQueue_Size++;
  1231. //UDF_TransferExtentToFE();
  1232. return TRUE;
  1233. }
  1234. /////////////////////////////////////////////////////////////////////////////
  1235. // UDF_PlayExtents()
  1236. //
  1237. // Description: play a part of a file.
  1238. //
  1239. // Input: pFileHandle - points to the extents table of the playback file
  1240. // dwOffset - start sector number from the file begining
  1241. // dwSize - playback size by sector
  1242. // Output: None
  1243. // In/Out: None
  1244. // Return: TRUE if play successfully,FALSE otherwise
  1245. //
  1246. // Remarks:
  1247. BOOL UDF_PlayExtents(DWORD pFileHandle, DWORD dwOffset, DWORD dwSize)
  1248. {
  1249. int i=1;
  1250. Extent_ad tempExtent;
  1251. DWORD dwFileExtentCnt,dwCrtLBN=0,dwPlayLength=0;
  1252. if((DWORD)NULL==pFileHandle)
  1253. {
  1254. tr_printf(("FATAL: UDF_PlayExtents() Failed [1]: pFileHandle is NULL.n"));
  1255. return FALSE;
  1256. }
  1257. //dwCrtLBN = dwOffset + g_pUDFInfo->dwMainPartitionLocation;
  1258. Array_getAt(pFileHandle, 0, (BYTE*)(&tempExtent));
  1259. dwFileExtentCnt=tempExtent.dwExtentLength;
  1260. while( i<=dwFileExtentCnt && dwSize>0 && Array_getAt(pFileHandle, i, (BYTE*)(&tempExtent)) )
  1261. {
  1262. tempExtent.dwExtentLength &= ~ALLOCATION_EXTENT_INTERPRETATION;
  1263. if( tempExtent.dwExtentLength == 0 || tempExtent.dwExtentLocation == 0 )
  1264. return FALSE; // It should not run to here.
  1265. tempExtent.dwExtentLocation += g_pUDFInfo->dwMainPartitionLocation;
  1266. tempExtent.dwExtentLength = (tempExtent.dwExtentLength+LOGICAL_BLOCK_SIZE-1)/ LOGICAL_BLOCK_SIZE;
  1267. if( dwOffset < dwCrtLBN + tempExtent.dwExtentLength )
  1268. {
  1269. dwPlayLength = MIN( dwSize, dwCrtLBN+tempExtent.dwExtentLength-dwOffset );
  1270. if( !_addExtentToPlayQueue(tempExtent.dwExtentLocation+dwOffset-dwCrtLBN, dwPlayLength) )
  1271. return FALSE;
  1272. dwOffset += dwPlayLength;
  1273. dwSize -= dwPlayLength;
  1274. }
  1275. dwCrtLBN += tempExtent.dwExtentLength;
  1276. i++;
  1277. }
  1278. UDF_TransferExtentToFE();
  1279. if( g_DVDVR_PlayQueue_Size == 0 )
  1280. { //this playback is only one extent.
  1281. ie_send_ex(IE_CORE_PLAYBACK_FINISHIED,(void*)QUE_PlaybackFinished);
  1282. }
  1283. if( dwSize > 0 )
  1284. {
  1285. tr_printf(("FATAL: UDF_PlayExtents() Failed [2]: Over range.n"));
  1286. return FALSE;
  1287. }
  1288. return TRUE;
  1289. }
  1290. #endif
  1291. /////////////////////////////////////////////////////////////////////////////
  1292. // Private Services
  1293. /////////////////////////////////////////////////////////////////////////////
  1294. // _initializeUDF102()
  1295. //
  1296. // Description: Initializes a UDF-1.02 File-System.
  1297. //
  1298. // Input: bIsUDFBridge - Indicates whether or not the UDF instance is
  1299. //    recorded in UDF-Bridge format.
  1300. // Output: None
  1301. // In/Out: None
  1302. // Return: TRUE if the initialization was successful; FALSE othewise.
  1303. //
  1304. // Remarks:
  1305. // 1. Depending on whether or not UDF was recorded in UDF-Bridge format,
  1306. //    the absolute address of the Volume-Recognition-Sequence is determined.
  1307. // 2. The method will look for the NSR02 descriptor, indicating UDF-1.02.
  1308. #define DESC_BUFFER_SZ 33
  1309. BOOL _initializeUDF102(void)
  1310. {
  1311. BOOL bNSRFound= FALSE;
  1312. BOOL bRootDirEstablished= FALSE;
  1313. UINT16 uMVDS_Size= 0;
  1314. //UINT16 uFSDS_Size= 0;
  1315. UINT32 ulPartitionSize= 0;
  1316. DWORD dwMVDS_Location, dwFSDS_Location;
  1317. DWORD dwCurrDescLBN;
  1318. BYTE *pDescBuffer;
  1319. Tag *pDescTag;
  1320. struct GenericVolumeStructureDesc_Base *pCurrDescHdr;
  1321. struct AnchorVolumeDescPtr *pAnchorVolDescPtr;
  1322. dbg_printf(("_initializeUDF102() calling.n"));
  1323. // Allocate space for a generic Descriptor base
  1324. pCurrDescHdr= (struct GenericVolumeStructureDesc_Base*)malloc(sizeof(struct GenericVolumeStructureDesc_Base));
  1325. if (NULL == pCurrDescHdr) {
  1326. dbg_printf(("WARNING: _initializeUDF102() Failed [1]: Low system resourcesn"));
  1327. return FALSE;
  1328. }
  1329. // Verify Integrity of the Volume Recognition Sequence, by searching for
  1330. // the first Volume-Structure Descriptor ("NSR" Descriptor)
  1331. dwCurrDescLBN= (g_pUDFInfo->dwSessionStartLBN + VOLUME_RECOGNITION_SEQUENCE_START_LSN);
  1332. while (dwCurrDescLBN < g_pUDFInfo->dwSessionStartLBN + VOLUME_RECOGNITION_SEQUENCE_START_LSN+16) 
  1333. {
  1334. // Read the Descriptor's Header in order to determine the type of the descriptor
  1335. if (! AuxCache_GetBytes(dwCurrDescLBN, 0, sizeof(struct GenericVolumeStructureDesc_Base), 
  1336.    (BYTE*)pCurrDescHdr)) 
  1337. {
  1338. dbg_printf(("WARNING: _initializeUDF102() Failed [2]n"));
  1339. break;
  1340. }
  1341. #ifdef _DEBUG
  1342. // Check for a Beginning Extended Area Descriptor
  1343. if (0 == strncmp((LPCSTR)pCurrDescHdr->aStandardID, STANDARD_ID_BEA01, STANDARD_ID_LEN)) {
  1344. dbg_printf(("Beginning of Extended Area Descriptor found.n"));
  1345. dwCurrDescLBN++; // Skip to the next Descriptor
  1346. continue;
  1347. }
  1348. // Check for a Boot Descriptor
  1349. if (0 == strncmp((LPCSTR)pCurrDescHdr->aStandardID, STANDARD_ID_BOOT2, STANDARD_ID_LEN)) {
  1350. dbg_printf(("Boot Descriptor found.n"));
  1351. dwCurrDescLBN++; // Skip to the next Descriptor
  1352. continue;
  1353. }
  1354. #endif //_DEBUG
  1355. // Check for an NSR02 Descriptor
  1356. if (0 == strncmp((LPCSTR)pCurrDescHdr->aStandardID, STANDARD_ID_NSR02, STANDARD_ID_LEN)) {
  1357. bNSRFound= TRUE;
  1358. break;
  1359. }
  1360. //<<MikeX_0524_2004_A: Check for an NSR03 Descriptor
  1361. if (0 == strncmp((LPCSTR)pCurrDescHdr->aStandardID, STANDARD_ID_NSR03, STANDARD_ID_LEN)) {
  1362. bNSRFound= TRUE;
  1363. break;
  1364. }
  1365. //MikeX_0524_2004_A>>
  1366. // Check for a Terminating Extended Area Descriptor
  1367. if (0 == strncmp((LPCSTR)pCurrDescHdr->aStandardID, STANDARD_ID_TEA01, STANDARD_ID_LEN)) {
  1368. dbg_printf(("Volume-Recognition-Sequence Termination found.n"));
  1369. break;
  1370. }
  1371. // Any other Descriptor is not of interest -- just skip to the next one
  1372. dbg_printf(("Skipping Volume-Descriptor of type: 0x%02x.n", pCurrDescHdr->uStructureType));
  1373. dwCurrDescLBN++;
  1374. } //endof while
  1375. free(pCurrDescHdr);
  1376. //MikeX_0617_2004_A: Patch!!! Can play the DVD disc without PVD.
  1377. /* if (! bNSRFound) {
  1378. dbg_printf(("WARNING: _initializeUDF102() Failed [3]n"));
  1379. return FALSE;
  1380. }
  1381. */
  1382. // Allocate space for a Descriptor Buffer, that will hold a Descriptor-fraction
  1383. pDescBuffer= (BYTE*)malloc(DESC_BUFFER_SZ);
  1384. if (NULL == pDescBuffer) {
  1385. dbg_printf(("WARNING: _initializeUDF102() Failed [4]: Low system resorucesn"));
  1386. return FALSE;
  1387. }
  1388. // Locate the First Anchor-Point which contains an Anchor Volume-Descriptor Pointer
  1389. if (! AuxCache_GetBytes((g_pUDFInfo->dwSessionStartLBN + FIRST_ANCHOR_POINT_LSN), 0, 
  1390.    DESC_BUFFER_SZ, pDescBuffer)) 
  1391. {
  1392. dbg_printf(("WARNING: _initializeUDF102() Failed [5]n"));
  1393. free(pDescBuffer);
  1394. return FALSE;
  1395. }
  1396. pAnchorVolDescPtr= (struct AnchorVolumeDescPtr *)pDescBuffer;
  1397. // Verify Integrity of the Anchor Volume-Descriptor Pointer
  1398. if ((TAG_ID_ANCHOR_VOLUME_DESC_PTR != LE_WORD(pAnchorVolDescPtr->tgDescTag.uTagID)) ||
  1399. (FIRST_ANCHOR_POINT_LSN != LE_DWORD(pAnchorVolDescPtr->tgDescTag.dwTagLocation))) 
  1400. {
  1401. dbg_printf(("WARNING: _initializeUDF102() Failed [6]n"));
  1402. free(pDescBuffer);
  1403. return FALSE;
  1404. }
  1405. // Extract the Location and Length of the Main Volume Descriptor Sequence (MVDS)
  1406. dwMVDS_Location= LE_DWORD(pAnchorVolDescPtr->exMainVolumeDescSequenceExtent.dwExtentLocation);
  1407. uMVDS_Size= (UINT16)((LE_DWORD(pAnchorVolDescPtr->exMainVolumeDescSequenceExtent.dwExtentLength) - 1) / LOGICAL_BLOCK_SIZE);
  1408. // Check for a possible Error
  1409. if ((0 == dwMVDS_Location) || (0 == uMVDS_Size)) {
  1410. // Extract the Reserve Descriptor information
  1411. dwMVDS_Location= LE_DWORD(pAnchorVolDescPtr->exReserveVolumeDescSequenceExtent.dwExtentLocation);
  1412. uMVDS_Size= (UINT16)((LE_DWORD(pAnchorVolDescPtr->exReserveVolumeDescSequenceExtent.dwExtentLength) - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1413. // Make sure that a Reserve Descriptor is indeed available
  1414. if (0 == uMVDS_Size) {
  1415. dbg_printf(("WARNING: _initializeUDF102() Failed [7]n"));
  1416. free(pDescBuffer);
  1417. return FALSE;
  1418. }
  1419. }
  1420. // Enumerate the Main Volume Descriptor Sequence, one Descriptor at a time,
  1421. // until all required information is obtained.
  1422. dwCurrDescLBN= dwMVDS_Location;
  1423. while (uMVDS_Size) 
  1424. {
  1425. if (! AuxCache_GetBytes(dwCurrDescLBN, 0, DESC_BUFFER_SZ, pDescBuffer)) {
  1426. dbg_printf(("WARNING: _initializeUDF102() Failed [8]n"));
  1427. break;
  1428. }
  1429. pDescTag= (Tag*)pDescBuffer;
  1430. // Check for a Primary-Volume Descriptor
  1431. if (TAG_ID_PRIMARY_VOLUME_DESC == LE_WORD(pDescTag->uTagID)) {
  1432. char szPrimaryVolumeName[32];
  1433. WCHAR szwPrimaryVolumeName[32];
  1434. dbg_printf(("Primary Volume Descriptor found.n"));
  1435. // Copy the Primary-Volume Name
  1436. AuxCache_GetBytes(dwCurrDescLBN, (1+PRIMARY_VOLUME_DESC_INFO_OFFSET), 31,
  1437.  (BYTE*)szPrimaryVolumeName);
  1438. szPrimaryVolumeName[31]= 0;
  1439. _str2wcs(szPrimaryVolumeName, szwPrimaryVolumeName, sizeof(szwPrimaryVolumeName));
  1440. sc_SetBytes(SC_VOLUME_ID_ADDR, 0, FILESYSTEM_MAX_VOLUME_NAME*sizeof(WCHAR), szwPrimaryVolumeName);
  1441. #ifdef HW_POWER_ON_RESUME         
  1442. {
  1443. // Calculate checksum here for poweron resume
  1444. // Calculating checksum using simple mechanism of adding each byte of the 
  1445.           int i;
  1446.           BYTE atemp[8];
  1447. NewChecksum = 0;
  1448. for (i=0;i<31;i++)
  1449. NewChecksum += szPrimaryVolumeName[i];
  1450. AuxCache_GetBytes(dwCurrDescLBN, (1+VOLUME_SET_IDENTIFIER), 8,
  1451.  (BYTE*)atemp);
  1452. for(i=0;i<8;i++)
  1453. NewChecksum+=atemp[i];
  1454. }
  1455. #endif //HW_POWER_ON_RESUME
  1456. dbg_printf(("Volume-ID: '%s'n", szPrimaryVolumeName));
  1457. }
  1458. // Check for a Partition-Descriptor
  1459. if (TAG_ID_PARTITION_DESC == LE_WORD(pDescTag->uTagID)) {
  1460. struct {
  1461. UINT32 dwPartitionStartingLocation;
  1462. UINT32 uPartitionLength;
  1463. } PartitionDescInfo;
  1464. AuxCache_GetBytes(dwCurrDescLBN, PARTITION_DESC_INFO_OFFSET, sizeof(PartitionDescInfo),
  1465.  (BYTE*)&PartitionDescInfo);
  1466. g_pUDFInfo->dwMainPartitionLocation= LE_DWORD(PartitionDescInfo.dwPartitionStartingLocation);
  1467. ulPartitionSize= LE_DWORD(PartitionDescInfo.uPartitionLength);
  1468. }
  1469. // Check for a Logical-Volume Descriptor
  1470. if (TAG_ID_LOGICAL_VOLUME_DESC == LE_WORD(pDescTag->uTagID)) {
  1471. Long_ad ladFSDInfo;
  1472. // Cast the Contents-Use to a Long_ad (DVD-RW Part 2, Section 2.6.7)
  1473. AuxCache_GetBytes(dwCurrDescLBN, LOGICAL_VOLUME_DESC_INFO_OFFSET, sizeof(Long_ad),
  1474.  (BYTE*)&ladFSDInfo);
  1475. dwFSDS_Location= LE_WORD(ladFSDInfo.lbaExtentLocation.uLogicalBlockNumber);
  1476. //uFSDS_Size= (UINT16)((LE_DWORD(ladFSDInfo.cbExtentLength) + (UINT32)LOGICAL_BLOCK_SIZE - 1) / (UINT32)LOGICAL_BLOCK_SIZE);//Hamadk_0908_2003_a:Fixed a bug in intializing of the file system
  1477. }
  1478. // Check for a Terminating Descriptor
  1479. if (TAG_ID_TERMINATING_DESC == LE_WORD(pDescTag->uTagID))
  1480. break;
  1481. // Move to the next Descriptor
  1482. dwCurrDescLBN++;
  1483. uMVDS_Size--;
  1484. }
  1485. // Make sure that there is enough information to access the File-Set Descriptor
  1486. if ((0 == uMVDS_Size) || (0 == ulPartitionSize)/* || (0 == uFSDS_Size)*/) {
  1487. free(pDescBuffer);
  1488. dbg_printf(("WARNING: _initializeUDF102() Failed [9]n"));
  1489. return FALSE;
  1490. }
  1491. // Establish the absolute LBA of the File-Set Descriptor Sequence, which is also
  1492. // the fixed Offset needed to be added to any LBN in order to get the absoulte
  1493. // LBA of Files and Directories.
  1494. g_pUDFInfo->dwLBA_Offset= (g_pUDFInfo->dwMainPartitionLocation + dwFSDS_Location);
  1495. // Enumerate the File-Set Descriptor Sequence, until a File-Set Descriptor is found.
  1496. // From that File-Set Descriptor, extract the ICB corresponding to the Root-Directory.
  1497. dwCurrDescLBN= g_pUDFInfo->dwLBA_Offset;
  1498. //Get the File Set Descriptor directly without checking if the size read our from logical volume descriptor.
  1499. //while (uFSDS_Size) {
  1500. if (! AuxCache_GetBytes(dwCurrDescLBN, 0, DESC_BUFFER_SZ, pDescBuffer)) {
  1501. dbg_printf(("WARNING: _initializeUDF102() Failed [10]n"));
  1502. // break;
  1503. }
  1504. pDescTag= (Tag*)pDescBuffer;
  1505. if (TAG_ID_FILE_SET_DESC == LE_WORD(pDescTag->uTagID)) {
  1506. Long_ad ladRootDirICB;
  1507. // Extract the location of the Root Directory
  1508. AuxCache_GetBytes(dwCurrDescLBN, FILE_SET_DESC_INFO_OFFSET, sizeof(Long_ad),
  1509.  (BYTE*)&ladRootDirICB);
  1510. g_pUDFInfo->dwRootDirICB= LE_DWORD(ladRootDirICB.lbaExtentLocation.uLogicalBlockNumber);
  1511. bRootDirEstablished= TRUE;
  1512. //break;
  1513. }
  1514. if (TAG_ID_TERMINATING_DESC == LE_WORD(pDescTag->uTagID))
  1515. //break;
  1516. // Move to the next Descriptor
  1517. //dwCurrDescLBN++;
  1518. //uFSDS_Size--;
  1519. //}
  1520. // When this point is reached, the entire File-Set Descriptor Sequence has been
  1521. // scanned, and the Root-Directory's ICB possibly established.
  1522. free(pDescBuffer);
  1523. // Set the Current Directory to the Root-Directory, if it was established.
  1524. if (bRootDirEstablished)
  1525. g_pUDFInfo->dwCurrDirICB= g_pUDFInfo->dwRootDirICB;
  1526. g_pUDFInfo->uRevision= 0x0102;
  1527. return bRootDirEstablished;
  1528. }
  1529. /////////////////////////////////////////////////////////////////////////////
  1530. // _initializeUDF200()
  1531. //
  1532. // Description: Initializes a UDF-2.00 File-System.
  1533. //
  1534. // Input: bIsUDFBridge - Indicates whether or not the UDF instance is
  1535. //    recorded in UDF-Bridge format.
  1536. // Output: None
  1537. // In/Out: None
  1538. // Return: TRUE if the initialization was successful; FALSE othewise.
  1539. //
  1540. // Remarks:
  1541. // 1. Depending on whether or not UDF was recorded in UDF-Bridge format,
  1542. //    the absolute address of the Volume-Recognition-Sequence is determined.
  1543. // 2. The method will look for the NSR03 descriptor, indicating UDF-2.00 and
  1544. //    higher.
  1545. // 3. The Integrity of the Volume is verified using the Logical-Volume-
  1546. //    Integrity Descriptor.
  1547. // 4. The Sparable-Partition and Sparing-Table are established.
  1548. BOOL _initializeUDF200(void)
  1549. {
  1550. #ifndef UDF_SUPPORT_UDF201
  1551. return FALSE;
  1552. #else
  1553. /*
  1554. BOOL bNSRFound= FALSE;
  1555. BOOL bVolumeIntegrityVerified= FALSE;
  1556. BOOL bRootDirEstablished= FALSE;
  1557. UINT16 uMVDS_Size= 0;
  1558. UINT16 uPartitionSize= 0;
  1559. UINT16 uPartitionNumber;
  1560. UINT16 uLVIS_Size= 0;
  1561. UINT16 uFSDS_Size= 0;
  1562. DWORD dwMVDS_Location, dwLVIS_Location, dwFSDS_Location;
  1563. DWORD dwCurrDescLBN;
  1564. BYTE *pDescBuffer;
  1565. Tag *pDescTag;
  1566. struct GenericVolumeStructureDesc *pCurrDesc;
  1567. struct AnchorVolumeDescPtr *pAnchorVolDescPtr;
  1568. dbg_printf(("_initializeUDF200() calling.n"));
  1569. // Allocate space for a generic Descriptor (all Descriptors are not larger than
  1570. // a single Logical-Block).
  1571. pDescBuffer= (BYTE*)malloc(LOGICAL_BLOCK_SIZE);
  1572. if (NULL == pDescBuffer) {
  1573. dbg_printf(("WARNING: _initializeUDF200() Failed [1]n"));
  1574. return FALSE;
  1575. }
  1576. // Verify Integrity of the Volume Recognition Sequence, by searching for
  1577. // the first Volume-Structure Descriptor ("NSR" Descriptor)
  1578. dwCurrDescLBN= (g_pUDFInfo->dwSessionStartLBN + VOLUME_RECOGNITION_SEQUENCE_START_LSN);
  1579. while (TRUE) {
  1580. if (! AuxCache_GetBytes(dwCurrDescLBN, 0, LOGICAL_BLOCK_SIZE, pDescBuffer)) {
  1581. free(pDescBuffer);
  1582. dbg_printf(("WARNING: _initializeUDF200() Failed [2]n"));
  1583. return FALSE;
  1584. }
  1585. pCurrDesc= (struct GenericVolumeStructureDesc*)pDescBuffer;
  1586. // Check for a Beginning Extended Aread Descriptor
  1587. if (0 == strncmp((LPCSTR)pCurrDesc->aStandardID, STANDARD_ID_BEA01, STANDARD_ID_LEN)) {
  1588. dwCurrDescLBN++; // Skip to the next Descriptor
  1589. continue;
  1590. }
  1591. // Check for a Boot Descriptor
  1592. if (0 == strncmp((LPCSTR)pCurrDesc->aStandardID, STANDARD_ID_BOOT2, STANDARD_ID_LEN)) {
  1593. dwCurrDescLBN++; // Skip to the next Descriptor
  1594. continue;
  1595. }
  1596. // Check for an NSR03 Descriptor
  1597. if (0 == strncmp((LPCSTR)pCurrDesc->aStandardID, STANDARD_ID_NSR03, STANDARD_ID_LEN)) {
  1598. bNSRFound= TRUE;
  1599. break;
  1600. }
  1601. // Check for a Terminating Extended Area Descriptor
  1602. if (0 == strncmp((LPCSTR)pCurrDesc->aStandardID, STANDARD_ID_TEA01, STANDARD_ID_LEN))
  1603. break;
  1604. // Any other Descriptor is not of interest -- just skip to the next one
  1605. dwCurrDescLBN++;
  1606. }
  1607. if (! bNSRFound) {
  1608. free(pDescBuffer);
  1609. dbg_printf(("WARNING: _initializeUDF200() Failed [3]n"));
  1610. return FALSE;
  1611. }
  1612. // Locate the First Anchor-Point which contains an Anchor Volume-Descriptor Pointer
  1613. if (! AuxCache_GetBytes(FIRST_ANCHOR_POINT_LSN, 0, LOGICAL_BLOCK_SIZE, pDescBuffer)) {
  1614. free(pDescBuffer);
  1615. dbg_printf(("WARNING: _initializeUDF200() Failed [4]n"));
  1616. return FALSE;
  1617. }
  1618. pAnchorVolDescPtr= (struct AnchorVolumeDescPtr *)pDescBuffer;
  1619. // Verify Integrity of the Anchor Volume-Descriptor Pointer
  1620. if ((TAG_ID_ANCHOR_VOLUME_DESC_PTR != LE_WORD(pAnchorVolDescPtr->tgDescTag.uTagID)) ||
  1621. (FIRST_ANCHOR_POINT_LSN != LE_DWORD(pAnchorVolDescPtr->tgDescTag.dwTagLocation))) {
  1622. free(pDescBuffer);
  1623. dbg_printf(("WARNING: _initializeUDF200() Failed [5]n"));
  1624. return FALSE;
  1625. }
  1626. // Extract the Location and Length of the Main Volume Descriptor Sequence (MVDS)
  1627. dwMVDS_Location= LE_DWORD(pAnchorVolDescPtr->exMainVolumeDescSequenceExtent.dwExtentLocation);
  1628. uMVDS_Size= (UINT16)((LE_DWORD(pAnchorVolDescPtr->exMainVolumeDescSequenceExtent.dwExtentLength) - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1629. // Check for a possible Error
  1630. if ((0 == dwMVDS_Location) || (0 == uMVDS_Size)) {
  1631. // Extract the Reserve Descriptor information
  1632. dwMVDS_Location= LE_DWORD(pAnchorVolDescPtr->exReserveVolumeDescSequenceExtent.dwExtentLocation);
  1633. uMVDS_Size= (UINT16)((LE_DWORD(pAnchorVolDescPtr->exReserveVolumeDescSequenceExtent.dwExtentLength) - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1634. // Make sure that a Reserve Descriptor is indeed available
  1635. if (0 == uMVDS_Size)
  1636. return FALSE;
  1637. }
  1638. // Enumerate the Main Volume Descriptor Sequence, one Descriptor at a time,
  1639. // until all required information is obtained.
  1640. dwCurrDescLBN= dwMVDS_Location;
  1641. while (uMVDS_Size) {
  1642. if (! AuxCache_GetBytes(dwCurrDescLBN, 0, LOGICAL_BLOCK_SIZE, pDescBuffer)) {
  1643. free(pDescBuffer);
  1644. dbg_printf(("WARNING: _initializeUDF200() Failed [6]n"));
  1645. return FALSE;
  1646. }
  1647. pDescTag= (Tag*)pDescBuffer;
  1648. // Check for a Primary-Volume Descriptor
  1649. if (TAG_ID_PRIMARY_VOLUME_DESC == LE_WORD(pDescTag->uTagID)) {
  1650. struct PrimaryVolumeDesc *pPVD= (struct PrimaryVolumeDesc *)pDescBuffer;
  1651. dbg_printf(("Primary Volume Descriptor found.n"));
  1652. // Copy the Primary-Volume Name
  1653. strncpy(g_pUDFInfo->szPrimaryVolumeName, (LPCSTR)&pPVD->sVolumeID[1], 31);
  1654. g_pUDFInfo->szPrimaryVolumeName[31]= 0;
  1655. dbg_printf(("Volume-ID: '%s'n", g_pUDFInfo->szPrimaryVolumeName));
  1656. dbg_printf(("Volume-Set ID: '%s'n", (LPCSTR)&pPVD->sVolumeSetID[1]));
  1657. dbg_printf(("Volume recorded on: %d/%02d/%04d %02d:%02d:%02d.n",
  1658. pPVD->tsRecording.uDay, pPVD->tsRecording.uMonth, LE_WORD(pPVD->tsRecording.iYear),
  1659. pPVD->tsRecording.uHour, pPVD->tsRecording.uMinute, pPVD->tsRecording.uSecond));
  1660. }
  1661. // Check for a Partition-Descriptor
  1662. if (TAG_ID_PARTITION_DESC == LE_WORD(pDescTag->uTagID)) {
  1663. struct PartitionDesc *pPartitionDesc= (struct PartitionDesc *)pDescBuffer;
  1664. struct PartitionHeaderDesc *pPartitionHdrDesc;
  1665. g_pUDFInfo->dwMainPartitionLocation= LE_DWORD(pPartitionDesc->dwPartitionStartingLocation);
  1666. uPartitionSize= (UINT16)((LE_DWORD(pPartitionDesc->uPartitionLength) - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1667. uPartitionNumber= pPartitionDesc->uPartitionNumber;
  1668. // Cast the Contents-Use to a Partition-Header Descriptor, and extract
  1669. // the necessary info (DVD-RW Part 2, Section 2.6.6)
  1670. pPartitionHdrDesc= (struct PartitionHeaderDesc *)pPartitionDesc->aPartitionContentsUse;
  1671. g_pUDFInfo->sadMainPartitionUnallocSpaceBitmap= pPartitionHdrDesc->sadUnallocSpaceBitmap;
  1672. // Note: Additional information about the Partition will be obtained from the
  1673. //       Logical Volume Descriptor.
  1674. }
  1675. // Check for a Logical-Volume Descriptor
  1676. if (TAG_ID_LOGICAL_VOLUME_DESC == LE_WORD(pDescTag->uTagID)) {
  1677. DWORD uPartitionMapsCnt;
  1678. struct LogicalVolumeDesc *pLVD= (struct LogicalVolumeDesc *)pDescBuffer;
  1679. struct PartitionMapGeneric *pGenPartitionMap;
  1680. struct PartitionMapType2_SparablePartition *pSparablePartitionMap= NULL;
  1681. // Cast the Contents-Use to a Long_ad (DVD-RW Part 2, Section 2.6.7)
  1682. Long_ad *pFSDInfo= (Long_ad*)pLVD->aLogicalVolumeContentsUse;
  1683. dwFSDS_Location= LE_WORD(pFSDInfo->lbaExtentLocation.uLogicalBlockNumber);
  1684. uFSDS_Size= (UINT16)((LE_DWORD(pFSDInfo->cbExtentLength) - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1685. // Extract the location and size of the Logical Volume Integrity Sequence
  1686. dwLVIS_Location= LE_DWORD(pLVD->exIntegritySequenceExtent.dwExtentLocation);
  1687. uLVIS_Size= (UINT16)((LE_DWORD(pLVD->exIntegritySequenceExtent.dwExtentLength) - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1688. // Gather some additional Partition information, by examining the Partition-Maps
  1689. uPartitionMapsCnt= LE_DWORD(pLVD->uNumberOfPartitionMaps);
  1690. pGenPartitionMap= (struct PartitionMapGeneric*)(pDescBuffer + sizeof(struct LogicalVolumeDesc));
  1691. // Seek for a Type2 Partition-Map, describing the Sparable Partition corresponding
  1692. // to the Main Partition.
  1693. g_pUDFInfo->bUseSparingManagement= FALSE;
  1694. g_pUDFInfo->pMainPartitionSparingTable= NULL;
  1695. while (uPartitionMapsCnt) {
  1696. if (PARTITION_MAP_TYPE_2 == pGenPartitionMap->uPartitionMapType) {
  1697. // Cast to a Sparable-Partition Map
  1698. pSparablePartitionMap= (struct PartitionMapType2_SparablePartition *)pGenPartitionMap;
  1699. // Make sure that it's the correct type
  1700. if (0 == strcmp(ENTITYID_SPARABLE_PARTITION, (LPCSTR)pSparablePartitionMap->eidPartitionTypeID.aIdentifier)) {
  1701. g_pUDFInfo->bUseSparingManagement= TRUE;
  1702. break;
  1703. }
  1704. }
  1705. // Move to the next Partition-Map
  1706. ((BYTE*)pGenPartitionMap) += pGenPartitionMap->cbPartitionMapLength;
  1707. uPartitionMapsCnt--;
  1708. }
  1709. // Check if the Sparable Partition Map was located
  1710. if ( g_pUDFInfo->bUseSparingManagement &&
  1711.  (0 != uPartitionMapsCnt) && 
  1712.  (uPartitionNumber == pSparablePartitionMap->uPartitionNumber) &&
  1713.  (0 != pSparablePartitionMap->cbSparingTableSize) ) 
  1714. {
  1715. DWORD dwSparingTableAddr= 0;
  1716. DWORD cbSparingTableSize= 0;
  1717. // Extract the necessary information and allocate space for the Sparing-Table
  1718. g_pUDFInfo->uSparingPacketLength= LE_WORD(pSparablePartitionMap->uPacketLength);
  1719. dwSparingTableAddr= LE_DWORD(pSparablePartitionMap->aLocationsOfSparingTables[0]);
  1720. cbSparingTableSize= LE_DWORD(pSparablePartitionMap->cbSparingTableSize);
  1721. g_pUDFInfo->pMainPartitionSparingTable= (struct SparingTable*)malloc((UINT16)cbSparingTableSize);
  1722. if (NULL == g_pUDFInfo->pMainPartitionSparingTable) {
  1723. uPartitionSize= 0;
  1724. break;
  1725. }
  1726. // Load the Sparing-Table
  1727. if (! AuxCache_GetBytes(dwSparingTableAddr, 0, (UINT16)cbSparingTableSize, (BYTE*)g_pUDFInfo->pMainPartitionSparingTable))
  1728. {
  1729. free(g_pUDFInfo->pMainPartitionSparingTable);
  1730. uPartitionSize= 0;
  1731. break;
  1732. }
  1733. }
  1734. }
  1735. // Check for a Terminating Descriptor
  1736. if (TAG_ID_TERMINATING_DESC == LE_WORD(pDescTag->uTagID))
  1737. break;
  1738. // Move to the next Descriptor
  1739. dwCurrDescLBN++;
  1740. uMVDS_Size--;
  1741. }
  1742. // Make sure that there is enough information to access the File-Set Descriptor
  1743. if ((0 == uMVDS_Size) || (0 == uPartitionSize) || (0 == uFSDS_Size)) {
  1744. free(pDescBuffer);
  1745. dbg_printf(("WARNING: _initializeUDF200() Failed [7]n"));
  1746. return FALSE;
  1747. }
  1748. // Enumerate the Logical Volume Integrity Sequence, until a Close Logical Volume 
  1749. // Integrity Descriptor is found.
  1750. // In that Descriptor, examine and validate the UDF Revision.
  1751. dwCurrDescLBN= dwLVIS_Location;
  1752. while (uLVIS_Size) {
  1753. if (! AuxCache_GetBytes(dwCurrDescLBN, 0, LOGICAL_BLOCK_SIZE, pDescBuffer)) {
  1754. free(pDescBuffer);
  1755. dbg_printf(("WARNING: _initializeUDF200() Failed [8]n"));
  1756. return FALSE;
  1757. }
  1758. pDescTag= (Tag*)pDescBuffer;
  1759. if (TAG_ID_LOGICAL_VOLUME_INTEGRITY == LE_WORD(pDescTag->uTagID)) {
  1760. struct LogicalVolumeIntegrityDesc *pLVID= (struct LogicalVolumeIntegrityDesc *)pDescBuffer;
  1761. if (INTEGRITY_TYPE_CLOSE == LE_DWORD(pLVID->dwIntegrityType)) {
  1762. struct LogicalVolumeIntegrityDescImplUse *pImplUse= 
  1763. (struct LogicalVolumeIntegrityDescImplUse*)((BYTE*)pLVID + 
  1764. sizeof(struct LogicalVolumeIntegrityDesc) + 
  1765. (8 * (UINT16)LE_DWORD(pLVID->uNumberOfPartitions)));
  1766. // Verify the appropriate UDF Revision
  1767. if (0x0200 == LE_WORD(pImplUse->uMinimumUDFReadRevision))
  1768. bVolumeIntegrityVerified= TRUE;
  1769. }
  1770. }
  1771. if (TAG_ID_TERMINATING_DESC == LE_WORD(pDescTag->uTagID))
  1772. break;
  1773. // Move to the next Descriptor
  1774. dwCurrDescLBN++;
  1775. uLVIS_Size--;
  1776. }
  1777. // Make sure that the Volume's Integrity was verified
  1778. if (! bVolumeIntegrityVerified) {
  1779. free(pDescBuffer);
  1780. dbg_printf(("WARNING: _initializeUDF200() Failed [9]n"));
  1781. return FALSE;
  1782. }
  1783. // Establish the absolute LBA of the File-Set Descriptor Sequence, which is also
  1784. // the fixed Offset needed to be added to any LBN in order to get the absoulte
  1785. // LBA of Files and Directories.
  1786. g_pUDFInfo->dwLBA_Offset= _absoluteLBA(dwFSDS_Location);
  1787. // Enumerate the File-Set Descriptor Sequence, until a File-Set Descriptor is found.
  1788. // From that File-Set Descriptor, extract the ICB corresponding to the Root-Directory.
  1789. dwCurrDescLBN= dwFSDS_Location;
  1790. while (uFSDS_Size) {
  1791. if (! AuxCache_GetBytes(_absoluteLBA(dwCurrDescLBN), 0, LOGICAL_BLOCK_SIZE, pDescBuffer)) {
  1792. free(pDescBuffer);
  1793. dbg_printf(("WARNING: _initializeUDF200() Failed [10]n"));
  1794. return FALSE;
  1795. }
  1796. pDescTag= (Tag*)pDescBuffer;
  1797. if (TAG_ID_FILE_SET_DESC == LE_WORD(pDescTag->uTagID)) {
  1798. // Extract the location of the Root Directory
  1799. struct FileSetDesc *pFSD= (struct FileSetDesc *)pDescBuffer;
  1800. g_pUDFInfo->ladRootDirICB= pFSD->ladRootDirICB;
  1801. bRootDirEstablished= TRUE;
  1802. break;
  1803. }
  1804. if (TAG_ID_TERMINATING_DESC == LE_WORD(pDescTag->uTagID))
  1805. break;
  1806. // Move to the next Descriptor
  1807. dwCurrDescLBN++;
  1808. uFSDS_Size--;
  1809. }
  1810. // When this point is reached, the entire File-Set Descriptor Sequence has been
  1811. // scanned, and the Root-Directory's ICB possibly established.
  1812. free(pDescBuffer);
  1813. // Set the Current Directory to the Root-Directory, if it was established.
  1814. if (bRootDirEstablished)
  1815. g_pUDFInfo->ladCurrDirICB= g_pUDFInfo->ladRootDirICB;
  1816. g_pUDFInfo->uRevision= 0x0200;
  1817. return bRootDirEstablished;
  1818. */
  1819. #ifdef DVD_VR_SUPPORT
  1820. BOOL bNSRFound= FALSE;
  1821. BOOL bVolumeIntegrityVerified= FALSE;
  1822. BOOL bRootDirEstablished= FALSE;
  1823. UINT16 uMVDS_Size= 0;
  1824. UINT16 uPartitionSize= 0;
  1825. UINT16 uPartitionNumber;
  1826. UINT16 uLVIS_Size= 0;
  1827. UINT16 uFSDS_Size= 0;
  1828. DWORD dwMVDS_Location, dwLVIS_Location, dwFSDS_Location;
  1829. DWORD dwCurrDescLBN;
  1830. BYTE *pDescBuffer;
  1831. Tag *pDescTag;
  1832. struct GenericVolumeStructureDesc *pCurrDesc;
  1833. struct AnchorVolumeDescPtr *pAnchorVolDescPtr;
  1834. dbg_printf(("_initializeUDF200() calling.n"));
  1835. // Allocate space for a generic Descriptor (all Descriptors are not larger than
  1836. // a single Logical-Block).
  1837. pDescBuffer= (BYTE*)malloc(VOLUME_RECOGNITION_SIZE);
  1838. if (NULL == pDescBuffer) {
  1839. dbg_printf(("WARNING: _initializeUDF200() Failed [1]n"));
  1840. return FALSE;
  1841. }
  1842. // Verify Integrity of the Volume Recognition Sequence, by searching for
  1843. // the first Volume-Structure Descriptor ("NSR" Descriptor)
  1844. dwCurrDescLBN= (g_pUDFInfo->dwSessionStartLBN + VOLUME_RECOGNITION_SEQUENCE_START_LSN);
  1845. while (TRUE) {
  1846. if (! AuxCache_GetBytes(dwCurrDescLBN, 0, VOLUME_RECOGNITION_SIZE, pDescBuffer)) {
  1847. free(pDescBuffer);
  1848. dbg_printf(("WARNING: _initializeUDF200() Failed [2]n"));
  1849. return FALSE;
  1850. }
  1851. pCurrDesc= (struct GenericVolumeStructureDesc*)pDescBuffer;
  1852. // Check for a Beginning Extended Aread Descriptor
  1853. if (0 == strncmp((LPCSTR)pCurrDesc->aStandardID, STANDARD_ID_BEA01, STANDARD_ID_LEN)) {
  1854. dwCurrDescLBN++; // Skip to the next Descriptor
  1855. continue;
  1856. }
  1857. // Check for a Boot Descriptor
  1858. if (0 == strncmp((LPCSTR)pCurrDesc->aStandardID, STANDARD_ID_BOOT2, STANDARD_ID_LEN)) {
  1859. dwCurrDescLBN++; // Skip to the next Descriptor
  1860. continue;
  1861. }
  1862. // Check for an NSR03 Descriptor
  1863. if (0 == strncmp((LPCSTR)pCurrDesc->aStandardID, STANDARD_ID_NSR03, STANDARD_ID_LEN)) {
  1864. bNSRFound= TRUE;
  1865. break;
  1866. }
  1867. // Check for a Terminating Extended Area Descriptor
  1868. if (0 == strncmp((LPCSTR)pCurrDesc->aStandardID, STANDARD_ID_TEA01, STANDARD_ID_LEN))
  1869. break;
  1870. // Any other Descriptor is not of interest -- just skip to the next one
  1871. dwCurrDescLBN++;
  1872. }
  1873. if (! bNSRFound) {
  1874. free(pDescBuffer);
  1875. dbg_printf(("WARNING: _initializeUDF200() Failed [3]n"));
  1876. return FALSE;
  1877. }
  1878. free(pDescBuffer);
  1879. pDescBuffer= (BYTE*)malloc(ANCHOR_VOLUME_DESCRIPTOR_POINTER_SIZE);
  1880. if (NULL == pDescBuffer) {
  1881. dbg_printf(("WARNING: _initializeUDF200() Failed [1]: Low system resourcen"));
  1882. return FALSE;
  1883. }
  1884. // Locate the First Anchor-Point which contains an Anchor Volume-Descriptor Pointer
  1885. if (! AuxCache_GetBytes(FIRST_ANCHOR_POINT_LSN, 0, ANCHOR_VOLUME_DESCRIPTOR_POINTER_SIZE, pDescBuffer)) {
  1886. free(pDescBuffer);
  1887. dbg_printf(("WARNING: _initializeUDF200() Failed [4]n"));
  1888. return FALSE;
  1889. }
  1890. pAnchorVolDescPtr= (struct AnchorVolumeDescPtr *)pDescBuffer;
  1891. // Verify Integrity of the Anchor Volume-Descriptor Pointer
  1892. if ((TAG_ID_ANCHOR_VOLUME_DESC_PTR != LE_WORD(pAnchorVolDescPtr->tgDescTag.uTagID)) ||
  1893. (FIRST_ANCHOR_POINT_LSN != LE_DWORD(pAnchorVolDescPtr->tgDescTag.dwTagLocation))) {
  1894. free(pDescBuffer);
  1895. dbg_printf(("WARNING: _initializeUDF200() Failed [5]n"));
  1896. return FALSE;
  1897. }
  1898. // Extract the Location and Length of the Main Volume Descriptor Sequence (MVDS)
  1899. dwMVDS_Location= LE_DWORD(pAnchorVolDescPtr->exMainVolumeDescSequenceExtent.dwExtentLocation);
  1900. uMVDS_Size= (UINT16)((LE_DWORD(pAnchorVolDescPtr->exMainVolumeDescSequenceExtent.dwExtentLength) - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1901. // Check for a possible Error
  1902. if ((0 == dwMVDS_Location) || (0 == uMVDS_Size)) {
  1903. // Extract the Reserve Descriptor information
  1904. dwMVDS_Location= LE_DWORD(pAnchorVolDescPtr->exReserveVolumeDescSequenceExtent.dwExtentLocation);
  1905. uMVDS_Size= (UINT16)((LE_DWORD(pAnchorVolDescPtr->exReserveVolumeDescSequenceExtent.dwExtentLength) - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1906. // Make sure that a Reserve Descriptor is indeed available
  1907. if (0 == uMVDS_Size)
  1908. return FALSE;
  1909. }
  1910. free(pDescBuffer);
  1911. pDescBuffer= (BYTE*)malloc(VOLUME_DESCRIPTOR_SIZE);
  1912. if (NULL == pDescBuffer) {
  1913. dbg_printf(("WARNING: _initializeUDF200() Failed [1]: Low system resourcen"));
  1914. return FALSE;
  1915. }
  1916. // Enumerate the Main Volume Descriptor Sequence, one Descriptor at a time,
  1917. // until all required information is obtained.
  1918. dwCurrDescLBN= dwMVDS_Location;
  1919. while (uMVDS_Size) {
  1920. if (! AuxCache_GetBytes(dwCurrDescLBN, 0, VOLUME_DESCRIPTOR_SIZE, pDescBuffer)) {
  1921. free(pDescBuffer);
  1922. dbg_printf(("WARNING: _initializeUDF200() Failed [6]n"));
  1923. return FALSE;
  1924. }
  1925. pDescTag= (Tag*)pDescBuffer;
  1926. // Check for a Primary-Volume Descriptor
  1927. if (TAG_ID_PRIMARY_VOLUME_DESC == LE_WORD(pDescTag->uTagID)) {
  1928. struct PrimaryVolumeDesc *pPVD= (struct PrimaryVolumeDesc *)pDescBuffer;
  1929. dbg_printf(("Primary Volume Descriptor found.n"));
  1930. dbg_printf(("Volume-ID: '%s'n", (LPCSTR)&pPVD->sVolumeID[1]));
  1931. dbg_printf(("Volume-Set ID: '%s'n", (LPCSTR)&pPVD->sVolumeSetID[1]));
  1932. dbg_printf(("Volume recorded on: %d/%02d/%04d %02d:%02d:%02d.n",
  1933. pPVD->tsRecording.uDay, pPVD->tsRecording.uMonth, LE_WORD(pPVD->tsRecording.iYear),
  1934. pPVD->tsRecording.uHour, pPVD->tsRecording.uMinute, pPVD->tsRecording.uSecond));
  1935. }
  1936. // Check for a Partition-Descriptor
  1937. if (TAG_ID_PARTITION_DESC == LE_WORD(pDescTag->uTagID)) {
  1938. struct PartitionDesc *pPartitionDesc= (struct PartitionDesc *)pDescBuffer;
  1939. struct PartitionHeaderDesc *pPartitionHdrDesc;
  1940. g_pUDFInfo->dwMainPartitionLocation= LE_DWORD(pPartitionDesc->dwPartitionStartingLocation);
  1941. uPartitionSize= (UINT16)((LE_DWORD(pPartitionDesc->uPartitionLength) - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1942. uPartitionNumber= pPartitionDesc->uPartitionNumber;
  1943. // Cast the Contents-Use to a Partition-Header Descriptor, and extract
  1944. // the necessary info (DVD-RW Part 2, Section 2.6.6)
  1945. pPartitionHdrDesc= (struct PartitionHeaderDesc *)pPartitionDesc->aPartitionContentsUse;
  1946. // Note: Additional information about the Partition will be obtained from the
  1947. //       Logical Volume Descriptor.
  1948. }
  1949. // Check for a Logical-Volume Descriptor
  1950. if (TAG_ID_LOGICAL_VOLUME_DESC == LE_WORD(pDescTag->uTagID)) {
  1951. DWORD uPartitionMapsCnt;
  1952. struct LogicalVolumeDesc *pLVD= (struct LogicalVolumeDesc *)pDescBuffer;
  1953. struct PartitionMapGeneric *pGenPartitionMap;
  1954. struct PartitionMapType2_SparablePartition *pSparablePartitionMap= NULL;
  1955. // Cast the Contents-Use to a Long_ad (DVD-RW Part 2, Section 2.6.7)
  1956. Long_ad *pFSDInfo= (Long_ad*)pLVD->aLogicalVolumeContentsUse;
  1957. dwFSDS_Location= LE_WORD(pFSDInfo->lbaExtentLocation.uLogicalBlockNumber);
  1958. uFSDS_Size= (UINT16)((LE_DWORD(pFSDInfo->cbExtentLength) - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1959. // Extract the location and size of the Logical Volume Integrity Sequence
  1960. dwLVIS_Location= LE_DWORD(pLVD->exIntegritySequenceExtent.dwExtentLocation);
  1961. uLVIS_Size= (UINT16)((LE_DWORD(pLVD->exIntegritySequenceExtent.dwExtentLength) + LOGICAL_BLOCK_SIZE - 1) / (UINT32)LOGICAL_BLOCK_SIZE);
  1962. // Gather some additional Partition information, by examining the Partition-Maps
  1963. uPartitionMapsCnt= LE_DWORD(pLVD->uNumberOfPartitionMaps);
  1964. pGenPartitionMap= (struct PartitionMapGeneric*)(pDescBuffer + sizeof(struct LogicalVolumeDesc));
  1965. // Seek for a Type2 Partition-Map, describing the Sparable Partition corresponding
  1966. // to the Main Partition.
  1967. if( (UINT32)NULL != g_pUDFInfo->pMainPartitionSparingTable && FALSE != g_pUDFInfo->bUseSparingManagement )
  1968. {
  1969. Array_destruct((UINT32)(g_pUDFInfo->pMainPartitionSparingTable));
  1970. g_pUDFInfo->pMainPartitionSparingTable = (UINT32)NULL;
  1971. g_DVDVR_SparingTableSize=0;
  1972. }
  1973. g_pUDFInfo->bUseSparingManagement= FALSE;
  1974. while (uPartitionMapsCnt) {
  1975. if (PARTITION_MAP_TYPE_2 == pGenPartitionMap->uPartitionMapType) {
  1976. // Cast to a Sparable-Partition Map
  1977. pSparablePartitionMap= (struct PartitionMapType2_SparablePartition *)pGenPartitionMap;
  1978. // Make sure that it's the correct type
  1979. if (0 == strcmp(ENTITYID_SPARABLE_PARTITION, (LPCSTR)pSparablePartitionMap->eidPartitionTypeID.aIdentifier)) {
  1980. g_pUDFInfo->bUseSparingManagement= TRUE;
  1981. break;
  1982. }
  1983. }
  1984. // Move to the next Partition-Map
  1985. ((BYTE*)pGenPartitionMap) += pGenPartitionMap->cbPartitionMapLength;
  1986. uPartitionMapsCnt--;
  1987. }
  1988. // Check if the Sparable Partition Map was located
  1989. if ( g_pUDFInfo->bUseSparingManagement &&
  1990.  (0 != uPartitionMapsCnt) && 
  1991.  (uPartitionNumber == pSparablePartitionMap->uPartitionNumber) &&
  1992.  (0 != pSparablePartitionMap->cbSparingTableSize) ) 
  1993. {
  1994. DWORD dwSparingTableAddr= 0;
  1995. DWORD cbSparingTableSize= 0;
  1996. BYTE buffer[8];
  1997. DWORD i;
  1998. DWORD dwSparingTableArrayAddr = g_DVDVR_SpringTableAddr;
  1999. // Extract the necessary information and allocate space for the Sparing-Table
  2000. g_pUDFInfo->uSparingPacketLength= LE_WORD(pSparablePartitionMap->uPacketLength);
  2001. dwSparingTableAddr= LE_DWORD(pSparablePartitionMap->aLocationsOfSparingTables[0]);
  2002. cbSparingTableSize= LE_DWORD(pSparablePartitionMap->cbSparingTableSize);
  2003. g_pUDFInfo->pMainPartitionSparingTable= Array_constructEx(
  2004. (UINT16)(cbSparingTableSize+SPARING_TABLE_MAP_ENTRY_SIZE-1)/SPARING_TABLE_MAP_ENTRY_SIZE,
  2005. SPARING_TABLE_MAP_ENTRY_SIZE,&dwSparingTableArrayAddr);
  2006. if ((UINT32)NULL == g_pUDFInfo->pMainPartitionSparingTable) {
  2007. dbg_printf(("WARNING: _initializeUDF200() Failed [1]: Low system resourcen"));
  2008. uPartitionSize= 0;
  2009. break;
  2010. }
  2011. g_DVDVR_SparingTableSize = (DWORD) CONTAINER_COUNT( ( (UINT16)(cbSparingTableSize+
  2012. SPARING_TABLE_MAP_ENTRY_SIZE-1) / SPARING_TABLE_MAP_ENTRY_SIZE ) * SPARING_TABLE_MAP_ENTRY_SIZE );
  2013. // Load the Sparing-Table
  2014. for( i=0 ; i<(cbSparingTableSize+SPARING_TABLE_MAP_ENTRY_SIZE-1)/SPARING_TABLE_MAP_ENTRY_SIZE ;i++ )
  2015. if (!AuxCache_GetBytes(dwSparingTableAddr, i*SPARING_TABLE_MAP_ENTRY_SIZE, (UINT16)SPARING_TABLE_MAP_ENTRY_SIZE, buffer)
  2016. || !Array_setAt(((UINT32)(g_pUDFInfo->pMainPartitionSparingTable)), i, buffer))
  2017. {
  2018. Array_destruct((UINT32)(g_pUDFInfo->pMainPartitionSparingTable));
  2019. g_pUDFInfo->pMainPartitionSparingTable = (UINT32)NULL;
  2020. g_pUDFInfo->bUseSparingManagement= FALSE;
  2021. g_DVDVR_SparingTableSize=0;
  2022. uPartitionSize= 0;
  2023. break;
  2024. }
  2025. }
  2026. }
  2027. // Check for a Terminating Descriptor
  2028. if (TAG_ID_TERMINATING_DESC == LE_WORD(pDescTag->uTagID))
  2029. break;
  2030. // Move to the next Descriptor
  2031. dwCurrDescLBN++;
  2032. uMVDS_Size--;
  2033. }
  2034. // Make sure that there is enough information to access the File-Set Descriptor
  2035. if ((0 == uMVDS_Size) || (0 == uPartitionSize) || (0 == uFSDS_Size)) {
  2036. free(pDescBuffer);
  2037. dbg_printf(("WARNING: _initializeUDF200() Failed [7]n"));
  2038. return FALSE;
  2039. }
  2040. free(pDescBuffer);
  2041. pDescBuffer= (BYTE*)malloc(LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR_SIZE);
  2042. if (NULL == pDescBuffer) {
  2043. dbg_printf(("WARNING: _initializeUDF200() Failed [1]: Low system resourcen"));
  2044. return FALSE;
  2045. }
  2046. // Enumerate the Logical Volume Integrity Sequence, until a Close Logical Volume 
  2047. // Integrity Descriptor is found.
  2048. // In that Descriptor, examine and validate the UDF Revision.
  2049. dwCurrDescLBN= dwLVIS_Location;
  2050. while (uLVIS_Size) {
  2051. if (! AuxCache_GetBytes(dwCurrDescLBN, 0, LOGICAL_VOLUME_INTEGRITY_DESCRIPTOR_SIZE, pDescBuffer)) {
  2052. free(pDescBuffer);
  2053. dbg_printf(("WARNING: _initializeUDF200() Failed [8]n"));
  2054. return FALSE;
  2055. }
  2056. pDescTag= (Tag*)pDescBuffer;
  2057. if (TAG_ID_LOGICAL_VOLUME_INTEGRITY == LE_WORD(pDescTag->uTagID)) {
  2058. struct LogicalVolumeIntegrityDesc *pLVID= (struct LogicalVolumeIntegrityDesc *)pDescBuffer;
  2059. if (INTEGRITY_TYPE_CLOSE == LE_DWORD(pLVID->dwIntegrityType)) {
  2060. struct LogicalVolumeIntegrityDescImplUse *pImplUse= 
  2061. (struct LogicalVolumeIntegrityDescImplUse*)malloc(sizeof( struct LogicalVolumeIntegrityDescImplUse));
  2062. if( NULL == pImplUse){
  2063. dbg_printf(("WARNING: _initializeUDF200() Failed [1]: Low system resourcen"));
  2064. free(pDescBuffer);
  2065. return FALSE;
  2066. }
  2067. if (! AuxCache_GetBytes(dwCurrDescLBN, 
  2068. sizeof(struct LogicalVolumeIntegrityDesc)+(8*(UINT16)LE_DWORD(pLVID->uNumberOfPartitions)), 
  2069. sizeof(struct LogicalVolumeIntegrityDescImplUse), pImplUse))
  2070. {
  2071. free(pImplUse);
  2072. free(pDescBuffer);
  2073. dbg_printf(("WARNING: _initializeUDF200() Failed [8]n"));
  2074. return FALSE;
  2075. }
  2076. // Verify the appropriate UDF Revision
  2077. //if (0x0200 == LE_WORD(pImplUse->uMinimumUDFReadRevision))
  2078. bVolumeIntegrityVerified= TRUE;
  2079. free(pImplUse);
  2080. }
  2081. }
  2082. if (TAG_ID_TERMINATING_DESC == LE_WORD(pDescTag->uTagID))
  2083. break;
  2084. // Move to the next Descriptor
  2085. dwCurrDescLBN++;
  2086. uLVIS_Size--;
  2087. }
  2088. // Make sure that the Volume's Integrity was verified
  2089. if (! bVolumeIntegrityVerified) {
  2090. free(pDescBuffer);
  2091. dbg_printf(("WARNING: _initializeUDF200() Failed [9]n"));
  2092. return FALSE;
  2093. }
  2094. free(pDescBuffer);
  2095. // Establish the absolute LBA of the File-Set Descriptor Sequence, which is also
  2096. // the fixed Offset needed to be added to any LBN in order to get the absoulte
  2097. // LBA of Files and Directories.
  2098. g_pUDFInfo->dwLBA_Offset= _absoluteLBA(dwFSDS_Location);
  2099. pDescBuffer= (BYTE*)malloc(VOLUME_DESCRIPTOR_SIZE);
  2100. if (NULL == pDescBuffer) {
  2101. dbg_printf(("WARNING: _initializeUDF200() Failed [1]: Low system resourcen"));
  2102. return FALSE;
  2103. }
  2104. // Enumerate the File-Set Descriptor Sequence, until a File-Set Descriptor is found.
  2105. // From that File-Set Descriptor, extract the ICB corresponding to the Root-Directory.
  2106. dwCurrDescLBN= dwFSDS_Location;
  2107. while (uFSDS_Size) {
  2108. if (! AuxCache_GetBytes(_absoluteLBA(dwCurrDescLBN), 0, VOLUME_DESCRIPTOR_SIZE, pDescBuffer)) {
  2109. free(pDescBuffer);
  2110. dbg_printf(("WARNING: _initializeUDF200() Failed [10]n"));
  2111. return FALSE;
  2112. }
  2113. pDescTag= (Tag*)pDescBuffer;
  2114. if (TAG_ID_FILE_SET_DESC == LE_WORD(pDescTag->uTagID)) {
  2115. // Extract the location of the Root Directory
  2116. struct FileSetDesc *pFSD= (struct FileSetDesc *)pDescBuffer;
  2117. g_pUDFInfo->dwRootDirICB= LE_DWORD(pFSD->ladRootDirICB.lbaExtentLocation.uLogicalBlockNumber);
  2118. bRootDirEstablished= TRUE;
  2119. break;
  2120. }
  2121. if (TAG_ID_TERMINATING_DESC == LE_WORD(pDescTag->uTagID))
  2122. break;
  2123. // Move to the next Descriptor
  2124. dwCurrDescLBN++;
  2125. uFSDS_Size--;
  2126. }
  2127. // When this point is reached, the entire File-Set Descriptor Sequence has been
  2128. // scanned, and the Root-Directory's ICB possibly established.
  2129. free(pDescBuffer);
  2130. // Set the Current Directory to the Root-Directory, if it was established.
  2131. if (bRootDirEstablished)
  2132. g_pUDFInfo->dwCurrDirICB= g_pUDFInfo->dwRootDirICB;
  2133. g_pUDFInfo->uRevision= 0x0200;
  2134. return bRootDirEstablished;
  2135. #else
  2136. return FALSE;
  2137. #endif//DVD_VR_SUPPORT
  2138. #endif //UDF_SUPPORT_UDF201
  2139. }
  2140. /////////////////////////////////////////////////////////////////////////////
  2141. // _absoluteLBA()
  2142. //
  2143. // Description: Computes the absolute address of a given Relative Logical-
  2144. // Block Address.
  2145. //
  2146. // Input: dwRelativeLBA - A DWORD which represents a relative address.
  2147. // Output: None
  2148. // In/Out: None
  2149. // Return: The absolute address corresponding to the relative one.
  2150. //
  2151. // Remarks:
  2152. // 1. If the current UDF Revision is lass than 2.00, then no Sparing Management
  2153. //    is available. In this case, the Absolute Address is a linear offset
  2154. //    from the beginning of the Main Partition.
  2155. // 2. For UDF-2.00 and higher, if no Sparing-Management is in use, the
  2156. //    Absolute Address is the same as with UDF Revisions preceding 2.00.
  2157. // 3. If Sparing-Management is in use, then the Sparing-Table is scanned
  2158. //    to determine whether the given Relative address belongs to a 
  2159. //    Spared Packet.
  2160. // 4. If the given Relative adderss is part of a Spared Packet, then
  2161. //    the Absolute address is the appropriate offset from the start of the 
  2162. //    spare packet, as specified in the Sparing-Table entry.
  2163. // 5. Otherwise, the Absolute address is as a linear offset from the Main
  2164. //    Sparable Partition.
  2165. static DWORD _absoluteLBA(DWORD dwRelativeLBA)
  2166. {
  2167. DWORD dwAbsoluteLocation= (g_pUDFInfo->dwMainPartitionLocation + dwRelativeLBA);
  2168. #ifndef UDF_SUPPORT_UDF201
  2169. return dwAbsoluteLocation;
  2170. #else
  2171. #ifdef DVD_VR_SUPPORT
  2172. UINT16 uCurrMapEntryPos,uReallocationTableLength;
  2173. DWORD dwOriginalLocation;
  2174. struct SparingTableMapEntry stmeCurrMapEntry;
  2175. // If no Sparing-Management is enabled, then the Absolute LBA is computed
  2176. // from the beginning of the containing Main-Partition.
  2177. // Note: Sparing-Management is only relevanr for UDF-2.00 and higher.
  2178. if ((0x0200 != g_pUDFInfo->uRevision) || (! g_pUDFInfo->bUseSparingManagement))
  2179. return dwAbsoluteLocation;
  2180. if(!Array_getAt(((UINT32)(g_pUDFInfo->pMainPartitionSparingTable)), SPARING_TABLE_RTL_OFFSET, (BYTE*)&stmeCurrMapEntry))
  2181. return dwAbsoluteLocation;
  2182. uReallocationTableLength = LE_WORD((WORD)stmeCurrMapEntry.dwOriginalLocation);
  2183. // Sparing-Management is being used: go over the Sparing-Table to find out
  2184. // if the supplied Relative-LBA belongs to a spared packet.
  2185. for (uCurrMapEntryPos=0; uCurrMapEntryPos < uReallocationTableLength; uCurrMapEntryPos++)
  2186. {
  2187. if(!Array_getAt(((UINT32)(g_pUDFInfo->pMainPartitionSparingTable)), uCurrMapEntryPos, (BYTE *)&stmeCurrMapEntry))
  2188. return dwAbsoluteLocation;
  2189. dwOriginalLocation= LE_DWORD(stmeCurrMapEntry.dwOriginalLocation);
  2190. if(dwOriginalLocation == 0xffffffffUL)
  2191. break;
  2192. if ((dwRelativeLBA >= dwOriginalLocation) && 
  2193. (dwRelativeLBA < (dwOriginalLocation + g_pUDFInfo->uSparingPacketLength))) {
  2194. // The Absolute address is a linear offset from the start of the Spare Packet,
  2195. // as specified in the MappedLocation field of the Sparing-Table Entry.
  2196. dwAbsoluteLocation= (LE_DWORD(stmeCurrMapEntry.dwMappedLocation) +
  2197.  (dwRelativeLBA - dwOriginalLocation));
  2198. }
  2199. }
  2200. return dwAbsoluteLocation;
  2201. #else
  2202. UINT16 uCurrMapEntryPos;
  2203. // If no Sparing-Management is enabled, then the Absolute LBA is computed
  2204. // from the beginning of the containing Main-Partition.
  2205. // Note: Sparing-Management is only relevanr for UDF-2.00 and higher.
  2206. if ((0x0200 != g_pUDFInfo->uRevision) || (! g_pUDFInfo->bUseSparingManagement))
  2207. return dwAbsoluteLocation;
  2208. /*
  2209. // Sparing-Management is being used: go over the Sparing-Table to find out
  2210. // if the supplied Relative-LBA belongs to a spared packet.
  2211. for (uCurrMapEntryPos=0; 
  2212.  uCurrMapEntryPos < LE_WORD(g_pUDFInfo->pMainPartitionSparingTable->uReallocationTableLength);
  2213.  uCurrMapEntryPos++)
  2214. {
  2215. DWORD dwOriginalLocation;
  2216. struct SparingTableMapEntry stmeCurrMapEntry= g_pUDFInfo->pMainPartitionSparingTable->aMapEntries[uCurrMapEntryPos];
  2217. dwOriginalLocation= LE_DWORD(stmeCurrMapEntry.dwOriginalLocation);
  2218. if ((dwRelativeLBA >= dwOriginalLocation) && 
  2219. (dwRelativeLBA < (dwOriginalLocation + g_pUDFInfo->uSparingPacketLength))) {
  2220. // The Absolute address is a linear offset from the start of the Spare Packet,
  2221. // as specified in the MappedLocation field of the Sparing-Table Entry.
  2222. dwAbsoluteLocation= (LE_DWORD(stmeCurrMapEntry.dwMappedLocation) +
  2223.  (dwRelativeLBA - dwOriginalLocation));
  2224. }
  2225. }
  2226. return dwAbsoluteLocation;
  2227. */
  2228. return 0L;
  2229. #endif //DVD_VR_SUPPORT
  2230. #endif //UDF_SUPPORT_UDF201
  2231. }
  2232. /////////////////////////////////////////////////////////////////////////////
  2233. // _findFirstFileIDDesc()
  2234. //
  2235. // Description: Initiates a search for the first occurrence of a File-ID
  2236. // Descriptor structure describing a File/Sub-Directory that 
  2237. // meets the supplied criteria.
  2238. //
  2239. // Input: i_pszFileID - A string holding the requested Filename/pattern.
  2240. // uFileCharacteristicsMask - A Mask to apply to the File's Characteristics.
  2241. // uFileCharacteristics - A combination of Characteristics, that should match.
  2242. // Output: o_pFileIDDescPtr - Points to a FileIDDesc Pointer, to receive
  2243. //    the File-ID Descriptor of a matching File/Sub-Directory.
  2244. // In/Out: None
  2245. // Return: A UINT16, which is the ID of the search, and should be passed
  2246. // to future calls to any of the search-related methods.
  2247. // NULL is returned if no File matching the requested criteria could
  2248. // be found.
  2249. //
  2250. // Remarks:
  2251. // 1. The supplied i_pszFileID can be a Filename or a pattern, as described
  2252. //    in the documentation for UDF_findFirstFile().
  2253. // 2. uFileCharacteristicsMask is a Mask that is applied to any File-ID 
  2254. //    Descriptor whose File-ID mathces the supplied Filename/pattern. 
  2255. //    This mask is applied to that item's Characteristics.
  2256. // 3. uFileCharacteristics is compared against the Masked Characteristics 
  2257. //    of a matching item.
  2258. //    If there is a match, then the whole item is considered to match the
  2259. //    requested criteria.
  2260. // 4. The returned ID should be saved for future use with search-related
  2261. //    methods.
  2262. // 5. A return value of NULL indicates that no File/Sub-Directory matching
  2263. //    the requested criteria could be found.
  2264. // 6. The search is limited to the current working-directory.
  2265. // 7. The search is Case-Sensitive.
  2266. // 9. The returned File-ID Descriptor Pointer should be considered persistant
  2267. //    across calls. The caller needs to make sure that o_pFileIDDescPtr
  2268. //    is freed when it is no longer needed.
  2269. // 8. _findClose() must be called when no additional searches are needed.
  2270. static UINT16 _findFirstFileIDDesc(LPCWSTR i_pszFileID, UINT8 uFileCharacteristicsMask, 
  2271.    UINT8 uFileCharacteristics, 
  2272.    struct FileIDDesc **o_pFileIDDescPtr)
  2273. {
  2274. BOOL bSuccess;
  2275. BOOL bWildcardSearch;
  2276. UINT16 uFileIDDescListSizeInCont;
  2277. UINT16 uSearchID;
  2278. UINT16 uAllocDescsOffset;
  2279. DWORD dwDirFileEntryAddr, dwDirectoryStartAddr, dwDirectorySize;
  2280. Short_ad sadDirAD;
  2281. struct TerminalEntry *pEntry;
  2282. DirectorySearchInfo dsiInfo;
  2283. // Allocate space for a Terminal Entry
  2284. pEntry= (struct TerminalEntry *)malloc(sizeof(struct TerminalEntry));
  2285. if (NULL == pEntry) {
  2286. tr_printf(("FATAL: _findFirstFileIDDesc() Failed [1]: Low system resources.n"));
  2287. return NULL;
  2288. }
  2289. // Extract the File-Entry of the Current Directory
  2290. dwDirFileEntryAddr= _absoluteLBA(g_pUDFInfo->dwCurrDirICB);
  2291. if (! AuxCache_GetBytes(dwDirFileEntryAddr, 0, sizeof(struct TerminalEntry), (BYTE*)pEntry)) {
  2292. dbg_printf(("WARNING: _findFirstFileIDDesc() Failed [2]n"));
  2293. free(pEntry);
  2294. return NULL;
  2295. }
  2296. // Examine only the Descriptor's Tag and icbTag, in order to establish what kind of
  2297. // Descriptor is at hand.
  2298.  if(!IS_SHORT_ALLOC_DESC(pEntry)&&!IS_LONG_ALLOC_DESC(pEntry)&&!IS_IN_ICB_ALLOC_DESC(pEntry))
  2299.  {
  2300. dbg_printf(("WARNING: _findFirstFileIDDesc() Failed [3]: Unsupported Allocation-Scheme.n"));
  2301. free(pEntry);
  2302. return NULL;
  2303. }
  2304. // Calculate the offset of the Allocation-Descriptor of the Directory;
  2305. // This offset is: (sizeof(FileEntry or ExtFileEntry) + cbLengthOfExtAttrs).
  2306. uAllocDescsOffset= 0;
  2307. if (TAG_ID_FILE_ENTRY == LE_WORD(pEntry->tgDescTag.uTagID)) {
  2308. UINT32 cbLengthOfExtAttrs;
  2309. if (AuxCache_GetBytes(dwDirFileEntryAddr, FILE_ENTRY_L_EXTATTR_OFFSET, 
  2310.  sizeof(cbLengthOfExtAttrs), (BYTE*)&cbLengthOfExtAttrs)) 
  2311. {
  2312. uAllocDescsOffset= (sizeof(struct FileEntry) + 
  2313. (UINT16)LE_DWORD(cbLengthOfExtAttrs));
  2314. }
  2315. }
  2316. else if (TAG_ID_EXT_FILE_ENTRY == LE_WORD(pEntry->tgDescTag.uTagID)) {
  2317. UINT32 cbLengthOfExtAttrs;
  2318. if (AuxCache_GetBytes(dwDirFileEntryAddr, EXT_FILE_ENTRY_L_EXTATTR_OFFSET,
  2319.  sizeof(cbLengthOfExtAttrs), (BYTE*)&cbLengthOfExtAttrs))
  2320. {
  2321. uAllocDescsOffset= (sizeof(struct ExtFileEntry) + 
  2322. (UINT16)LE_DWORD(cbLengthOfExtAttrs));
  2323. }
  2324. }
  2325.        if(!IS_IN_ICB_ALLOC_DESC(pEntry))
  2326. {
  2327. // Extract the Allocation-Descriptor of the Directory
  2328. if ((0 == uAllocDescsOffset) ||
  2329. ! AuxCache_GetBytes(dwDirFileEntryAddr, uAllocDescsOffset, sizeof(sadDirAD), 
  2330.    (BYTE*)&sadDirAD))
  2331. {
  2332. // The ICB was neither a File-Entry nor an Extended-File-Entry: there's nothing
  2333. // that can be done.
  2334. dbg_printf(("WARNING: _findFirstFileIDDesc() Failed [4]n"));
  2335. return NULL;
  2336. }
  2337. // Calculate the Start Address of the Directory itself
  2338. dwDirectorySize= LE_DWORD(sadDirAD.cbExtentLength);
  2339. if (0 == dwDirectorySize) {
  2340. dbg_printf(("WARNING: _findFirstFileIDDesc() Failed [5]n"));
  2341. return NULL;
  2342. }
  2343. dwDirectoryStartAddr= _absoluteLBA(LE_DWORD(sadDirAD.dwExtentPosition));
  2344. // Allocate space for the File-ID Descriptors List Cache
  2345. uFileIDDescListSizeInCont= CONTAINER_COUNT(DIRECTORY_FILEIDLIST_SZ);
  2346. dsiInfo.hFileIDDescList= sc_Malloc(uFileIDDescListSizeInCont);
  2347. if (NULL_HANDLE == dsiInfo.hFileIDDescList) {
  2348. tr_printf(("FATAL: _findFirstFileIDDesc() Failed [6]: Low system resourcesn"));
  2349. return NULL;
  2350. }
  2351. // Cache the beginning of the Directory's contents (File-ID Descriptors List)
  2352. if (! sc_CopyFromDisc(dwDirectoryStartAddr, 0, DIRECTORY_FILEIDLIST_SZ, 
  2353.   dsiInfo.hFileIDDescList))
  2354. {
  2355. dbg_printf(("WARNING: _findFirstFileIDDesc() Failed [7]n"));
  2356. sc_Free(dsiInfo.hFileIDDescList, uFileIDDescListSizeInCont);
  2357. return NULL;
  2358. }
  2359. dsiInfo.cbDescListOffset= 0;
  2360. dsiInfo.cbCurrDescOffset= 0;
  2361. }
  2362. else
  2363.     {
  2364.     UINT32 cbLengthofAllocDesc;
  2365.     if (AuxCache_GetBytes(dwDirFileEntryAddr, FILE_ENTRY_L_ALLOCDESC_OFFSET,
  2366.    sizeof(cbLengthofAllocDesc), (BYTE*)&cbLengthofAllocDesc))
  2367.   {
  2368.   dwDirectorySize= (UINT16)LE_DWORD(cbLengthofAllocDesc);
  2369.   } 
  2370. uFileIDDescListSizeInCont= /*CONTAINER_COUNT((UINT16)dwDirectorySize);//*/CONTAINER_COUNT(DIRECTORY_FILEIDLIST_SZ);
  2371.   dsiInfo.hFileIDDescList= sc_Malloc(uFileIDDescListSizeInCont);
  2372. if (NULL_HANDLE == dsiInfo.hFileIDDescList) 
  2373. {
  2374. tr_printf(("FATAL: _findFirstFileIDDesc() Failed [6]: Low system resourcesn"));
  2375. return NULL;
  2376. }
  2377.     if (! sc_CopyFromDisc(dwDirFileEntryAddr, uAllocDescsOffset, DIRECTORY_FILEIDLIST_SZ, 
  2378.   dsiInfo.hFileIDDescList))
  2379.           {
  2380.            dbg_printf(("WARNING: _findFirstFileIDDesc() Failed [7]n"));
  2381.           sc_Free(dsiInfo.hFileIDDescList, uFileIDDescListSizeInCont);
  2382.          return NULL;
  2383.        }     
  2384. dsiInfo.cbCurrDescOffset= uAllocDescsOffset;
  2385. dsiInfo.cbDescListOffset= uAllocDescsOffset;
  2386. dwDirectorySize+=uAllocDescsOffset;
  2387. dwDirectoryStartAddr = dwDirFileEntryAddr;
  2388.     }
  2389.   
  2390. free(pEntry);
  2391. // Copy the necessary information into the DirSearchInfo, and initialize it
  2392. dsiInfo.dwDirICB= dwDirectoryStartAddr;
  2393. dsiInfo.dwDirectorySize= dwDirectorySize;
  2394. // In case of a Wildcard search, use a static string for File-ID, instead of allocating
  2395. // memory.
  2396. bWildcardSearch= ((0 == i_pszFileID[0]) ? TRUE : FALSE);
  2397. if (bWildcardSearch) {
  2398. dsiInfo.pszFileID= (LPWSTR)g_pszWildcardSearch;
  2399. }
  2400. else {
  2401. dsiInfo.pszFileID= (LPWSTR)malloc((1 + wcslen(i_pszFileID)) * sizeof(WCHAR));
  2402. if (NULL == dsiInfo.pszFileID) {
  2403. tr_printf(("FATAL: _findFirstFileIDDesc() Failed [8]: Low system resourcesn"));
  2404. sc_Free(dsiInfo.hFileIDDescList, uFileIDDescListSizeInCont);
  2405. return NULL;
  2406. }
  2407. wcscpy(dsiInfo.pszFileID, i_pszFileID);
  2408. }
  2409. // Continue to copy necessary information into the DirSearchInfo, and initialize it.
  2410. dsiInfo.uFileCharacteristicsMask= uFileCharacteristicsMask;
  2411. dsiInfo.uFileCharacteristics= uFileCharacteristics;
  2412. // Allocate a Search-Info
  2413. uSearchID= _FileSys_allocateSearchInfo();
  2414. if (NULL == uSearchID) {
  2415. dbg_printf(("WARNING: _findFirstFileIDDesc() Failed [9]: No available Search-Info IDn"));
  2416. if (! bWildcardSearch)
  2417. free(dsiInfo.pszFileID);
  2418. sc_Free(dsiInfo.hFileIDDescList, uFileIDDescListSizeInCont);
  2419. return NULL;
  2420. }
  2421. // Register the Directory-Search Info in the Search-Info Pool
  2422. bSuccess= _FileSys_setSearchInfo(uSearchID, (const BYTE*)&dsiInfo);
  2423. if (! bSuccess) {
  2424. dbg_printf(("FATAL: _findFirstFileIDDesc() Failed [10]: Cannot register new Searchn"));
  2425. }
  2426. // Now, the information in pDirInfo is stable and complete: perform the search
  2427. if (bSuccess && ! _findNextFileIDDesc(uSearchID, o_pFileIDDescPtr)) {
  2428. dbg_printf(("WARNING: _findFirstFileIDDesc() Failed [11]n"));
  2429. bSuccess= FALSE;
  2430. }
  2431. if (! bSuccess) {
  2432. if (! bWildcardSearch)
  2433. free(dsiInfo.pszFileID);
  2434. sc_Free(dsiInfo.hFileIDDescList, uFileIDDescListSizeInCont);
  2435. _FileSys_freeSearchInfo(uSearchID);
  2436. return NULL;
  2437. }
  2438. return uSearchID;
  2439. }
  2440. /////////////////////////////////////////////////////////////////////////////
  2441. // _fileID_Cut()
  2442. //
  2443. // Description: Cut the fileID to specific length.
  2444. //
  2445. // Input:        i_fileID_len - The source fileID length.
  2446. // i_pSourceBuffer - Source buff contains the source fileID.
  2447. // Output: o_fileID_len - Dest fileID length.
  2448. // o_pDestBuffer - Dest buff contains the fileID with the proper length
  2449. // Return: TRUE if the requested data was successfully cut;
  2450. // FALSE otherwise.
  2451. BOOL _fileID_Cut(UINT8 i_fileID_len, BYTE* i_pSourceBuffer, UINT8 o_fileID_len, BYTE* o_pDestBuffer)
  2452. {
  2453. if( 0 == i_pSourceBuffer[0] )
  2454. o_pDestBuffer[0]=0;
  2455. else if( UNICODE_COMPRESSIONID_SINGLE_BYTE == i_pSourceBuffer[0] )
  2456. {
  2457. int iSuffixLen=1;
  2458. BYTE* bp=i_pSourceBuffer+i_fileID_len-1;
  2459. do
  2460. {
  2461. if( *bp == '.' )
  2462. break;
  2463. bp--;
  2464. iSuffixLen++;
  2465. }
  2466. while( bp != i_pSourceBuffer );
  2467. memcpy( o_pDestBuffer, i_pSourceBuffer, o_fileID_len );
  2468. if( iSuffixLen < i_fileID_len && iSuffixLen < o_fileID_len - 2 )
  2469. memcpy( o_pDestBuffer+o_fileID_len-iSuffixLen, i_pSourceBuffer+i_fileID_len-iSuffixLen, iSuffixLen);
  2470. }
  2471. else if( UNICODE_COMPRESSIONID_DOUBLE_BYTE == i_pSourceBuffer[0] )
  2472. {
  2473. int iSuffixLen=1;
  2474. WORD* bp=(WORD*)(i_pSourceBuffer+i_fileID_len-2);
  2475. do
  2476. {
  2477. #ifdef MOTOROLA
  2478. if( *bp == 0x002e )   //'.' in double byte.
  2479. #else
  2480. if( *bp == 0x2e00 )
  2481. #endif //MOTOROLA
  2482. break;
  2483. bp--;
  2484. iSuffixLen++;
  2485. }
  2486. while( (BYTE*)bp != i_pSourceBuffer+1 );
  2487. iSuffixLen *= 2;
  2488. memcpy( o_pDestBuffer, i_pSourceBuffer, o_fileID_len );
  2489. if( iSuffixLen < i_fileID_len && iSuffixLen < o_fileID_len - 3 )
  2490. memcpy( o_pDestBuffer+o_fileID_len-iSuffixLen, i_pSourceBuffer+i_fileID_len-iSuffixLen, iSuffixLen);
  2491. }
  2492. return TRUE;
  2493. }
  2494. /////////////////////////////////////////////////////////////////////////////
  2495. // _fileIDDescList_getBytes()
  2496. //
  2497. // Description: Retrieves Bytes from a File-ID Descriptor-List associated
  2498. // with an open Directory-Search.
  2499. //
  2500. // Input: cbOffset - The offset of the requested Bytes from the List's start;
  2501. // cbBytesCnt - The number of requested Bytes.
  2502. // Output: o_pDestBuffer - Points to a destination Buffer, that will contain
  2503. // the requested Bytes upon successful completion.
  2504. // In/Out: io_pInfo - Points to the DirectorySearchInfo associated with
  2505. //    the Search whose List should be used.
  2506. // Return: TRUE if the requested data was successfully retrieved;
  2507. // FALSE otherwise.
  2508. static BOOL _fileIDDescList_getBytes(DirectorySearchInfo *io_pInfo, UINT32 cbOffset, 
  2509.  UINT8 cbBytesCnt, BYTE *o_pDestBuffer)
  2510. {
  2511. // Check if there's a Cache-Hit: if the Cache contains at least cbBytesCnt from
  2512. // the requested Offset.
  2513. if(cbBytesCnt>=DIRECTORY_FILEIDLIST_SZ-1)
  2514. return FALSE;
  2515. // Note: The Cache is assumed to be at least 256 Bytes in size, and cbBytesCnt
  2516. //       cannot exceed 256 Bytes.
  2517. if ((cbOffset < io_pInfo->cbDescListOffset) ||
  2518. ((cbOffset + cbBytesCnt) > (io_pInfo->cbDescListOffset + DIRECTORY_FILEIDLIST_SZ)))
  2519. {
  2520. // Cache-Miss: Fill-in the Cache, starting from the requested Offset, thus
  2521. // ensuring that the request can be satisfied.
  2522. if (! sc_CopyFromDisc(io_pInfo->dwDirICB, cbOffset, DIRECTORY_FILEIDLIST_SZ,
  2523.   io_pInfo->hFileIDDescList))
  2524. {
  2525. dbg_printf(("WARNING: _fileIDDescList_getBytes() Failed [1]n"));
  2526. return FALSE;
  2527. }
  2528. // Adjust the Cache-base to the new Offset
  2529. io_pInfo->cbDescListOffset= cbOffset;
  2530. }
  2531. // At this point, the Cache is guaranteed to contain enough data that would satisfy
  2532. // the request. Copy the requested Bytes.
  2533. // because the file name can't more than MAX_SUPPORT_FILE_ID_LENGTH(128) bytes, so cut off the tail or the file name
  2534. //if( cbBytesCnt <= MAX_SUPPORT_FILE_ID_LENGTH )
  2535. sc_GetBytes(io_pInfo->hFileIDDescList, (UINT16)(cbOffset - io_pInfo->cbDescListOffset),
  2536. cbBytesCnt, o_pDestBuffer);
  2537. //else
  2538. //{
  2539. // BYTE* buff=NULL;
  2540. // buff=(BYTE*)MEM_Allocate(DEFAULT_HEAP, cbBytesCnt);
  2541. // if(buff == NULL)
  2542. // {
  2543. // dbg_printf(("WARNING: _fileIDDescList_getBytes() Failed [2]: Low system resources.n"));
  2544. // return FALSE;
  2545. // }
  2546. // sc_GetBytes(io_pInfo->hFileIDDescList, (UINT16)(cbOffset - io_pInfo->cbDescListOffset),
  2547. // cbBytesCnt, buff);
  2548. // _fileID_Cut(cbBytesCnt, buff, MAX_SUPPORT_FILE_ID_LENGTH+1, o_pDestBuffer);
  2549. //
  2550. // MEM_Free(DEFAULT_HEAP,buff);
  2551. //}
  2552. return TRUE;
  2553. }
  2554. /////////////////////////////////////////////////////////////////////////////
  2555. // _findNextFileIDDesc()
  2556. //
  2557. // Description: Continues a search that was previously initiated via a call
  2558. // to _findFirstFileIDDesc().
  2559. //
  2560. // Input: uSearchID - The ID of a search, that was returned from a
  2561. // previous call to _findFirstFileIDDesc().
  2562. // Output: o_pFileIDDescPtr - Points to a FileIDDesc Pointer, to receive
  2563. //    the File-ID Descriptor of a matching 
  2564. //    File/Sub-Directory.
  2565. // In/Out: None
  2566. // Return: TRUE if the search succeeded, and an additional File-ID Descriptor
  2567. // matching the criteria was found. In this case, the supplied
  2568. // o_pFileIDDescPtr contains a valid pointer.
  2569. // FALSE is returned if no more Files/Sub-Directories matching the
  2570. // supplied criteria could be found. In this case, the supplied 
  2571. // o_pFileIDDescPtr is invalid.
  2572. //
  2573. // Remarks:
  2574. // 1. This method continues a previous search from the point it left off.
  2575. // 2. The search relates to the Directory that was the current working-
  2576. //    directory at the time the search was initiated via _findFirstFileIDDesc().
  2577. // 3. The search uses the same criteria as were originally supplied to 
  2578. //    _findFirstFileIDDesc().
  2579. // 4. The returned File-ID Descriptor Pointer should be considered persistant
  2580. //    across calls. The caller has to make sure that o_pFileIDDescPtr
  2581. //    is freed when it is no longer needed.
  2582. // 5. _findClose() must be called when no additional searches are needed.
  2583. static BOOL _findNextFileIDDesc(UINT16 uSearchID, struct FileIDDesc **o_pFileIDDescPtr)
  2584. {
  2585. BOOL bFileIDFound;
  2586. UINT8 uFileIDLength;
  2587. WCHAR szUnicodeFileID[(MAX_ID_LENGTH / sizeof(WCHAR)) + 1];
  2588. LPCWSTR pszFileID;
  2589. struct FileIDDesc *pCurrFileIDDesc;
  2590. //<<<MikeX_1213_2004_A:compare the files' length when searching files.
  2591. DirectorySearchInfo dsiInfo;
  2592. UINT8 uFoundFileIDLength;
  2593. BOOL bBlurredlySearch = FALSE;
  2594. //MikeX_1213_2004_A>>>
  2595. // Retrieve the Directory-Search Info from the Search-Pool
  2596. if ((NULL == uSearchID) ||
  2597. ! _FileSys_getSearchInfo(uSearchID, (BYTE*)&dsiInfo))
  2598. {
  2599. return FALSE;
  2600. }
  2601. uFileIDLength= wcslen(dsiInfo.pszFileID);
  2602. // MikeX_1213_2004_A: support blurred searching
  2603. if(FILESYS_BLURRED_SEARCH == dsiInfo.pszFileID[uFileIDLength-1] )
  2604. {
  2605. bBlurredlySearch = TRUE;
  2606. uFileIDLength --;
  2607. }
  2608. // Reset the result
  2609. *o_pFileIDDescPtr= NULL;
  2610. // Prepare a descriptor-container
  2611. pCurrFileIDDesc= (struct FileIDDesc *)malloc(sizeof(struct FileIDDesc) + MAX_ID_LENGTH + 2);
  2612. if (NULL == pCurrFileIDDesc) {
  2613. tr_printf(("FATAL: _findNextFileIDDesc() Failed [1]: Low system resourcesn"));
  2614. return FALSE;
  2615. }
  2616. // Scan the File-ID Descriptors List, as long as the entire Directory has not been
  2617. // enumerated, and there is no match.
  2618. bFileIDFound= FALSE;
  2619. while ( (dsiInfo.cbCurrDescOffset < dsiInfo.dwDirectorySize) && (! bFileIDFound) )
  2620. {
  2621. UINT8 cbCurrFileIDDescSize;
  2622. // Read the contents of the Current File-ID Descriptor
  2623. if (! _fileIDDescList_getBytes(&dsiInfo, dsiInfo.cbCurrDescOffset,
  2624.    sizeof(struct FileIDDesc), (BYTE*)pCurrFileIDDesc))
  2625. {
  2626. dbg_printf(("WARNING: _findNextFileIDDesc() Failed [2]n"));
  2627. break;
  2628. }
  2629. cbCurrFileIDDescSize= (sizeof(struct FileIDDesc) + pCurrFileIDDesc->cbLengthOfFileID + 
  2630.    LE_WORD(pCurrFileIDDesc->cbLengthOfImplUse));
  2631. // Collect the File-ID, and place it into the sFileID field of the Current Descriptor,
  2632. // ignoring the aImplUse field (which is not needed).
  2633. if (! _fileIDDescList_getBytes(&dsiInfo, 
  2634.    (dsiInfo.cbCurrDescOffset + sizeof(struct FileIDDesc) +
  2635. LE_WORD(pCurrFileIDDesc->cbLengthOfImplUse)),
  2636.    pCurrFileIDDesc->cbLengthOfFileID,
  2637.    (BYTE*)&(pCurrFileIDDesc->sFileID)))
  2638. {
  2639. dbg_printf(("WARNING: _findNextFileIDDesc() Failed [3]n"));
  2640. break;
  2641. }
  2642. // Collect the current File-ID
  2643. pszFileID= (LPCWSTR)szUnicodeFileID;
  2644. //Hannah_0524_2005
  2645. // Convert the File-ID into UNICODE, if required
  2646. if (0 == pCurrFileIDDesc->cbLengthOfFileID) {
  2647. // An empty File-ID
  2648. szUnicodeFileID[0]= 0;
  2649. }
  2650. else if (UNICODE_COMPRESSIONID_SINGLE_BYTE == pCurrFileIDDesc->sFileID[0]) {
  2651. if( pCurrFileIDDesc->cbLengthOfFileID> MAX_ID_LENGTH/sizeof(WCHAR) +1 )
  2652. {
  2653. BYTE* buff = NULL;
  2654. BYTE len = pCurrFileIDDesc->cbLengthOfFileID;
  2655. buff=(BYTE*)malloc(len +1);
  2656. if(buff == NULL)
  2657. {
  2658. dbg_printf(("WARNING: _findNextFileRecord() Failed [5]:Low system resourcesn"));
  2659. break;
  2660. }
  2661. memcpy(buff, pCurrFileIDDesc->sFileID, pCurrFileIDDesc->cbLengthOfFileID);
  2662. buff[len] = 0;
  2663.  _fileID_Cut(len/*+1*/, buff, MAX_ID_LENGTH/sizeof(WCHAR)+1, (BYTE*)pCurrFileIDDesc->sFileID);
  2664.  free(buff);
  2665.  pCurrFileIDDesc->cbLengthOfFileID = MAX_ID_LENGTH/sizeof(WCHAR)+1;
  2666. }
  2667. //pCurrFileIDDesc->cbLengthOfFileID = MIN(MAX_ID_LENGTH/sizeof(WCHAR),(pCurrFileIDDesc->cbLengthOfFileID)); //Hannah_0322
  2668. // The File-ID is given in ANSI-ASCII: convert it into UNICODE
  2669. _str2wcs((LPCSTR)&pCurrFileIDDesc->sFileID[1], szUnicodeFileID,
  2670.  ((pCurrFileIDDesc->cbLengthOfFileID) * sizeof(WCHAR)));
  2671. }
  2672. else if (UNICODE_COMPRESSIONID_DOUBLE_BYTE == pCurrFileIDDesc->sFileID[0]) {
  2673. if( pCurrFileIDDesc->cbLengthOfFileID> MAX_ID_LENGTH +1 )
  2674. {
  2675. BYTE* buff = NULL;
  2676. BYTE len = pCurrFileIDDesc->cbLengthOfFileID;
  2677. buff=(BYTE*)malloc(len +2);
  2678. if(buff == NULL)
  2679. {
  2680. dbg_printf(("WARNING: _findNextFileRecord() Failed [5]:Low system resourcesn"));
  2681. break;
  2682. }
  2683. memcpy(buff, pCurrFileIDDesc->sFileID, pCurrFileIDDesc->cbLengthOfFileID);
  2684. buff[len] = 0;
  2685. buff[len+1] = 0;
  2686.  _fileID_Cut(len/*+1*/, buff, MAX_ID_LENGTH+1, (BYTE*)pCurrFileIDDesc->sFileID);
  2687.  free(buff);
  2688.  pCurrFileIDDesc->cbLengthOfFileID = MAX_ID_LENGTH+1;
  2689. }
  2690. // The File-ID is given in UNICODE: manipulate as required
  2691. pCurrFileIDDesc->sFileID[pCurrFileIDDesc->cbLengthOfFileID]= 0;
  2692. pCurrFileIDDesc->sFileID[pCurrFileIDDesc->cbLengthOfFileID+1]= 0;
  2693. #ifdef MOTOROLA
  2694. pszFileID= (LPCWSTR)&pCurrFileIDDesc->sFileID[1];
  2695. #else
  2696. swab((LPSTR)&pCurrFileIDDesc->sFileID[1], (LPSTR)szUnicodeFileID, 
  2697.  (pCurrFileIDDesc->cbLengthOfFileID + 1));
  2698. #endif //MOTOROLA
  2699. }
  2700. //Hannah_0524_2005
  2701. else {
  2702. // The File-ID is given in an unsupported compression; copy "as is"
  2703. memcpy(szUnicodeFileID, pCurrFileIDDesc->sFileID, pCurrFileIDDesc->cbLengthOfFileID);
  2704. szUnicodeFileID[(pCurrFileIDDesc->cbLengthOfFileID - 1) / sizeof(WCHAR)]= 0;
  2705. }
  2706. if (TAG_ID_FILE_ID_DESC != LE_WORD(pCurrFileIDDesc->tgDescTag.uTagID)) {
  2707. dbg_printf(("WARNING: _findNextFileIDDesc() Failed [4]n"));
  2708. break;
  2709. }
  2710. // Check if an appropriate FileID Descriptor was found, according to
  2711. // both the File-ID and the File-Characteristics.
  2712. #if 0 // Robin_1112_2004, "*" mean any char/string, RB_TBD
  2713. if (dsiInfo.uFileCharacteristics == (pCurrFileIDDesc->uFileCharacteristics & dsiInfo.uFileCharacteristicsMask))
  2714. {
  2715. if ((0 != uFileIDLength && dsiInfo.pszFileID[uFileIDLength-1] == '*') && (0 == _wcsnicmp(dsiInfo.pszFileID, pszFileID, uFileIDLength-1)) )
  2716. bFileIDFound= TRUE;
  2717. else if ((uFileIDLength == wcslen(pszFileID) || 0 == uFileIDLength) && (0 == _wcsnicmp(dsiInfo.pszFileID, pszFileID, uFileIDLength)) )
  2718. bFileIDFound= TRUE;
  2719. }
  2720. #else
  2721. //<<<MikeX_1213_2004_A:compare the files' length when searching files.
  2722. if( 0 != pCurrFileIDDesc->cbLengthOfFileID )
  2723. {
  2724. if (UNICODE_COMPRESSIONID_SINGLE_BYTE == pCurrFileIDDesc->sFileID[0])
  2725. uFoundFileIDLength = pCurrFileIDDesc->cbLengthOfFileID - 1;
  2726. else if (UNICODE_COMPRESSIONID_DOUBLE_BYTE == pCurrFileIDDesc->sFileID[0])
  2727. uFoundFileIDLength = (pCurrFileIDDesc->cbLengthOfFileID - 1) / sizeof(WCHAR);
  2728. else
  2729. uFoundFileIDLength = 0;
  2730. }
  2731. else
  2732. uFoundFileIDLength = 0;
  2733. if( 0 == uFoundFileIDLength || 0 == uFileIDLength )
  2734. uFoundFileIDLength = uFileIDLength;
  2735. //MikeX_1213_2004_A>>>
  2736. if ( (dsiInfo.uFileCharacteristics == (pCurrFileIDDesc->uFileCharacteristics & dsiInfo.uFileCharacteristicsMask)) &&
  2737.  (0 == _wcsnicmp(dsiInfo.pszFileID, pszFileID, uFileIDLength)) && //MikeX_1119_2003: convert the file ID lower-case to upper-case.
  2738. (bBlurredlySearch || (uFoundFileIDLength == uFileIDLength)) ) //MikeX_1213_2004_A:compare the files' length when searching files.
  2739. {
  2740. bFileIDFound= TRUE;
  2741. }
  2742. #endif
  2743. // Continue to the next Directory-entry
  2744. dsiInfo.cbCurrDescOffset += (4 * ((cbCurrFileIDDescSize + 3) / 4));
  2745. }
  2746. if (bFileIDFound) {
  2747. // Assign the result
  2748. *o_pFileIDDescPtr= pCurrFileIDDesc;
  2749. }
  2750. else {
  2751. // No match was found - this Directory has been exhausted: mark that the entire
  2752. // contents was read, so that future calls will return immediately.
  2753. dsiInfo.cbCurrDescOffset= dsiInfo.dwDirectorySize;
  2754. // Free the memory
  2755. free(pCurrFileIDDesc);
  2756. }
  2757. // Update the Directory-Search Info in the Search-Pool
  2758. if (! _FileSys_setSearchInfo(uSearchID, (const BYTE*)&dsiInfo)) {
  2759. dbg_printf(("WARNING: _findNextFileIDDesc() Failed [5]n"));
  2760. }
  2761. return bFileIDFound;
  2762. }
  2763. /////////////////////////////////////////////////////////////////////////////
  2764. // _findClose()
  2765. //
  2766. // Description: Terminates a search.
  2767. //
  2768. // Input: hDirInfo - A Handle to a search, that was returned from a
  2769. //    previous call to _findFirstFileIDDesc().
  2770. // Output: None
  2771. // In/Out: None
  2772. // Return: TRUE if the search was successfully terminated; FALSE othewise.
  2773. //
  2774. // Remarks:
  2775. // Any search that is initiated via _findFirstFileIDDesc() must be terminated
  2776. // using a call to this method, in order to allow for proper release of
  2777. // resources that were allocated for that search.
  2778. static BOOL _findClose(UINT16 uSearchID)
  2779. {
  2780. DirectorySearchInfo dsiInfo;
  2781. // Retrieve the Directory-Search Info from the Search-Pool
  2782. if ((NULL == uSearchID) ||
  2783. ! _FileSys_getSearchInfo(uSearchID, (BYTE*)&dsiInfo))
  2784. {
  2785. return FALSE;
  2786. }
  2787. if (dsiInfo.pszFileID != g_pszWildcardSearch)
  2788. free(dsiInfo.pszFileID);
  2789. sc_Free(dsiInfo.hFileIDDescList, CONTAINER_COUNT(DIRECTORY_FILEIDLIST_SZ));
  2790. _FileSys_freeSearchInfo(uSearchID);
  2791. return TRUE;
  2792. }
  2793. /////////////////////////////////////////////////////////////////////////////
  2794. // _getFileAttributes()
  2795. //
  2796. // Description: Translates a native File-ID Descriptor into a 
  2797. // FindData structure.
  2798. //
  2799. // Input: FileIDDesc - Points to a FileIDDesc structure to translate.
  2800. // Output: o_pFindData - Points to a FindData structure to receive the
  2801. //   translated information.
  2802. // In/Out: None
  2803. // Return: TRUE if the Descriptor was successfully translated; FALSE othewise.
  2804. //
  2805. // Remarks: None
  2806. static BOOL _getFileAttributes(const struct FileIDDesc *i_pFileIDDesc,
  2807.    FindData *o_pFindData)
  2808. {
  2809. DWORD dwFileEntryAddr;
  2810. DWORD cbLengthOfExtAttrs, cbLengthOfAllocDescs;
  2811.    //DWORD cbInfoLengthHigh, cbInfoLengthLow;
  2812.    Alloc_desc adFile;
  2813.    BYTE cbDescLength;
  2814. BYTE bDescNum;
  2815. UINT32 dwTmpExtentLength;
  2816. UINT32 dwTmpExtentPosition;
  2817. UINT8 cbEntrySize;
  2818. struct TerminalEntry *pEntry;
  2819. struct {
  2820. UINT32 dwFirst;
  2821. UINT32 dwSecond;
  2822. } QuadWord;
  2823. // Load the File's File-Entry. Use a Teriminal-Entry at first, just to peek
  2824. // into the type of Descriptor that is at hand (File-Entry / Extended-File-Entry).
  2825. pEntry= (struct TerminalEntry *)malloc(sizeof(struct TerminalEntry));
  2826. if (NULL == pEntry) {
  2827. dbg_printf(("WARNING: _getFileAttributes() Failed [1]n"));
  2828. return FALSE;
  2829. }
  2830. dwFileEntryAddr= _absoluteLBA(LE_DWORD(i_pFileIDDesc->ladICB.lbaExtentLocation.uLogicalBlockNumber));
  2831. if (! AuxCache_GetBytes(dwFileEntryAddr, 0, sizeof(struct TerminalEntry), (BYTE*)pEntry)) {
  2832. dbg_printf(("WARNING: _getFileAttributes() Failed [2]n"));
  2833. free(pEntry);
  2834. return FALSE;
  2835. }
  2836. // Fill-in the File's Type from the File-Entry
  2837. o_pFindData->uFileType= pEntry->icbTag.uFileType;
  2838. // Compute the size of the Entry according to the Descriptor type, and extract
  2839. // the length of the Extended Attributes inside the Descriptor.
  2840. if (TAG_ID_FILE_ENTRY == LE_WORD(pEntry->tgDescTag.uTagID)) {
  2841. cbEntrySize= sizeof(struct FileEntry);
  2842. if (AuxCache_GetBytes(dwFileEntryAddr, FILE_ENTRY_L_EXTATTR_OFFSET,
  2843.  sizeof(QuadWord), (BYTE*)&QuadWord))
  2844. {
  2845. cbLengthOfExtAttrs= LE_DWORD(QuadWord.dwFirst);
  2846. cbLengthOfAllocDescs= LE_DWORD(QuadWord.dwSecond);
  2847. }
  2848. }
  2849. else if (TAG_ID_EXT_FILE_ENTRY == LE_WORD(pEntry->tgDescTag.uTagID)) {
  2850. cbEntrySize= sizeof(struct ExtFileEntry);
  2851. if (AuxCache_GetBytes(dwFileEntryAddr, EXT_FILE_ENTRY_L_EXTATTR_OFFSET,
  2852.  sizeof(QuadWord), (BYTE*)&QuadWord))
  2853. {
  2854. cbLengthOfExtAttrs= LE_DWORD(QuadWord.dwFirst);
  2855. cbLengthOfAllocDescs= LE_DWORD(QuadWord.dwSecond);
  2856. }
  2857. }
  2858. else {
  2859. dbg_printf(("WARNING: _getFileAttributes() Failed [3]n"));
  2860. free(pEntry);
  2861. return FALSE;
  2862. }
  2863. /*
  2864. if (AuxCache_GetBytes(dwFileEntryAddr, FILE_ENTRY_INFOLENGTH_OFFSET,
  2865.  sizeof(QuadWord), (BYTE*)&QuadWord))
  2866. {
  2867. #ifdef MOTOROLA
  2868. cbInfoLengthHigh= LE_DWORD(QuadWord.dwFirst);
  2869. cbInfoLengthLow=  LE_DWORD(QuadWord.dwSecond);
  2870. #else
  2871. cbInfoLengthHigh= LE_DWORD(QuadWord.dwSecond);
  2872. cbInfoLengthLow=  LE_DWORD(QuadWord.dwFirst);
  2873. #endif //MOTOROLA
  2874. }
  2875. */
  2876. // Calculate the Starting-Address of the File, according to the type of Allocation
  2877. // Descriptor. Set the File's Size accordingly.
  2878. if (IS_IN_ICB_ALLOC_DESC(pEntry)) {
  2879. // The File's Body starts inside this File-Entry
  2880. o_pFindData->dwStartAddr= LE_DWORD(i_pFileIDDesc->ladICB.lbaExtentLocation.uLogicalBlockNumber);//dwFileEntryAddr;//(dwFileEntryAddr +cbLengthOfExtAttrs);
  2881. o_pFindData->cbFileSizeHigh= 0;
  2882. o_pFindData->cbFileSizeLow= cbLengthOfAllocDescs;
  2883. }
  2884. else
  2885. {
  2886. if(IS_SHORT_ALLOC_DESC(pEntry))
  2887.  cbDescLength = sizeof(Short_ad);
  2888. else if(IS_LONG_ALLOC_DESC(pEntry))
  2889.  cbDescLength = sizeof(Long_ad);
  2890. if (! AuxCache_GetBytes(dwFileEntryAddr, (cbEntrySize + (UINT16)cbLengthOfExtAttrs),
  2891.   cbDescLength, (BYTE*)&adFile))
  2892. {
  2893. dbg_printf(("WARNING: _getFileAttributes() Failed [4]n"));
  2894. memset(&adFile, 0, cbDescLength);
  2895. }
  2896. if(ICB_FILETYPE_DIRECTORY == o_pFindData->uFileType) //directory
  2897. o_pFindData->dwStartAddr= LE_DWORD(i_pFileIDDesc->ladICB.lbaExtentLocation.uLogicalBlockNumber);
  2898. else //File
  2899. {
  2900. if(IS_SHORT_ALLOC_DESC(pEntry))
  2901. o_pFindData->dwStartAddr= _absoluteLBA(LE_DWORD(adFile.sadFile.dwExtentPosition));
  2902. else
  2903. o_pFindData->dwStartAddr= _absoluteLBA(LE_DWORD(adFile.ladFile.lbaExtentLocation.uLogicalBlockNumber));
  2904. }
  2905. {
  2906. if(IS_SHORT_ALLOC_DESC(pEntry))
  2907. o_pFindData->cbFileSizeLow = adFile.sadFile.cbExtentLength;
  2908. else
  2909. o_pFindData->cbFileSizeLow = adFile.ladFile.cbExtentLength;
  2910. for(bDescNum = 1;bDescNum<cbLengthOfAllocDescs/ sizeof(Short_ad);bDescNum++)
  2911. {
  2912. if(IS_SHORT_ALLOC_DESC(pEntry))
  2913. {
  2914. dwTmpExtentLength = adFile.sadFile.cbExtentLength;
  2915. dwTmpExtentPosition = adFile.sadFile.dwExtentPosition;
  2916. }
  2917. else
  2918. {
  2919. dwTmpExtentLength = adFile.ladFile.cbExtentLength;
  2920. dwTmpExtentPosition = adFile.ladFile.lbaExtentLocation.uLogicalBlockNumber;
  2921. }
  2922. if (!AuxCache_GetBytes(dwFileEntryAddr, (cbEntrySize + (UINT16)cbLengthOfExtAttrs)+bDescNum* cbDescLength,
  2923.    cbDescLength, (BYTE*)&adFile))
  2924. break;
  2925. else
  2926. {
  2927. if((IS_SHORT_ALLOC_DESC(pEntry))&&((dwTmpExtentPosition+dwTmpExtentLength/LOGICAL_BLOCK_SIZE) ==adFile.sadFile.dwExtentPosition)) 
  2928. {
  2929. if(FILE_EXTENT_LENGTH - (o_pFindData->cbFileSizeLow+adFile.sadFile.cbExtentLength)>=LOGICAL_BLOCK_SIZE)
  2930.                 o_pFindData->cbFileSizeLow+=adFile.sadFile.cbExtentLength;
  2931.                 else
  2932.                 {
  2933.                 o_pFindData->cbFileSizeLow = FILE_EXTENT_LENGTH - LOGICAL_BLOCK_SIZE+1;
  2934.                 break;
  2935.                 }
  2936.                 }     
  2937.                 else if(IS_LONG_ALLOC_DESC(pEntry)&&((dwTmpExtentPosition+dwTmpExtentLength/LOGICAL_BLOCK_SIZE) ==adFile.ladFile.lbaExtentLocation.uLogicalBlockNumber))
  2938.                 {
  2939.                 if(FILE_EXTENT_LENGTH - (o_pFindData->cbFileSizeLow+adFile.ladFile.cbExtentLength)>=LOGICAL_BLOCK_SIZE)
  2940.                 o_pFindData->cbFileSizeLow+=adFile.ladFile.cbExtentLength;
  2941.                 else
  2942.                 {
  2943.                 o_pFindData->cbFileSizeLow = FILE_EXTENT_LENGTH - LOGICAL_BLOCK_SIZE+1;
  2944.                 break;
  2945.                 }
  2946.                 }
  2947.                 else  //The extent is not continous 
  2948.                 break;
  2949.                 }
  2950. }
  2951. o_pFindData->cbFileSizeHigh= 0;
  2952. }
  2953.    }
  2954. #if 0
  2955. if(IS_EXTENDED_ALLOC_DESC(pEntry))
  2956. {
  2957. struct ExtAllocDesc extFile;
  2958.  
  2959. if (! AuxCache_GetBytes(dwFileEntryAddr, (cbEntrySize + (UINT16)cbLengthOfExtAttrs),
  2960.    sizeof(struct ExtAllocDesc), (BYTE*)&extFile))
  2961. {
  2962. dbg_printf(("WARNING: _getFileAttributes() Failed [4]n"));
  2963. memset(&extFile, 0, sizeof(extFile));
  2964. }
  2965. if(ICB_FILETYPE_DIRECTORY == o_pFindData->uFileType) //directory
  2966. o_pFindData->dwStartAddr= LE_DWORD(i_pFileIDDesc->ladICB.lbaExtentLocation.uLogicalBlockNumber);
  2967. else //File
  2968. o_pFindData->dwStartAddr= _absoluteLBA(LE_DWORD(extFile.lbaExtentLocation.uLogicalBlockNumber));
  2969. // Read the continuous extent until it reaches size of 4G-2K.
  2970. {
  2971. o_pFindData->cbFileSizeLow = extFile.cbExtentLength;
  2972. for(bDescNum = 1;bDescNum<cbLengthOfAllocDescs/bDescLength;bDescNum++)
  2973. {
  2974. dwTmpExtentLength = extFile.cbExtentLength;
  2975. dwTmpExtentPosition = extFile.lbaExtentLocation.uLogicalBlockNumber;
  2976. if (AuxCache_GetBytes(dwFileEntryAddr, (cbEntrySize + (UINT16)cbLengthOfExtAttrs)+bDescNum* sizeof(struct ExtAllocDesc),
  2977.    sizeof(extFile), (BYTE*)&extFile))
  2978. if((dwTmpExtentPosition+dwTmpExtentLength/LOGICAL_BLOCK_SIZE) ==extFile.lbaExtentLocation.uLogicalBlockNumber) 
  2979. {
  2980. if(FILE_EXTENT_LENGTH - (o_pFindData->cbFileSizeLow+extFile.cbExtentLength)>=LOGICAL_BLOCK_SIZE)
  2981.                 o_pFindData->cbFileSizeLow+=extFile.cbExtentLength;
  2982.                 else
  2983.                 {
  2984.                 o_pFindData->cbFileSizeLow = FILE_EXTENT_LENGTH - LOGICAL_BLOCK_SIZE;
  2985.                 break;
  2986.                 }
  2987. }
  2988. }
  2989. o_pFindData->cbFileSizeHigh= 0;
  2990. }
  2991. }
  2992. #endif
  2993. free(pEntry);
  2994. // Extract the File-ID
  2995. if (UNICODE_COMPRESSIONID_SINGLE_BYTE == i_pFileIDDesc->sFileID[0]) {
  2996. // The File-ID is given in ANSI-ASCII: convert it into UNICODE
  2997. _str2wcs((LPCSTR)&i_pFileIDDesc->sFileID[1], o_pFindData->szFileID,
  2998.  (i_pFileIDDesc->cbLengthOfFileID * sizeof(WCHAR)));
  2999. }
  3000. else if (UNICODE_COMPRESSIONID_DOUBLE_BYTE == i_pFileIDDesc->sFileID[0]) {
  3001. // The File-ID is given in UNICODE: manipulate as required
  3002. #ifdef MOTOROLA
  3003. memcpy(o_pFindData->szFileID, &i_pFileIDDesc->sFileID[1], 
  3004.    (i_pFileRec->cbLengthOfFileID - 1));
  3005. #else
  3006. swab((LPSTR)&i_pFileIDDesc->sFileID[1], (LPSTR)o_pFindData->szFileID, 
  3007.  (i_pFileIDDesc->cbLengthOfFileID - 1));
  3008. #endif //MOTOROLA
  3009. o_pFindData->szFileID[(i_pFileIDDesc->cbLengthOfFileID - 1) / sizeof(WCHAR)]= 0;
  3010. }
  3011. else {
  3012. // The File-ID is given in an unsupported compression; copy "as is"
  3013. memcpy(o_pFindData->szFileID, &i_pFileIDDesc->sFileID[1], 
  3014.    (i_pFileIDDesc->cbLengthOfFileID - 1));
  3015. o_pFindData->szFileID[(i_pFileIDDesc->cbLengthOfFileID - 1) / sizeof(WCHAR)]= 0;
  3016. }
  3017. return TRUE;
  3018. }
  3019. #endif //FILESYSTEM_SUPPORT_UDF