1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: ut_BinaryFileFormat.cpp
4
5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain proprietary
8 information of Nintendo and/or its licensed developers and are protected by
9 national and international copyright laws. They may not be disclosed to third
10 parties or copied or duplicated in any form, in whole or in part, without the
11 prior written consent of Nintendo.
12
13 The content herein is highly confidential and should be handled accordingly.
14
15 $Revision: $
16 *---------------------------------------------------------------------------*/
17
18 #include "precompiled.h"
19
20 #include <nw/types.h>
21 #include <nw/assert.h>
22 #include <nw/ut/ut_BinaryFileFormat.h>
23 #include <nw/ut/ut_Inlines.h>
24
25
26 namespace nw {
27 namespace ut {
28
29
30 bool
IsValidBinaryFile(const BinaryFileHeader * pHeader,u32 signature,u32 version,u16 minBlocks)31 IsValidBinaryFile(
32 const BinaryFileHeader* pHeader,
33 u32 signature,
34 u32 version,
35 u16 minBlocks /* = 1 */
36 )
37 {
38 NW_POINTER_ASSERT( pHeader );
39
40 if ( pHeader->signature != signature )
41 {
42 NW_WARNING(false, "Signature check failed ('%c%c%c%c' must be '%c%c%c%c').",
43 static_cast<char>(BitExtract(pHeader->signature, 24, 8)),
44 static_cast<char>(BitExtract(pHeader->signature, 16, 8)),
45 static_cast<char>(BitExtract(pHeader->signature, 8, 8)),
46 static_cast<char>(BitExtract(pHeader->signature, 0, 8)),
47 static_cast<char>(BitExtract(signature, 24, 8)),
48 static_cast<char>(BitExtract(signature, 16, 8)),
49 static_cast<char>(BitExtract(signature, 8, 8)),
50 static_cast<char>(BitExtract(signature, 0, 8))
51 );
52 return false;
53 }
54
55 if ( pHeader->byteOrder != BYTE_ORDER_MARK )
56 {
57 NW_WARNING(false, "Unsupported byte order.");
58 return false;
59 }
60
61 if ( NW_UT_VERSION_MAJOR(version) != NW_UT_VERSION_MAJOR(pHeader->version) ||
62 NW_UT_VERSION_MINOR(version) < NW_UT_VERSION_MINOR(pHeader->version) ||
63 NW_UT_VERSION_BINARYBUGFIX(version) > NW_UT_VERSION_BINARYBUGFIX(pHeader->version) )
64 {
65 NW_WARNING(false, "Version check faild (bin:'%d.%d.%d.%d', lib:'%d.%d.%d.%d').",
66 NW_UT_VERSION_MAJOR(pHeader->version),
67 NW_UT_VERSION_MINOR(pHeader->version),
68 NW_UT_VERSION_MICRO(pHeader->version),
69 NW_UT_VERSION_BINARYBUGFIX(pHeader->version),
70 NW_UT_VERSION_MAJOR(version),
71 NW_UT_VERSION_MINOR(version),
72 NW_UT_VERSION_MICRO(version),
73 NW_UT_VERSION_BINARYBUGFIX(version)
74 );
75 return false;
76 }
77
78 if( pHeader->fileSize < sizeof(BinaryFileHeader) + sizeof(BinaryBlockHeader) * minBlocks )
79 {
80 NW_WARNING(false, "Too small file size(=%d).", pHeader->fileSize);
81 return false;
82 }
83
84 if( pHeader->dataBlocks < minBlocks )
85 {
86 NW_WARNING(false, "Too small number of data blocks(=%d).", pHeader->dataBlocks);
87 return false;
88 }
89
90 return true;
91 }
92
93
94 /*!--------------------------------------------------------------------------*
95 Name: IsReverseEndianBinaryFile
96
97 @brief NintendoWare 標準バイナリファイルのエンディアンが逆かどうかを
98 チェックします。
99
100 @param[in] pFileHeader 対象のファイルヘッダへのポインタ
101
102 @return エンディアンが逆なら true,さもなければ false を返します。
103 *---------------------------------------------------------------------------*/
104 bool
IsReverseEndianBinaryFile(const BinaryFileHeader * pFileHeader)105 IsReverseEndianBinaryFile( const BinaryFileHeader* pFileHeader )
106 {
107 NW_POINTER_ASSERT( pFileHeader );
108 return ( pFileHeader->byteOrder != BYTE_ORDER_MARK );
109 }
110
111
112 /*!--------------------------------------------------------------------------*
113 Name: GetNextBinaryBlockHeader
114
115 @brief NintendoWare 標準バイナリファイル内の次のブロックヘッダを
116 取得します。
117
118 @param[in] pFileHeader 対象のファイルヘッダへのポインタ
119 @param[in] pBlockHeader 現在のブロックヘッダへのポインタ
120
121 @return pBlockHeaderの次のブロックヘッダを返します。
122 次のブロックがない場合は、NULLを返します。
123 pBlockHeaderがNULLの場合は、一番始めのブロックヘッダを返します。
124 *---------------------------------------------------------------------------*/
125 BinaryBlockHeader*
GetNextBinaryBlockHeader(BinaryFileHeader * pFileHeader,BinaryBlockHeader * pBlockHeader)126 GetNextBinaryBlockHeader(
127 BinaryFileHeader* pFileHeader,
128 BinaryBlockHeader* pBlockHeader
129 )
130 {
131 NW_POINTER_ASSERT( pFileHeader );
132
133 void* ptr;
134 if ( ! IsReverseEndianBinaryFile( pFileHeader ) )
135 {
136 if ( pBlockHeader == NULL )
137 {
138 if ( pFileHeader->dataBlocks == 0 ) return NULL;
139 ptr = AddOffsetToPtr( pFileHeader, pFileHeader->headerSize );
140 }
141 else
142 {
143 ptr = AddOffsetToPtr( pBlockHeader, pBlockHeader->size );
144 }
145
146 if ( ptr >= AddOffsetToPtr( pFileHeader, pFileHeader->fileSize ) )
147 {
148 return NULL;
149 }
150 }
151 else
152 {
153 if ( pBlockHeader == NULL )
154 {
155 if ( pFileHeader->dataBlocks == 0 ) return NULL;
156 ptr = AddOffsetToPtr( pFileHeader, ReverseEndian( pFileHeader->headerSize ) );
157 }
158 else
159 {
160 ptr = AddOffsetToPtr( pBlockHeader, ReverseEndian( pBlockHeader->size ) );
161 }
162
163 if ( ptr >= AddOffsetToPtr( pFileHeader, ReverseEndian( pFileHeader->fileSize ) ) )
164 {
165 return NULL;
166 }
167 }
168
169 return reinterpret_cast<BinaryBlockHeader*>( ptr );
170 }
171
172 } /* namespace ut */
173 } /* namespace nw */
174