рд╕реНрдЯреАрдо рдлрд╛рдЗрд▓реЗрдВ рднрд╛рдЧ 1 - рдЬреАрд╕реАрдПрдл / рдПрдирд╕реАрдПрдл

рд╕реНрдЯреАрдо рд▓реЛрдЧреЛ рдЬреИрд╕рд╛ рдХрд┐ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ , рдореИрдВ рд╕реНрдЯреАрдо рдЕрд╡рд╕рдВрд░рдЪрдирд╛ рдХреЗ рдЙрд╕ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓реЗрдЦ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬреЛ рдПрдВрдЯреА-рд╕реНрдЯреАрдо рд╕рдореБрджрд╛рдп рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдФрд░ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рд╡рд┐рдЪрд╛рд░-рдордВрдерди рджреНрд╡рд╛рд░рд╛ рдЦреЛрд▓ рд╕рдХрддрд╛ рд╣реИред



рд╣рд╛рд▓ рддрдХ рддрдХ, рдЬреАрд╕реАрдПрдл рдлрд╛рдЗрд▓реЗрдВ рд╡реИрд▓рд╡ рджреНрд╡рд╛рд░рд╛ рдЬрд╛рд░реА рдХрд┐рдП рдЧрдП рд╕рднреА рдЦреЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рдереЗ, рдФрд░ рдЕрдиреНрдп рд╕рднреА рдХреЗ рд▓рд┐рдП рдПрдирд╕реАрдПрдлред рдЕрдкрдиреЗ рдЖрдк рд╕реЗ, рдпреЗ рдлрд╛рдЗрд▓реЗрдВ рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рдХрдИ рд╕реНрддрд░реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдлрд╝рд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдЫрд╡рд┐ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреА рд╣реИрдВред NCF рдФрд░ GCF рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдпрд╣ рд╣реИ рдХрд┐ рдкреВрд░реНрд╡ рдореЗрдВ рдХреЗрд╡рд▓ рд╣реЗрдбрд░ рд╣реЛрддреЗ рд╣реИрдВ, рдФрд░ рдЙрдирд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдлрд╛рдЗрд▓реЗрдВ рдПрдХ рдЕрд▓рдЧ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ ( <рд╕реНрдЯреАрдо рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛> / SteamApps / рдЖрдо / <рдЦреЗрд▓ рдирд╛рдо> ) рдореЗрдВ рд╕реНрдерд┐рдд рд╣реЛрддреА рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдореИрдВ GCF рдХрд╛ рд╡рд░реНрдгрди рдХрд░реВрдВрдЧрд╛, рдФрд░ рдмрд╛рдж рдореЗрдВ NCF рдХреА рд╕рднреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рджреВрдВрдЧрд╛ред



рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдЗрди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реВрдВрдЧрд╛ рдФрд░ рдЕрдкрдиреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдирдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реВрдВрдЧрд╛ (рдпрд╣ рд▓реЗрдЦ рдХрд╛ рдПрдХ рд▓рд┐рдВрдХ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╣реИ)ред рд╢реБрд░реБрдЖрдд рдХрд╛рдлреА рдЙрдмрд╛рдК рд╣реЛрдЧреА - рд╕рдВрд░рдЪрдирд╛рдУрдВ рдФрд░ рдЙрдирдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рдХрд╛ рд╡рд░реНрдгрдиред рд╕рдмрд╕реЗ "рд╕реНрд╡рд╛рджрд┐рд╖реНрдЯ" рдЙрдирдХреЗ рдмрд╛рдж рд╣реЛрдЧрд╛ ...



рдпрд╣рд╛рдВ рд╕рднреА рдХреЛрдб рд╕реНрдЯреАрдо рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд░рд┐рд╡рд░реНрд╕ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИред рдлрд╝рд╛рдЗрд▓ рдкреНрд░рд╛рд░реВрдк рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХрд╛рдВрд╢ рдЬрд╛рдирдХрд╛рд░реА рдЦреБрд▓реЗ рд╕реНрд░реЛрддреЛрдВ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХреА рдЧрдИ рдереА, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЗрд╕реЗ рдереЛрдбрд╝рд╛ рдкреВрд░рдХ рдХрд┐рдпрд╛ рдФрд░ рдХреИрд╢ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдЙрд╕ рд╕рдордп рд╕рдмрд╕реЗ рд▓реЛрдХрдкреНрд░рд┐рдп HLLIB рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХреА рдЧрдИ)ред



рд╕рд╛рдорд╛рдиреНрдп рдлрд╝рд╛рдЗрд▓ рд╕рдВрд░рдЪрдирд╛



рдлрд╝рд╛рдЗрд▓ рдХреЛ рддрд╛рд░реНрдХрд┐рдХ рд░реВрдк рд╕реЗ 2 рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рд╣реЗрдбрд░ рдФрд░ рд╕реНрд╡рдпрдВ рд╕рд╛рдордЧреНрд░реАред рд╕рд╛рдордЧреНрд░реА рдХреЛ рдмреНрд▓реЙрдХреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ 8kB рд╕реЗрдХреНрдЯрд░реЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХреБрдЫ рдлрд╛рдЗрд▓реЗрдВ рдФрд░ рдЙрдирдХреЗ рдЕрдиреБрдХреНрд░рдо рд╣реЗрдбрд░ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рд╣реИрдВред рд╕рднреА рд╣реЗрдбрд░ рдореЗрдВ рдлрд╝реАрд▓реНрдб рд╣реЛрддреЗ рд╣реИрдВ рдЬреЛ рдЪрд╛рд░-рдмрд╛рдЗрдЯ рдкреВрд░реНрдгрд╛рдВрдХ рд╣реЛрддреЗ рд╣реИрдВ (рдЕрдкрд╡рд╛рдж рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдФрд░ рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛ рдХреА рд╕реВрдЪреА рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рднрд╛рдЧ рд╣реИ)ред



рд╣реЗрдбрд░ рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрд░рдЪрдирд╛рдПрдБ рд╣реЛрддреА рд╣реИрдВ:



рдкрд╣рд▓реА рдЪреАрдЬ рдЬреЛ рдЖрдкрдХреА рдЖрдВрдЦ рдХреЛ рдкрдХрдбрд╝рддреА рд╣реИ рд╡рд╣ рд╣реИ рдЪреЗрдХрд╕рдордЗрдирдЧреНрдиреЗрдЪрд░ , рдЬреЛ рд╣реЗрдбрд░ рднрд╛рдЧ рдХрд╛ рдПрдХ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯреЗрдб рд╣реИрд╢ рд╣реИ рдЬреЛ рдлрд╛рдЗрд▓реЛрдВ рдХреЗ рдЪреЗрдХрд╕рдо рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИред

рдЗрди рд╕рднреА рд╢реАрд░реНрд╖рдХреЛрдВ рдФрд░ рдЙрдирдХреЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдЙрджреНрджреЗрд╢реНрдп рдкрд░ рдмрд╛рдж рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреАред

рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЬреЛ рдмрд╣реБрдд рдзреНрдпрд╛рди рд╕реЗ рдирд╣реАрдВ рдкрдврд╝рддреЗ рд╣реИрдВ, рдореИрдВ рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛рддрд╛ рд╣реВрдВ рдХрд┐ рд▓рдЧрднрдЧ рд╕рднреА рд╣реЗрдбрд░ рдХреЗ рд╕рднреА рдлрд╝реАрд▓реНрдб рдЪрд╛рд░-рдмрд╛рдЗрдЯ рдкреВрд░реНрдгрд╛рдВрдХ (рд╕реА ++ рдореЗрдВ uint32_t ) рд╣реИрдВ, рдЬрдм рддрдХ рдХрд┐ рдЕрдиреНрдпрдерд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рди рд╣реЛред



FileHeader


рдирд╛рдо рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдпрд╣ рд╕рдВрдкреВрд░реНрдг рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╢реАрд░реНрд╖рд▓реЗрдЦ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝реАрд▓реНрдб рд╢рд╛рдорд┐рд▓ рд╣реИрдВ:



HeaderVersion - рд╣рдореЗрд╢рд╛ 0x00000001, рдЗрд╕ рд╣реЗрдбрд░ рдХреЗ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИред

CacheType - GCF рдХреЗ рд▓рд┐рдП 0x00000001 рдФрд░ NCF рдХреЗ рд▓рд┐рдП 0x00000002ред

FormatVersion - рд╢реЗрд╖ рд╣реЗрдбрд░ рдХреЗ рд╕рдВрд░рдЪрдирд╛ рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИред рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдг 6. рд╣реИ рдпрд╣ рдмрд╛рдж рдореЗрдВ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

ApplicationID - рдлрд╝рд╛рдЗрд▓ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ (AppID)ред

ApplicationVersion рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рд╛рдордЧреНрд░реА рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИред рдЕрджреНрдпрддрдиреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред

рдпрджрд┐ рдлрд╝рд╛рдЗрд▓ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдХрд┐рд╕реА рдЕрдиреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧ рджреНрд╡рд╛рд░рд╛ рдЖрд░реЛрд╣рд┐рдд рд╣реИ рддреЛ IsMounted - рдореЗрдВ 0x00000001 рд╕рдореНтАНрдорд┐рд▓рд┐рдд рд╣реИ ред рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрд╢рд╛ 0x00000000ред

рдбрдореА 0 рдПрдХ рд╕рдВрд░реЗрдЦрдг рдХреНрд╖реЗрддреНрд░ рд╣реИ рдЬрд┐рд╕рдореЗрдВ 0x00000000 рд╣реЛрддрд╛ рд╣реИред

FileSize рдХреБрд▓ рдлрд╝рд╛рдЗрд▓ рдЖрдХрд╛рд░ рд╣реИред рдпрджрд┐ рдпрд╣ 4 рдЬреАрдмреА рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ, рддреЛ рдЗрд╕ рдлрд╝реАрд▓реНрдб рдореЗрдВ рдЕрдВрддрд░ <рдлрд╝рд╛рдЗрд▓ рдЖрдХрд╛рд░> -ffffffff рд╣реИ , рдФрд░ рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЖрдХрд╛рд░ рд╕реНрд╡рдпрдВ рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ

рдбреЗрдЯрд╛ рдмреНрд▓реЙрдХ рдХрд╛ рдЖрдХрд╛рд░ рдФрд░ рдорд╛рддреНрд░рд╛ред

ClusterSize - рд╕рд╛рдордЧреНрд░реА рдореЗрдВ рдбреЗрдЯрд╛ рдмреНрд▓реЙрдХ рдХрд╛ рдЖрдХрд╛рд░ред GCF рдХреЗ рд▓рд┐рдП, рдЗрд╕рдореЗрдВ 0x00002000 рдФрд░ NCF, 0x00000000 рд╢рд╛рдорд┐рд▓ рд╣реИрдВред

ClusterCount - рд╕рд╛рдордЧреНрд░реА рдореЗрдВ рдбреЗрдЯрд╛ рдмреНрд▓реЙрдХ рдХреА рд╕рдВрдЦреНрдпрд╛ред

рдЪреЗрдХрд╕рдо рд╣реЗрдбрд░ рдХрд╛ рдЪреЗрдХрд╕рдо рд╣реИред рдЗрд╕рдХреА рдЧрдгрдирд╛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдп рджреНрд╡рд╛рд░рд╛ рдХреА рдЬрд╛рддреА рд╣реИ:



UINT32 HeaderChecksum(UINT8 *lpData, int Size) { UINT32 Checksum = 0; for (int i=0 ; i<Size ; i++) Checksum += *(lpData++); return Checksum; }
      
      





рдкрд╣рд▓рд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдкреЙрдЗрдВрдЯрд░ рдХреЛ рд╕рдВрд░рдЪрдирд╛ рдореЗрдВ рднреЗрдЬрддрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ - рдЗрд╕рдХрд╛ рдЖрдХрд╛рд░, рдЪреЗрдХрд╕рдо рдлреАрд▓реНрдб рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде (рдЬреЛ рдХрд┐ 4 рд╕реЗ рдХрдо рд╣реИ)ред



BlockAllocationTableHeader


рдмреНрд▓реЙрдХ рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рд╡рд┐рд╡рд░рдг рд╢рд╛рдорд┐рд▓ рд╣реИ (рд╕реЗрдХреНрдЯрд░ рдирд╣реАрдВ!):



рдмреНрд▓реЙрдХрдХрд╛рдЙрдВрдЯ - рдлрд╛рдЗрд▓ рдореЗрдВ рдХреБрд▓ рдмреНрд▓реЙрдХ рд╣реЛрддреЗ рд╣реИрдВред

BlocksUsed - рдкреНрд░рдпреБрдХреНрдд рдмреНрд▓реЙрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред рд╣рдореЗрд╢рд╛ рдмреНрд▓реЙрдХ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдХрдоред рдпрджрд┐ рдпрд╣ рдЖ рд░рд╣рд╛ рд╣реИ, рддреЛ рдХреБрд▓ рдорд╛рддреНрд░рд╛ рдХрд╛ рдореВрд▓реНрдп рдмрдврд╝ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рдмрд╛рдж рдХреЗ рд╕рднреА рд╣реЗрдбрд░ рдХреЗ рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг рдФрд░ рд╣реЗрдбрд░ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рди рдЦрд╛рд▓реА рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЕрдВрдд рдореЗрдВ рдкрд╣рд▓рд╛ рдбреЗрдЯрд╛ рд╕реЗрдХреНрдЯрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИред

LastUsedBlock - рдЕрдВрддрд┐рдо рдкреНрд░рдпреБрдХреНрдд рдмреНрд▓реЙрдХ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХред

рдбрдореА 0, рдбрдореА 1, рдбрдореА 2, рдбрдореА 2 - рдЕрд▓рд╛рдЗрдирдореЗрдВрдЯ рдлрд╝реАрд▓реНрдб рдореЗрдВ 0x00000000 рд╣реЛрддреЗ рд╣реИрдВред

рдЪреЗрдХрд╕рдо рд╣реЗрдбрд░ рдХрд╛ рдЪреЗрдХрд╕рдо рд╣реИред рдкрд┐рдЫрд▓реЗ рд╕рднреА рдХреНрд╖реЗрддреНрд░реЛрдВ рдХрд╛ рдпреЛрдЧ рд╕рдореНтАНрдорд┐рд▓рд┐рдд рд╣реИред



BlockAllocationTable


рдпрд╣ BlockAllocationTableEntry рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдПрдХ рд╕рд░рдгреА рд╣реИ, рдЬрд┐рд╕рдХреА рд╕рдВрдЦреНрдпрд╛ рдмреНрд▓реЙрдХ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ ( BlockAllocationTableHeader.BlockCount ):



рдЭрдВрдбреЗ - рдмреНрд▓реЙрдХ рдХреЗ рдмрд┐рдЯ рдЭрдВрдбреЗ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рд╕рдВрднрд╡ рдорд╛рд╕реНрдХ:



рдбрдореА 0 рд╕рдВрд░реЗрдЦрдг рдХреНрд╖реЗрддреНрд░, 0x0000 рд╢рд╛рдорд┐рд▓ рд╣реИрдВред

FileDataOffset рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдЗрд╕ рдмреНрд▓реЙрдХ рдХреА рднрд░рдкрд╛рдИ рд╣реЛрддреА рд╣реИред

FileDataSize - рдЗрд╕ рдмреНрд▓реЙрдХ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЯреБрдХрдбрд╝реЗ рдХрд╛ рдЖрдХрд╛рд░ред

FirstClusterIndex - рдХреНрд▓рд╕реНрдЯрд░ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкрд╣рд▓реЗ рдХреНрд▓рд╕реНрдЯрд░ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХред

NextBlockIndex - рдЕрдЧрд▓реЗ рдмреНрд▓реЙрдХ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХред рдЗрд╕рдореЗрдВ BlockAllocationTableHeader рдХрд╛ рдорд╛рди рд╕рдорд╛рд╣рд┐рдд рд╣реИред рдЕрдЧрд░ рдпрд╣ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХрд╛ рдЕрдВрддрд┐рдо рдмреНрд▓реЙрдХ рд╣реИ рддреЛ рдмреНрд▓реЙрдХрдХрд╛рдЙрдВрдЯ рдХрд░реЗрдВред

рдкрд┐рдЫрд▓рд╛рдмреНрд▓реЙрдХрдЗрдВрдбреЗрдХреНрд╕ - рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рдкрд┐рдЫрд▓реЗ рдмреНрд▓реЙрдХ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рд╢рд╛рдорд┐рд▓ рд╣реИред рдпрджрд┐ рдпрд╣ рдкрд╣рд▓рд╛ рд╣реИ, рддреЛ рдЗрд╕рдореЗрдВ BlockAllocationTableHeader рдХрд╛ рдорд╛рди рд╣реИ ред BlockCountред

ManifestIndex - рдЗрд╕ рдмреНрд▓реЙрдХ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХрдЯ рд╕реВрдЪрдХрд╛рдВрдХред

рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рдШреЛрд╖рдгрд╛рдкрддреНрд░ рд╕реВрдЪреА рд╕реЗ рдмреНрд▓реЙрдХ рдирдВрдмрд░ рд╣реИред



FileAllocationTableHeader


рд╕реЗрдХреНрдЯрд░ рддрд╛рд▓рд┐рдХрд╛ рд╢реАрд░реНрд╖ рд▓реЗрдЦ:



ClusterCount - рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред FileHeader.ClusterCount рдХреЗ рдмрд░рд╛рдмрд░ рдорд╛рди рд░рдЦрддрд╛ рд╣реИ ред

FirstUnusedEntry - рдкрд╣рд▓реЗ рдЕрдкреНрд░рдпреБрдХреНрдд рдХреНрд╖реЗрддреНрд░ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХред

IsLongTerminator - рдПрдХ рдорд╛рди рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╕реЗрдХреНрдЯрд░ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рдЕрдВрдд рдХрд╛ рдПрдХ рд╕рдВрдХреЗрддрдХ рд╣реИред рдпрджрд┐ рдЗрд╕рдореЗрдВ 0x00000000 рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рддреЛ рдЯрд░реНрдорд┐рдиреЗрдЯрд░ 0x0000FFFF рд╣реИ, рдЕрдиреНрдпрдерд╛ - 0xFFFFFFFFред

рдЪреЗрдХрд╕рдо рд╣реЗрдбрд░ рдХрд╛ рдЪреЗрдХрд╕рдо рд╣реИред BlockAllocationTableHeader рдХреА рддрд░рд╣, рдкрд┐рдЫрд▓реЗ рд╢реАрд░реНрд╖ рд▓реЗрдЦ рдлрд╝реАрд▓реНрдб рдХрд╛ рдпреЛрдЧ рд╣реИред



FileAllocationTable


FileAllocationTableHeader.ClusterCount рдкреНрд░рдХрд╛рд░ uint32_t рдХреА рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рд╡рд╛рд▓реА рдПрдХ рд╕реЗрдХреНрдЯрд░ рддрд╛рд▓рд┐рдХрд╛ред рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд▓ рдореЗрдВ рдЪреЗрди рдпрд╛ рдЯрд░реНрдорд┐рдиреЗрдЯрд░ рдорд╛рди рдореЗрдВ рдЕрдЧрд▓реЗ рдХреНрд▓рд╕реНрдЯрд░ рдХрд╛ рдЗрдВрдбреЗрдХреНрд╕ рд╣реЛрддрд╛ рд╣реИ (рдЪреЗрди рдореЗрдВ рдЕрдВрддрд┐рдо рд╣реЛрдиреЗ рдкрд░ FileAllocationTableHeader рдШреЛрд╖рдгрд╛ рджреЗрдЦреЗрдВред

рд╕реВрдЪреА рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рдХреНрд╖реЗрддреНрд░ рд╕рдВрдЦреНрдпрд╛ рд╣реИред



ManifestHeader


рдореЗрдирд┐рдлреЗрд╕реНрдЯ рдЯреЗрдмрд▓ рдХрд╛ рд╡рд┐рд╡рд░рдг рд╢рд╛рдорд┐рд▓ рд╣реИ:



рд╣реЗрдбрд░рд╡рд░реНрдЬрди рд╣реЗрдбрд░ рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИред 0x00000004 рд╢рд╛рдорд┐рд▓ рд╣реИрдВред

ApplicationID - рдлрд╝рд╛рдЗрд▓ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ред FileHeader.ApplicationID рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ ред

ApplicationVersion рдлрд╝рд╛рдЗрд▓ рдХреА рд╕рд╛рдордЧреНрд░реА рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИред FileHeader.ApplicationVersion рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ ред

NodeCount - рдкреНрд░рдХрдЯ рддрддреНрд╡реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред

FileCount - рдкреНрд░рдХрдЯ рдореЗрдВ рдШреЛрд╖рд┐рдд рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ (рдФрд░ рдХреИрд╢ рдореЗрдВ рдирд┐рд╣рд┐рдд)ред

CompressionBlockSize - рдПрдХ рд╕рдВрдкреАрдбрд╝рд┐рдд рдмреНрд▓реЙрдХ рдХрд╛ рдЕрдзрд┐рдХрддрдо рдЖрдХрд╛рд░ (рдЗрд╕рдХрд╛ рдЕрд╕рдореНрдкреАрдбрд┐рдд рдбреЗрдЯрд╛)ред

рдмрд╛рдЗрдирд░реАрд╕рд╛рдЗрдЬрд╝ - рдкреНрд░рдХрдЯ рдЖрдХрд╛рд░ (рдЗрд╕ рд╕рдВрд░рдЪрдирд╛ рд╕рд╣рд┐рдд)ред

NameSize - рддрддреНрд╡реЛрдВ (рдмрд╛рдЗрдЯреНрд╕) рдХреЗ рдирд╛рдо рд╡рд╛рд▓реЗ рдбреЗрдЯрд╛ рдмреНрд▓реЙрдХ рдХрд╛ рдЖрдХрд╛рд░ред

HashTableKeyCount - рд╣реИрд╢ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдорд╛рдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред

NumOfMinimumFootprintFiles - рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ (рдЬрд┐рд╕реЗ рдбрд┐рд╕реНрдХ рдкрд░ рдЕрдирдЬрд╝рд┐рдк рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП)ред

NumOfUserConfigFiles - рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред рдпрджрд┐ рдпрд╣ рдлрд╝рд╛рдЗрд▓ рдбрд┐рд╕реНрдХ рдкрд░ рд╣реИ, рддреЛ рдЦреЗрд▓ рд╢реБрд░реВ рд╣реЛрдиреЗ рдкрд░ рдЗрд╕реЗ рдЕрдзрд┐рд▓реЗрдЦрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рдЙрдЪреНрдЪ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╣реЛрддреА рд╣реИред

рдмрд┐рдЯрдорд╛рд╕реНрдХ - рдореЗрдВ рдмрд┐рдЯрдорд╛рд╕реНрдХ рд╣реЛрддреЗ рд╣реИрдВред рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдореЗрдВ, рдЗрд╕рдореЗрдВ рд╣рдореЗрд╢рд╛ 0x00000000 рд╢рд╛рдорд┐рд▓ рд╣реЛрддреЗ рд╣реИрдВред

рдлрд╝рд┐рдВрдЧрд░рдкреНрд░рд┐рдВрдЯ рдПрдХ рдЕрджреНрд╡рд┐рддреАрдп рд╕рдВрдЦреНрдпрд╛ рд╣реИ рдЬреЛ рд╣рд░ рдмрд╛рд░ рдкреНрд░рдХрдЯ рд╣реЛрдиреЗ рдкрд░ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИред

рдЪреЗрдХрд╕рдо - рдЪреЗрдХрд╕рдоред рдпрд╣ рдПрдбрд▓рд░ 32 рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЧрдгрдирд╛ рдХреА рдЬрд╛рддреА рд╣реИред рдЧрдгрдирд╛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рд╣реЗрдбрд░ рдХреЗ рд╡рд┐рд╡рд░рдг рдХреЗ рдмрд╛рдж рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред



рдкреНрд░рдХрдЯ


рдПрдХ рдкреЗрдбрд╝ рдЬрд┐рд╕рдореЗрдВ рдХреИрд╢ рдХреА рд╕рднреА рдлрд╛рдЗрд▓реЛрдВ рдХрд╛ рд╡рд┐рд╡рд░рдг рд╣реЛрддрд╛ рд╣реИред рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЖрдХрд╛рд░ рдШреЛрд╖рдгрд╛рдкрддреНрд░ рдХреЗ рдорд╛рди рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред NodeCount ред рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд╕рднреА рддрддреНрд╡реЛрдВ рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рдВрд░рдЪрдирд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рджрд░реНрд╢рд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:



NameOffset - рд╕рдВрдмрдВрдзрд┐рдд рдбреЗрдЯрд╛ рдмреНрд▓реЙрдХ рдореЗрдВ рддрддреНрд╡ рдХреЗ рдирд╛рдо рдХреА рдСрдлрд╕реЗрдЯред

CountOrSize - рддрддреНрд╡ рдХрд╛ рдЖрдХрд╛рд░ред рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдмрдЪреНрдЪреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ, рдФрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рд╕реАрдзреЗ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЖрдХрд╛рд░ (рдпрд╛ рдЗрд╕ рдкреНрд░рдХрдЯ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдлрд╝рд╛рдЗрд▓ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛) рдХреЗ рд▓рд┐рдПред

FileId - рдлрд╝рд╛рдЗрд▓ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ред рдмрдбрд╝реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдХрдИ рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рд▓рд┐рдВрдХ рдХрд░рдиреЗ рдФрд░ рдЪреЗрдХрд╕рдо рд╕реВрдЪреА рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред

рд╡рд┐рд╢реЗрд╖рддрд╛рдПрдБ - рдлрд╝рд╛рдЗрд▓ рд╡рд┐рд╢реЗрд╖рддрд╛ рдмрд┐рдЯ рдлрд╝реАрд▓реНрдбред рд╕рдВрднрд╛рд╡рд┐рдд рдорд╛рди (рдкреБрд╖реНрдЯрд┐ рд╕реЗ):





ParentIndex рдореВрд▓ рддрддреНрд╡ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рд╣реИред рдЬрдбрд╝ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП 0xFFFFFFFF рд╣реИред

NextIndex - рд╡рд░реНрддрдорд╛рди рдкреЗрдбрд╝ рдХреЗ рд╕реНрддрд░ рдкрд░ рдЕрдЧрд▓реЗ рддрддреНрд╡ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХред

рдЪрд╛рдЗрд▓реНрдбрдЗрдВрдбреЗрдХреНрд╕ рдкрд╣рд▓реЗ рдмрдЪреНрдЪреЗ рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рд╣реИред

рдпрджрд┐ NextIndex рдФрд░ ChildIndex рдХреЗ рд▓рд┐рдП рдХреЛрдИ рддрддреНрд╡ рдирд╣реАрдВ рд╣реИрдВ, рддреЛ рдЙрдирдХрд╛ рдорд╛рди 0x00000000 рд╣реЛрддрд╛ рд╣реИред

рдПрдХ рдкреЗрдбрд╝ рдореЗрдВ рдХрдо рд╕реЗ рдХрдо рдПрдХ рддрддреНрд╡ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП - рдЬрдбрд╝ред

рдЯреНрд░реА рдЖрдЗрдЯрдо рд╡рд╛рд▓реА рд╕реВрдЪреА рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХ рдЖрдЗрдЯрдо рдирдВрдмрд░ рд╣реИ (рдмрд╛рдж рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛)



рдлрд╝рд╛рдЗрд▓ рдирд╛рдо


рдЖрдХрд╛рд░ рдХрд╛ рдПрдХ рдбреЗрдЯрд╛ рдмреНрд▓реЙрдХ ManifestHeader.NameSize рдмрд╛рдЗрдЯреНрд╕ред рдЗрд╕рдореЗрдВ рдирд▓-рдЯрд░реНрдорд┐рдиреЗрдЯреЗрдб рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЬреЛ рдХрд┐ рдкреНрд░рдХрдЯ рдкреЗрдбрд╝ рдореЗрдВ рд╡рд░реНрдгрд┐рдд рддрддреНрд╡реЛрдВ рдХреЗ рдирд╛рдо рд╣реИрдВред рдЕрдирд┐рд╡рд╛рд░реНрдп рдкрд╣рд▓реЗ, рдЬрдбрд╝ рддрддреНрд╡ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рд╣реИ - рдПрдХ рдЦрд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧред рддрддреНрд╡ рдирд╛рдореЛрдВ рдХреА рднрд░рдкрд╛рдИ рдореВрд▓реНрдп рдореЗрдирд┐рдлреЗрд╕реНрдЯ [] рдХреЗ рдирд╛рдо рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╣реИ ред NameOffset



HashTableKeys


рддрддреНрд╡ рдирд╛рдореЛрдВ рдХреА рд╣реИрд╢ рддрд╛рд▓рд┐рдХрд╛ рд╕рдорд╛рд╣рд┐рдд рдХрд░рддрд╛ рд╣реИред HashTableIndices рдХреЗ рд▓рд┐рдП рдЗрдВрдбреЗрдХреНрд╕ рд╡реИрд▓реНрдпреВрдЬрд╝ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЬреЛ рдХрд┐ рд▓реЛрдЕрд░рдХреЗрд╕ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рд▓рд┐рдП рдЬреЗрдирдХрд┐рдВрд╕ рд╣реИрд╢ рдлрдВрдХреНрд╢рди рд▓реБрдХрдЕрдк 2 рд╕реЗ рдкреНрд░рд╛рдкреНрдд рд╕реВрдЪрдХрд╛рдВрдХреЛрдВ рдкрд░ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдП рдЧрдП рд╣реИрдВред рддрддреНрд╡реЛрдВ рдХреА рдЦреЛрдЬ рдХреЗ рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЕрдзрд┐рдХ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреАред



HashTableIndices


рдкрд┐рдЫрд▓реА рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдорд╛рдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдВрджрд░реНрднрд┐рдд рддрддреНрд╡реЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдорд┐рдд рдХреА рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред рддрддреНрд╡реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ ManifestHeader.NodeCount рд╣реИ ред



MinimumFootprints


рдореИрдирд┐рдлреЗрд╕реНрдЯ рдореЗрдВ рдЖрдЗрдЯрдо рдирдВрдмрд░ рдХреА рдПрдХ рд╕реВрдЪреА рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬрд┐рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╢реБрд░реВ рд╣реЛрдиреЗ рдкрд░ рдЕрдирдкреИрдХ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред



UserConfigs


рдореИрдирд┐рдлрд╝реЗрд╕реНрдЯ рдореЗрдВ рдЖрдЗрдЯрдо рдирдВрдмрд░ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓реЗрдВ рд╣реИрдВред



ManifestMapHeader


рдореИрдиреАрдлреЗрд╕реНрдЯ рдореИрдк рд╣реИрдбрд░:



рд╣реЗрдбрд░рд╡рд░реНрдЬрди рд╣реЗрдбрд░ рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИред рдмрд░рд╛рдмрд░ 0x00000001ред

рдбрдореА 0 рдПрдХ рд╕рдВрд░реЗрдЦрдг рдореВрд▓реНрдп рд╣реИред 0x00000000 рд╢рд╛рдорд┐рд▓ рд╣реИрдВред



ManifestMap


рдкреНрд░рддреНрдпреЗрдХ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рдмреНрд▓реЙрдХ ( BlockAllocationTable рд╕рдВрд░рдЪрдирд╛) рдХреЗ рд▓рд┐рдВрдХ рдХреА рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред рдПрдХ рддрддреНрд╡ рд╕реВрдЪрдХрд╛рдВрдХ рдкреНрд░рдХрдЯ рдкреЗрдбрд╝ рдореЗрдВ рдПрдХ рддрддреНрд╡ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реИред рдирд┐рд░реНрджреЗрд╢рд┐рдХрд╛рдУрдВ рдФрд░ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдХреИрд╢ рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рд╢реВрдиреНрдп рдЖрдХрд╛рд░ рдпрд╛ NCF рдХреЗ рд▓рд┐рдП), рдЗрд╕рдореЗрдВ рдмреНрд▓реЙрдХрдЕрдХреНрд▓реЛрдХреЗрд╢рдирдЯреЗрдмрд▓ рд╣реИрдбрд░.рдмреНрд▓реЙрдХрд╛рдЙрдВрдЯ рдХреЗ рдмрд░рд╛рдмрд░ рдореВрд▓реНрдп рд╣реЛрддрд╛ рд╣реИред



ChecksumDataContainer


рдХрдВрдЯреЗрдирд░ рдХрд╛ рд╣реЗрдбрд░ рдЬреЛ рдЪреЗрдХрд╕рдо рдХреЛ рд╕реНрдЯреЛрд░ рдХрд░рддрд╛ рд╣реИ:



рд╣реЗрдбрд░рд╡рд░реНрдЬрди рд╣реЗрдбрд░ рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИред рдмрд░рд╛рдмрд░ 0x00000001ред

ChecksumSize - рдХрдВрдЯреЗрдирд░ рдХрд╛ рдЖрдХрд╛рд░ред рдЗрд╕рдХреА рдЧрдгрдирд╛ рдирд┐рдореНрди рд╕рдВрд░рдЪрдирд╛ рд╕реЗ рдХреА рдЬрд╛рддреА рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдирд╡реАрдирддрдордПрдкреНрд▓реАрдХреЗрд╢рди рд╡рд░реНрдЬрди рд╕рдореНрдорд┐рд▓рд┐рдд рд╣реИред



FileIdChecksumTableHeader


рдЪреЗрдХрд╕рдо рдЗрдВрдбреЗрдХреНрд╕ рдЯреЗрдмрд▓ рдХрд╛ рд╢реАрд░реНрд╖рдХ:



рдлрд╝реЙрд░реНрдореЗрдЯрдХреЛрдб рдПрдХ рд╕реНрдерд┐рд░ рд╣реИред рдмрд░рд╛рдмрд░ 0x14893721ред

Dummy0 рдПрдХ рд╕рдорддрд▓ рдХреНрд╖реЗрддреНрд░ рд╣реИред 0x00000001 рдХрд╛ рдорд╛рди рд╕рдорд╛рд╣рд┐рдд рдХрд░рддрд╛ рд╣реИред

FileIdCount - рддрддреНрд╡-рдкреНрд░рдердо-рд╣реИрд╢ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рддрддреНрд╡реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред

рдЪреЗрдХрд╕рдордорд╛рдЙрдВрдЯ - рдЪреЗрдХрд╕рдо рд╕реВрдЪреА рдореЗрдВ рддрддреНрд╡реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред



FileIdChecksums


рдЪреЗрдХрд╕рдо рд╕реВрдЪреА рдореЗрдВ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рд╡рд╛рд▓реА рдПрдХ рддрд╛рд▓рд┐рдХрд╛:



ChecksumCount - рдЗрд╕ рддрддреНрд╡ рдХреЗ рд▓рд┐рдП рд╕реВрдЪреА рдореЗрдВ рдЪреЗрдХрд╕рдо рдХреА рд╕рдВрдЦреНрдпрд╛ред

FirstChecksumIndex - рд╕реВрдЪреА рдореЗрдВ рдкрд╣рд▓реЗ рдЪреЗрдХрд╕рдо рдХрд╛ рд╕реВрдЪрдХрд╛рдВрдХред

рдЗрдВрдбреЗрдХреНрд╕ рдореИрдирд┐рдлреЗрд╕реНрдЯ [] рдорд╛рди рд╣реИред



рдЪреЗрдХрд╕рдо


рдЪреЗрдХрд╕рдо рдХреА рд╕реВрдЪреАред рдЗрд╕рдореЗрдВ рд▓рдЧрд╛рддрд╛рд░ рдЙрдкрдЦрдВрдб рд╢рд╛рдорд┐рд▓ рд╣реИрдВ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкрд╣рд▓рд╛ рддрддреНрд╡ FileIdChecksums [] FirstChecksumIndex рдХреЗ рдорд╛рди рд╕реЗ рд╕рдВрджрд░реНрднрд┐рдд рд╣реИред

рдорд╛рдиреЛрдВ рдХреА рдЧрдгрдирд╛ рдирд┐рдореНрди рдПрд▓реНрдЧреЛрд░рд┐рдердо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреА рдЬрд╛рддреА рд╣реИ:



 UINT32 Checksum(UINT8 *lpData, UINT32 uiSize) { return (adler32(0, lpData, uiSize) ^ crc32(0, lpData, uiSize)); }
      
      







рдЪреЗрдХрд╕рдо рд╣рд╕реНрддрд╛рдХреНрд╖рд░


рдЪреЗрдХрд╕рдо рдмреНрд▓реЙрдХ рдХреЗ рд╣рд╕реНрддрд╛рдХреНрд╖рд░ред SHA-1 рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рджреНрд╡рд╛рд░рд╛ рдЧрдгрдирд╛ рдХреА рдЧрдИ рдФрд░ RSASSA-PKCS1-v1_5 рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рджреНрд╡рд╛рд░рд╛ рдЧрдгрдирд╛ рдХреА рдЧрдИ рдЪреЗрдХрд╕рдо рдмреНрд▓реЙрдХ рдХреЗ рд▓рд┐рдП рд╣реИрд╢ рдорд╛рди рд╣реЛрддрд╛ рд╣реИ ред



LatestApplicationVersion


рдЗрд╕ рдлрд╝реАрд▓реНрдб рдореЗрдВ рдЪреЗрдХрд╕рдо рдмреНрд▓реЙрдХ рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рд╕рд╛рдордЧреНрд░реА рдЕрдкрдбреЗрдЯ рдХреЗ рдмрд╛рдж рдХрд░рдВрдЯ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ред



DataHeader


рдХреИрд╢ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЗ рднреМрддрд┐рдХ рд╕реНрдерд╛рди рдХрд╛ рд╡рд░реНрдгрди рд╢реАрд░реНрд╖рдХ:



ClusterCount - рд╕реЗрдХреНрдЯрд░реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред рдорд╛рди FileHeader.ClusterCount рдлрд╝реАрд▓реНрдб рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред

рдХреНрд▓рд╕реНрдЯрд░ рдЖрдХрд╛рд░ - рдХреНрд╖реЗрддреНрд░ рдХрд╛ рдЖрдХрд╛рд░ред рдорд╛рди FileHeader.ClusterSize рдлрд╝реАрд▓реНрдб рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИред

FirstClusterOffset - рдлрд╝рд╛рдЗрд▓ рдХреА рд╢реБрд░реБрдЖрдд рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдкрд╣рд▓реЗ рдХреНрд╖реЗрддреНрд░ рдХреА рдСрдлрд╕реЗрдЯред

рдХреНрд▓рд╕реНрдЯрд░реНрд╕рдпреВрд▓реНрдб - рдкреНрд░рдпреБрдХреНрдд рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ред

рдЪреЗрдХрд╕рдо рд╣реЗрдбрд░ рдХрд╛ рдЪреЗрдХрд╕рдо рд╣реИред рдкреВрд░реНрд╡рд╡рд░реНрддреА рд╣реЗрдбрд░ рдлрд╝реАрд▓реНрдб рдХреЗ рдпреЛрдЧ рдХреЗ рдмрд░рд╛рдмрд░ред

рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдШрдЯ рд╕рдХрддреА рд╣реИред рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдореБрдХреНрдд рдХрд┐рдП рдЧрдП рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рднрд╡рд┐рд╖реНрдп рдХреЗ рдЕрдкрдбреЗрдЯ рдХреЗ рд▓рд┐рдП рд╕реНрдерд╛рди рдЖрд░рдХреНрд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд╝рд╛рдЗрд▓ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред



рдПрд▓реНрдЧреЛрд░рд┐рджрдо



рдЕрдВрдд рдореЗрдВ, рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдХреА рдмрд╛рд░реА рдЖрдИ - рдХреЛрдб рдХрд╛ рд╕рдмрд╕реЗ рджрд┐рд▓рдЪрд╕реНрдк рдЙрджрд╛рд╣рд░рдг рдЬреЛ рдЗрди рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд╕рд╛рде рд╡рд┐рд╕реНрддреГрдд рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдкреВрд░реНрдг рд╕реНрд░реЛрдд рдкреИрдХреЗрдЬ рдореЗрд░реЗ рднрдВрдбрд╛рд░ рдкрд░ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред



рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЖрдХрд╛рд░ рдЧрдгрдирд╛


рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдлрд╝рд╛рдЗрд▓ рдХрд╛ рдЖрдХрд╛рд░ рдореИрдирд┐рдлреЗрд╕реНрдЯ [] рдХреЗ рдорд╛рди рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ ред CountOrSize рдлрд╝реАрд▓реНрдб ред рд▓реЗрдХрд┐рди 4GB рд╕реЗ рдмрдбрд╝реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рддрд░реАрдХрд╛ рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИред рд╡рд╛рд▓реНрд╡ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░реНрд╕ рдиреЗ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рджрд░рдХрд┐рдирд╛рд░ рдХрд┐рдпрд╛: 2 рдЬреАрдмреА рд╕реЗ рдмрдбрд╝реА рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдлрд╝реАрд▓реНрдб рдХреЗ рдЙрдЪреНрдЪ рдмрд┐рдЯ рдХреЛ "1" рдкрд░ рд╕реЗрдЯ рдХрд░реЗрдВ рдФрд░ рд╕реВрдЪреА рдореЗрдВ рд╢реЗрд╖ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рд╕рдорд╛рди рдореВрд▓реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдФрд░ (рдпрд╛ рдХрдИ) рддрддреНрд╡реЛрдВ рдХреЛ рд╢реБрд░реВ рдХрд░реЗрдВ, рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рд╢реНрд░реГрдВрдЦрд▓рд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред рдореИрдирд┐рдлреЗрд╕реНрдЯ [] рдХреЗ рдореВрд▓реНрдп рдХреЛ рд╕рд╛рд░рд╛рдВрд╢рд┐рдд рдХрд░рдирд╛ред рдЗрд╕ рд╢реНрд░реГрдВрдЦрд▓рд╛ рд╕реЗ рдлрд╝реАрд▓реНрдбреНрд╕ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ, рд╣рдо рдХреБрд▓ рдлрд╝рд╛рдЗрд▓ рдЖрдХрд╛рд░ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред



рдлрд╛рдЗрд▓ рд╕рд╛рдЗрдЬ рдХрд╛рдЙрдВрдЯрд┐рдВрдЧ рдХреЛрдб
 UINT64 CGCFFile::GetFileSize(UINT32 Item) { UINT64 res = lpManifest[Item].CountOrSize & 0x7FFFFFFF; if ((lpManifest[Item].CountOrSize & 0x80000000) != 0) { for (UINT32 i=0 ; i<pManifestHeader->NodeCount ; i++) { ManifestNode *MN = &lpManifest[Item]; if (((MN->Attributes & 0x00004000) != 0) && (MN->ParentIndex == 0xFFFFFFFF) && (MN->NextIndex == 0xFFFFFFFF) && (MN->ChildIndex == 0xFFFFFFFF) && (MN->FileId == lpManifest[Item].FileId)) { res += MN->CountOrSize << 31; break; } } } return res; }
      
      





рдпрд╣рд╛рдБ рдореИрдВрдиреЗ рдЕрдкрдиреЗ рдХрд╛рдиреЛрдВ рд╕реЗ рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ "рдлреЗрдВрдЯ" рдмрдирд╛рдпрд╛, рдпрд╣ рдорд╛рдирддреЗ рд╣реБрдП рдХрд┐ 4GB рд╕реЗ рдмрдбрд╝реА рдлрд╛рдЗрд▓реЗрдВ рдЕрднреА рднреА рдХреИрд╢ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдирд╣реАрдВ рд╣реЛрдВрдЧреА ...



рдирд╛рдо рд╕реЗ рдПрдХ рдЖрдЗрдЯрдо рдХреЗ рд▓рд┐рдП рдЦреЛрдЬреЗрдВ


рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ "hl2 / map / background_01.bsp" рдирд╛рдордХ рдПрдХ рдлрд╝рд╛рдЗрд▓ рдЦреЛрдЬрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╣рдорд╛рд░реЗ рджреНрд╡рд╛рд░рд╛ рд╕рдВрдЧреНрд░рд╣реАрдд рд╕рднреА рдирд╛рдо рдПрдХ рдкреЗрдбрд╝ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдореЗрдВ рдПрдХ рд╡рд┐рднрд╛рдЬрдХ (рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, "/") рд╕реЗ рдЬреБрдбрд╝реЗ рддрддреНрд╡реЛрдВ рдореЗрдВ рдкрде рдХреЛ рддреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛ред рдлрд┐рд░ рд╣рдо рдореВрд▓ рддрддреНрд╡ рдХреЗ рд╡рдВрд╢рдЬ рд╕реЗ "hl2" рдирд╛рдо рдХреЗ рддрддреНрд╡ рдХреА рддрд▓рд╛рд╢ рдХрд░рддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдкрд╛рд╕ "рдореИрдкреНрд╕" рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рддрддреНрд╡ рд╣реИ, рдФрд░ рдХреЗрд╡рд▓ "рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб_01.рд╕реНрдкреВрди" рдирд╛рдо рдХреЗ рд╕рд╛рде рдПрдХ рддрддреНрд╡ рд╣реИред рдпрд╣ рд░рд╛рд╕реНрддрд╛ рд╕рдмрд╕реЗ рд╕реНрдкрд╖реНрдЯ рд╣реИ, рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдзреАрдорд╛ рд╣реИ - рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреА рдПрдХ рдмрд╛рдЗрдЯ рддреБрд▓рдирд╛ рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдкреЗрдбрд╝ рдХрд╛ рджреМрд░рд╛ рднреА рд╣реИред рд╕рд░рд╛рд╕рд░ рдЦрд░реНрдЪ

рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рддреЗрдЬ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣реИрд╢ рдЯреЗрдмрд▓ рд╣реЗрдбрд░ рдореЗрдВ рд╣реИрдВред



рдХрд┐рд╕реА рд╣реИрд╢ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рдЖрдЗрдЯрдо рдХреЗ рд▓рд┐рдП рдЦреЛрдЬреЗрдВ
рд╕реА ++

 UINT32 CGCFFile::GetItem(char *Item) { int DelimiterPos = -1; for (UINT32 i=0 ; i<strlen(Item) ; i++) if (Item[i] == '\\') DelimiterPos = i; char *FileName = &Item[++DelimiterPos]; UINT32 Hash = jenkinsLookupHash2((UINT8*)FileName, strlen(FileName), 1), HashIdx = Hash % pManifestHeader->HashTableKeyCount, HashFileIdx = lpHashTableKeys[HashIdx]; if (HashFileIdx == CACHE_INVALID_ITEM) if (strcmp(LowerCase(Item), Item) != 0) { Hash = jenkinsLookupHash2((UINT8*)LowerCase(Item), strlen(FileName), 1); HashIdx = Hash % pManifestHeader->HashTableKeyCount; HashFileIdx = lpHashTableKeys[HashIdx]; } if (HashFileIdx == CACHE_INVALID_ITEM) return CACHE_INVALID_ITEM; HashFileIdx -= pManifestHeader->HashTableKeyCount; while (true) { UINT32 Value = this->lpHashTableIndices[HashFileIdx]; UINT32 FileID = Value & 0x7FFFFFFF; if (strcmp(GetItemPath(FileID), Item) == 0) return FileID; if ((Value & 0x80000000) == 0x80000000) break; HashFileIdx++; } return CACHE_INVALID_ITEM; }
      
      





рдбреЗрд▓реНрдлреА

 function TGCFFile.GetItemByPath(Path: string): integer; var end_block: boolean; Hash, HashIdx, HashValue: ulong; FileID, HashFileIdx: integer; PathEx: AnsiString; begin result:=-1; {$IFDEF UNICODE} PathEx:=Wide2Ansi(ExtractFileName(Path)); {$ELSE} PathEx:=ExtractFileName(Path); {$ENDIF} Hash:=jenkinsLookupHash2(@PathEx[1], Length(PathEx), 1); HashIdx:=Hash mod fManifestHeader.HashTableKeyCount; HashFileIdx:=lpHashTableKeys[HashIdx]; if HashFileIdx=-1 then begin if (LowerCase(Path)<>Path) then begin {$IFDEF UNICODE} Hash:=jenkinsLookupHash2(@LowerCaseAnsi(PathEx)[1], Length(PathEx), 1); {$ELSE} Hash:=jenkinsLookupHash2(@LowerCase(PathEx)[1], Length(PathEx), 1); {$ENDIF} HashIdx:=Hash mod fManifestHeader.HashTableKeyCount; HashFileIdx:=lpHashTableKeys[HashIdx]; if HashFileIdx=-1 then Exit; end; end; dec(HashFileIdx, fManifestHeader.HashTableKeyCount); repeat HashValue:=lpHashTableIndices[HashFileIdx]; FileID:=HashValue and $7FFFFFFF; end_block:= (HashValue and $80000000 = $80000000); if CompareStr(ItemPath[FileID], Path)=0 then begin result:=FileID; Exit; end; inc(HashFileIdx); until end_block; if (result=-1) and (LowerCase(Path)<>Path) then result:=GetItemByPath(LowerCase(Path)); end;
      
      





рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдХреЛрдб рд╕реЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдкреВрд░реЗ рд░рд╛рд╕реНрддреЗ рд╕реЗ рдлрд╛рдЗрд▓ рддрдХ рд╣рдо рдХреЗрд╡рд▓ рдЗрд╕рдХрд╛ рдирд╛рдо рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдкрд░рд┐рдгрд╛рдо рдХреЗ рд╢реЗрд╖ рдкреВрд░реНрдгрд╛рдВрдХ рд╡рд┐рднрд╛рдЬрди рдХреЛ рдорд╛рди ManifestHeader.ashTableKeyCount рджреНрд╡рд╛рд░рд╛ рд▓реЗрддреЗ рд╣реИрдВ - рдпрд╣ HashTableKeys рд╕реВрдЪреА рдореЗрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реЛрдЧреА рдЬрд┐рд╕рдореЗрдВ 0xffffffff (рдпрджрд┐ рдРрд╕рд╛ рдХреЛрдИ рддрддреНрд╡ рдирд╣реАрдВ рд╣реИ) рдпрд╛ рдорд╛рди X + ManifestHeader.HashTableKeyCount рд╣реИ ред рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо X рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ HashTableIndices рд╕реВрдЪреА рдореЗрдВ рддрддреНрд╡ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдкрд╛рдпрд╛ рдЬрд╛рдиреЗ рд╡рд╛рд▓рд╛ рддрддреНрд╡ рдкрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЗрд╕ рд╕реВрдЪреА рдХреЗ рдорд╛рди рдЦреЛрдЬреЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдЖрдЗрдЯрдо рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдирд╛рдо рдХреНрд╡реЗрд░реА рдореЗрдВ рддреБрд▓рдирд╛ рдХреА рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рдпрд╣ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рд╕реВрдЪреА рдХреЗ рдЕрдЧрд▓реЗ рддрддреНрд╡ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рддрдм рддрдХ рджреЛрд╣рд░рд╛рддреЗ рд╣реИрдВ рдЬрдм рддрдХ рдХрд┐ рддрддреНрд╡ рд╕рдВрдЦреНрдпрд╛ рдХрд╛ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдЯ "0" рди рд╣реЛред

рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рднреНрд░рдорд┐рдд рд╣реЛ рдЧрдпрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ ... рдЗрд╕ рддрд░рд╣ рдХреЗ рднреНрд░рдо рдХреЗ рд▓рд┐рдП рд╡рд╛рд▓реНрд╡ рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХреЛ рджреЛрд╖ рджреЗрдВред

рдпрд╣ рд╡рд┐рдзрд┐ рдкреЗрдбрд╝ рдореЗрдВ рдкреНрд░рддреНрдпрдХреНрд╖ рдЦреЛрдЬ рд╕реЗ рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд╣реИ - рдЦреЗрд▓ рд╢реБрд░реВ рдХрд░рддреЗ рд╕рдордп рдкреНрд░рджрд░реНрд╢рди рдХреА рддреБрд▓рдирд╛ рд╕реНрдЯреАрдо.рдбреЗрд▓ рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рд▓рд╛рдЗрдмреНрд░реЗрд░реА-рдПрдореБрд▓реЗрдЯрд░ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд╕рд╛рде рдХреА рдЧрдИ рдереА, рдЬрд┐рд╕ рдкрд░ рдЕрднреА рднреА рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреАред



рдХрд┐рд╕реА рддрддреНрд╡ рдХреЛ рдкреВрд░реНрдг рдкрде рдорд┐рд▓рдирд╛


рдпрд╣ рдХреНрд░рд┐рдпрд╛ рдкрд┐рдЫрд▓реЗ рдПрдХ рдкрд░ рд╡рд╛рдкрд╕ рдЖ рдЧрдИ рд╣реИ - рдЙрд╕ рддрддреНрд╡ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ, рдЬрд┐рд╕реЗ рдЖрдкрдХреЛ рдкреЗрдбрд╝ рд╕реЗ рдЬрдбрд╝ рддрддреНрд╡ рддрдХ рдЬрд╛рдиреЗ рдХреА рдЬрд╝рд░реВрд░рдд рд╣реИ рдФрд░ рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрде рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╣реИред



рдлрд╝рд╛рдЗрд▓ рдкрде рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛
рд╕реА ++

 char *CGCFFile::GetItemPath(UINT32 Item) { size_t len = strlen(&lpNames[lpManifest[Item].NameOffset]); UINT32 Idx = lpManifest[Item].ParentIndex; while (Idx != CACHE_INVALID_ITEM) { len += strlen(&lpNames[lpManifest[Idx].NameOffset]) + 1; Idx= lpManifest[Idx].ParentIndex; } len--; char *res = new char[len+1]; memset(res, 0, len+1); size_t l = strlen(&lpNames[lpManifest[Item].NameOffset]); memcpy(&res[len-l], &lpNames[lpManifest[Item].NameOffset], l); len -= strlen(&lpNames[lpManifest[Item].NameOffset]); res[--len] = '\\'; Item = lpManifest[Item].ParentIndex; while ((Item != CACHE_INVALID_ITEM) && (Item != 0)) { l = strlen(&lpNames[lpManifest[Item].NameOffset]); memcpy(&res[len-l], &lpNames[lpManifest[Item].NameOffset], l); len -= strlen(&lpNames[lpManifest[Item].NameOffset]); res[--len] = '\\'; Item = lpManifest[Item].ParentIndex; } return res; }
      
      





рдбреЗрд▓реНрдлреА

 function TGCFFile.GetItemPath(Item: integer): string; var res: AnsiString; begin res:=pAnsiChar(@fNameTable[lpManifestNodes[Item].NameOffset+1]); Item:=lpManifestNodes[Item].ParentIndex; while (Item>-1) do begin res:=pAnsiChar(@fNameTable[lpManifestNodes[Item].NameOffset+1])+'\'+res; Item:=lpManifestNodes[Item].ParentIndex; end; Delete(res, 1, 1); {$IFDEF UNICODE} result:=Ansi2Wide(res); {$ELSE} result:=res; {$ENDIF} end;
      
      





рдбреЗрд▓реНрдлреА рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реИ рдХрд┐ C ++ рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ std :: string class рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ - рдореБрдЭреЗ рддрдм рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкрддрд╛ рдирд╣реАрдВ рдерд╛ред рдЗрд╕рдХреЗ рд╕рд╛рде, рдХреЛрдб рдмрд╣реБрдд рдХрдо рд╣реЛрдЧрд╛ ...



рдзрд╛рд░рд╛рдУрдВ


рд╕рдВрдЧреНрд░рд╣-рдЬреИрд╕реЗ рдлрд╝рд╛рдЗрд▓ рд╕реНрд╡рд░реВрдкреЛрдВ (рдЬрд┐рд╕рдореЗрдВ рдЕрдиреНрдп рдлрд╝рд╛рдЗрд▓реЗрдВ рд╣реИрдВ) рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд▓рд┐рдЦрддреЗ рд╕рдордп, рдореИрдВ "рд╕реНрдЯреНрд░реАрдо-рдЗрди-рд╕реНрдЯреНрд░реАрдо" рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рдЬреЛ рдЖрдкрдХреЛ рдмрд┐рдирд╛ рд╕рдВрдЧреНрд░рд╣ рдХрд┐рдП рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ рдЦреЛрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреБрд░рд╛рдиреЗ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рдХреИрд╢ рдЖрдзрд╛-рдЬреАрд╡рди рдореЗрдВред рдПрдХ рдлрд╝рд╛рдЗрд▓ pak0.pak рдереА , рдЬреЛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╣реИред рдирддреАрдЬрддрди, рдореИрдВрдиреЗ рдЖрдзрд╛ рдЬреАрд╡рди рдЦреЛрд▓рд╛ред рдЬреАрд╕реАрдПрдл рдлрд╝рд╛рдЗрд▓ , рдЗрд╕рдореЗрдВ - pak0.pak ред рдЬрд┐рд╕рдореЗрдВ, рдмрджрд▓реЗ рдореЗрдВ, рдореИрдВ рдЖрд╡рд╢реНрдпрдХ рдлрд╛рдЗрд▓реЗрдВ рдкрдврд╝рддрд╛ рд╣реВрдВред рдФрд░ рдпрд╣ рд╕рдм - рдореЗрдореЛрд░реА рдореЗрдВ рднреА рдЕрдирдкреИрдХ рдХрд┐рдП рдмрд┐рдирд╛, рд╕рднреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЛ рдореИрдВрдиреЗ рдлрд╛рдЗрд▓ рд╕реНрдЯреНрд░реАрдо (WindowsAPI рд╕реНрддрд░ рдкрд░ рдирд┐рдореНрди-рд╕реНрддрд░) рдкрд░ рд▓рд┐рдЦреЗ рд░реИрдкрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рд╣реИред



рдХреИрд╢ рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдЦреЛрд▓рдирд╛
рд╕реА ++

 CStream *CGCFFile::OpenFile(char* FileName, UINT8 Mode) { UINT32 Item = GetItem(FileName); if (Item == CACHE_INVALID_ITEM) return NULL; if ((lpManifest[Item].Attributes & CACHE_FLAG_FILE) != CACHE_FLAG_FILE) return NULL; return OpenFile(Item, Mode); } CStream *CGCFFile::OpenFile(UINT32 Item, UINT8 Mode) { StreamData *Data = new StreamData(); memset(Data, 0, sizeof(StreamData)); Data->Handle = (handle_t)Item; Data->Package = this; Data->Size = this->GetItemSize(Item).Size; if (IsNCF) Data->FileStream = (CStream*)new CStream(MakeStr(CommonPath, GetItemPath(Item)), Mode==CACHE_OPEN_WRITE); else BuildClustersTable(Item, &Data->Sectors); return new CStream(pStreamMethods, Data); }
      
      





рдбреЗрд▓реНрдлреА

 function TGCFFile.OpenFile(FileName: string; Access: byte): TStream; var Item: integer; begin result:=nil; Item:=ItemByPath[FileName]; if (Item=-1) then Exit; if ((lpManifestNodes[Item].Attributes and HL_GCF_FLAG_FILE<>HL_GCF_FLAG_FILE) or (ItemSize[Item].Size=0)) then Exit; result:=OpenFile(Item, Access); end; function TGCFFile.OpenFile(Item: integer; Access: byte): TStream; var res: TStream; begin res:=TStream.CreateStreamOnStream(@StreamMethods); res.Data.fHandle:=ulong(Item); res.Data.Package:=self; res.Data.fSize:=(res.Data.Package as TGCFFile).ItemSize[Item].Size; res.Data.fPosition:=0; if (IsNCF) then begin CommonPath:=IncludeTrailingPathDelimiter(CommonPath); case Access of ACCES_READ: begin res.Data.FileStream:=TStream.CreateReadFileStream(CommonPath+ItemPath[Item]); res.Methods.fSetSiz:=StreamOnStream_SetSizeNULL; res.Methods.fWrite:=StreamOnStream_WriteNULL; end; ACCES_WRITE: begin ForceDirectories(ExtractFilePath(CommonPath+ItemPath[Item])); res.Data.FileStream:=TStream.CreateWriteFileStream(CommonPath+ItemPath[Item]); end; ACCES_READWRITE: res.Data.FileStream:=TStream.CreateReadWriteFileStream(CommonPath+ItemPath[Item]); end; res.Data.FileStream.Seek(0, spBegin); end else GCF_BuildClustersTable(Item, @res.Data.SectorsTable); result:=res; end;
      
      





рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ - рдЖрдк рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЗрд╢рд╛рд░реЛрдВ рдХреЗ рдмрд┐рдирд╛ рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЦреЛрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдирд╕реЗ рдбреЗрдЯрд╛ рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред



рдЪреЗрдХрд╕рдо рдлрд╝рд╛рдЗрд▓ рдирд┐рд╖реНрдХрд░реНрд╖рдг


рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рдКрдкрд░ рд╡рд░реНрдгрд┐рдд рдзрд╛рд░рд╛рдПрдВ рд╕рдХреНрд░рд┐рдп рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рддреА рд╣реИрдВ - рдореИрдВ рдмрд╕ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдЖрдХрд╛рд░ рдХреЗ рдЯреБрдХрдбрд╝реЛрдВ рдореЗрдВ рдлрд╝рд╛рдЗрд▓ рдкрдврд╝рддрд╛ рд╣реВрдВ (рдЪреЗрдХрд╕рдо рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХрддрдо рдЯреБрдХрдбрд╝рд╛ рдЖрдХрд╛рд░ 32Kb рд╣реИ), рдЙрдирдХреЗ рд▓рд┐рдП рдЪреЗрдХрд╕рдо рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ рдФрд░ рд╣реЗрдбрд░ рдореЗрдВ рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рдорд╛рдиреЛрдВ рдХреЗ рд╕рд╛рде рдЙрдирдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВред



рдХрд┐рд╕реА рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЙрд╕рдХреЗ COP рдХреА рдЬрд╛рдБрдЪ рдХреЗ рд╕рд╛рде рдирд┐рдХрд╛рд▓рдирд╛
рд╕реА ++

 UINT64 CGCFFile::ExtractFile(UINT32 Item, char *Dest, bool IsValidation) { CStream *fileIn = this->OpenFile(Item, CACHE_OPEN_READ), *fileOut; if (fileIn == NULL) return 0; if (!IsValidation) { if (DirectoryExists(Dest)) Dest = MakeStr(IncludeTrailingPathDelimiter(Dest), GetItemName(Item)); fileOut = new CStream(Dest, true); if (fileOut->GetHandle() == INVALID_HANDLE_VALUE) return 0; fileOut->SetSize(GetItemSize(Item).Size); } UINT8 buf[CACHE_CHECKSUM_LENGTH]; UINT32 CheckSize = CACHE_CHECKSUM_LENGTH; UINT64 res = 0; while ((fileIn->Position()<fileIn->GetSize()) && (CheckSize == CACHE_CHECKSUM_LENGTH)) { if (Stop) break; UINT32 CheckIdx = lpFileIDChecksum[lpManifest[Item].FileId].FirstChecksumIndex + ((fileIn->Position() & 0xffffffffffff8000) >> 15); CheckSize = (UINT32)fileIn->Read(buf, CheckSize); UINT32 CheckFile = Checksum(buf, CheckSize), CheckFS = lpChecksum[CheckIdx]; if (CheckFile != CheckFS) { break; } else if (!IsValidation) { fileOut->Write(buf, CheckSize); } res += CheckSize; } delete fileIn; if (!IsValidation) delete fileOut; return res; }
      
      





рдбреЗрд▓реНрдлреА

 function TGCFFile.ExtractFile(Item: integer; Dest: string; IsValidation: boolean = false): int64; var StreamF, StreamP: TStream; CheckSize, CheckFile, CheckFS, CheckIdx: uint32_t; buf: array of byte; Size: int64; begin result:=0; StreamP:=OpenFile(Item, ACCES_READ); if (StreamP=nil) then Exit; Size:=ItemSize[Item].Size; if Assigned(OnProgress) then OnProgress(ItemPath[Item], 0, Size, Data); if Assigned(OnProgressObj) then OnProgressObj(ItemPath[Item], 0, Size, Data); StreamF:=nil; if (not IsValidation) then begin if DirectoryExists(Dest) then Dest:=IncludeTrailingPathDelimiter(Dest)+ExtractFileName(ItemName[Item]); StreamF:=TStream.CreateWriteFileStream(Dest); StreamF.Size:=ItemSize[Item].Size; if StreamF.Handle=INVALID_HANDLE_VALUE then begin StreamF.Free; Exit; end; end; SetLength(buf, HL_GCF_CHECKSUM_LENGTH); CheckSize:=HL_GCF_CHECKSUM_LENGTH; while ((StreamP.Position<StreamP.Size) and (CheckSize=HL_GCF_CHECKSUM_LENGTH)) do begin CheckIdx:=lpFileIdChecksumTableEntries[lpManifestNodes[Item].FileId].FirstChecksumIndex+ ((StreamP.Position and $ffffffffffff8000) shr 15); CheckSize:=StreamP.Read(buf[0], HL_GCF_CHECKSUM_LENGTH); CheckFile:=Checksum(@buf[0], CheckSize); CheckFS:=lpChecksumEntries[CheckIdx]; if (CheckFile<>CheckFS) and (not IgnoreCheckError) then begin if Assigned(OnError) then OnError(GetItemPath(Item), ERROR_CHECKSUM, Data); if Assigned(OnErrorObj) then OnErrorObj(GetItemPath(Item), ERROR_CHECKSUM, Data); break; end else if (not IsValidation) then StreamF.Write(buf[0], CheckSize); inc(result, CheckSize); if Assigned(OnProgress) then OnProgress('', result, Size, Data); if Assigned(OnProgressObj) then OnProgressObj('', result, Size, Data); if Stop then break; end; SetLength(buf, 0); StreamP.Free; if (not IsValidation) then StreamF.Free; end;
      
      





рдбреЗрд▓реНрдлреА рдХреЗ рд▓рд┐рдП рдХреЛрдб рдореЗрдВ рдХрд╛рдо рдХреА рдкреНрд░рдЧрддрд┐ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб рд╣реИ - рдСрдирдкреНрд░реЛрдЧреНрд░реЗрдб, рдСрдирдкреНрд░реЛрдПрдЧрдСрдирдЬреИрдХ рдХреЙрд▓рдмреИрдХ рдлрд╝рдВрдХреНрд╢рдиред



рдлрд╝рд╛рдЗрд▓ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдХрд░реЗрдВ


рдЪреВрдВрдХрд┐ рд░рд┐рд▓реАрдЬрд╝ рд╕реЗ рдХреБрдЫ рд╕рдордп рдкрд╣рд▓реЗ рд╣реА рдХрдИ рдЧреЗрдо рдбрд╛рдЙрдирд▓реЛрдб рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдРрд╕реЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЙрдирдХреА рд╕рд╛рдордЧреНрд░реА рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдпрд╛ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рдПрдиреНрдХреНрд░рд┐рдкреНрдЯ рдХреА рдЧрдИ рд╣реИред рдЦреЗрд▓ рдХреА рд░рд┐рд╣рд╛рдИ рдХреЗ рд╕рд╛рде, рдЗрд╕ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдбрд┐рдХреНрд░рд┐рдкреНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреБрдВрдЬреА рдЙрдкрд▓рдмреНрдз рд╣реЛ рдЬрд╛рддреА рд╣реИ, рдЬрд┐рд╕реЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреЗ рд╕рд╛рде рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:



рдлрд╝рд╛рдЗрд▓ рдбрд┐рдХреНрд░рд┐рдкреНрд╢рди
рд╕реА ++

 UCHAR IV[16] = {0}; void DecryptFileChunk(char *buf, UINT32 size, char *key) { AES_KEY aes_key; AES_set_decrypt_key((UCHAR*)key, 128, &aes_key); AES_cbc_encrypt((UCHAR*)buf, (UCHAR*)buf, size, &aes_key, IV, false); } UINT64 CGCFFile::DecryptFile(UINT32 Item, char *key) { UINT64 res = 0; CStream *str = OpenFile(Item, CACHE_OPEN_READWRITE); if (str == NULL) return 0; char buf[CACHE_CHECKSUM_LENGTH], dec[CACHE_CHECKSUM_LENGTH]; UINT32 CheckSize = CACHE_CHECKSUM_LENGTH; INT32 CompSize, UncompSize, sz; while ((str->Position() < str->GetSize()) && (CheckSize == CACHE_CHECKSUM_LENGTH)) { UINT32 CheckIdx = lpFileIDChecksum[lpManifest[Item].FileId].FirstChecksumIndex + ((str->Position() & 0xffffffffffff8000) >> 15); INT32 CheckSize = (INT32)str->Read(buf, 8); memcpy(&CompSize, &buf[0], 4); memcpy(&UncompSize, &buf[4], 4); if (((UINT32)UncompSize > pManifestHeader->CompressionBlockSize) || (CompSize > UncompSize) || (UncompSize < -1) || (CompSize < -1)) { // Chunk is not compressed CheckSize = (UINT32)str->Read(&buf[8], CACHE_CHECKSUM_LENGTH-8); DecryptFileChunk(&buf[0], CheckSize, key); } else if (((UINT32)UncompSize <= pManifestHeader->CompressionBlockSize) && (CompSize <= UncompSize) && (UncompSize > -1) || (CompSize > -1)) { // Chunk is compressed CheckSize = (UINT32)str->Read(&buf[8], UncompSize-8); INT32 CheckFile = UncompSize; if (CompSize%16 == 0) sz = CompSize; else sz = CompSize + 16 - (CompSize%16); memcpy(dec, buf, sz); DecryptFileChunk(&dec[0], sz, key); uncompress((Bytef*)&buf[0], (uLongf*)&CheckFile, (Bytef*)&dec[0], sz); } str->Seek(-CheckSize, USE_SEEK_CURRENT); str->Write(&buf[0], CheckSize); UINT32 Check1 = Checksum((UINT8*)&buf[0], CheckSize), Check2 = lpChecksum[CheckIdx]; if (Check1 != Check2) break; res += CheckSize; } lpManifest[Item].Attributes = lpManifest[Item].Attributes & (!CACHE_FLAG_ENCRYPTED); return res; }
      
      





рдбреЗрд▓реНрдлреА

 const IV: array[0..15] of byte = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0); procedure DecryptFileChunk(buf: pByte; ChunkSize: integer; Key: Pointer); var AES: TCipher_Rijndael; src: array[0..HL_GCF_CHECKSUM_LENGTH-1] of byte; begin Move(buf^, src[0], HL_GCF_CHECKSUM_LENGTH); AES:=TCipher_Rijndael.Create(); AES.Init(Key^, 16, IV[0], 16); AES.Mode:=cmCFBx; AES.Decode(src[0], buf^, ChunkSize); AES.Free; end; function TGCFFile.DecryptFile(Item: integer; Key: Pointer): int64; var StreamP: TStream; CheckSize, CheckFile, CheckFS, CheckIdx, sz: uint32_t; buf: array of byte; dec: array[0..HL_GCF_CHECKSUM_LENGTH] of byte; CompSize, UncompSize: integer; Size: int64; begin result:=0; StreamP:=OpenFile(Item, ACCES_READWRITE); if (StreamP=nil) then Exit; Size:=ItemSize[Item].Size; if Assigned(OnProgress) then OnProgress(ItemName[Item], 0, Size, Data); if Assigned(OnProgressObj) then OnProgressObj(ItemName[Item], 0, Size, Data); SetLength(buf, HL_GCF_CHECKSUM_LENGTH); CheckSize:=HL_GCF_CHECKSUM_LENGTH; while ((StreamP.Position<StreamP.Size) and (CheckSize=HL_GCF_CHECKSUM_LENGTH)) do begin CheckIdx:=lpFileIdChecksumTableEntries[lpManifestNodes[Item].FileId].FirstChecksumIndex+ ((StreamP.Position and $ffffffffffff8000) shr 15); CheckSize:=StreamP.Read(buf[0], 8); Move(buf[0], CompSize, 4); Move(buf[4], UncompSize, 4); if (ulong(UncompSize)>fManifestHeader.CompressionBlockSize) or (CompSize>UncompSize) or (UncompSize<-1) or (CompSize<-1) then begin //Chunk is not compressed! CheckSize:=StreamP.Read(buf[8], HL_GCF_CHECKSUM_LENGTH-8); DecryptFileChunk(@buf[0], CheckSize, Key); end else if ((ulong(UncompSize)<=fManifestHeader.CompressionBlockSize) and (CompSize<=UncompSize)) and ((UncompSize>-1) and (CompSize>-1)) then begin CheckSize:=StreamP.Read(buf[8], UncompSize-8); CheckFile:=UncompSize; //Chunk is compressed! if (CompSize mod 16=0) then sz:=CompSize else sz:=CompSize+16-(CompSize mod 16); Move(buf[8], dec[0], sz); DecryptFileChunk(@dec[0], sz, Key); uncompress(@buf[0], CheckFile, @dec[0], sz); end; StreamP.Seek(-CheckSize, spCurrent); StreamP.Write(buf[0], CheckSize); CheckFile:=Checksum(@buf[0], CheckSize); CheckFS:=lpChecksumEntries[CheckIdx]; if (CheckFile<>CheckFS) and (not IgnoreCheckError) then begin if Assigned(OnError) then OnError(GetItemPath(Item), ERROR_CHECKSUM, Data); if Assigned(OnErrorObj) then OnErrorObj(GetItemPath(Item), ERROR_CHECKSUM, Data); break; end; inc(result, CheckSize); //StreamP.Position:=StreamP.Position+CheckSize; if Assigned(OnProgress) then OnProgress('', result, Size, Data); if Assigned(OnProgressObj) then OnProgressObj('', result, Size, Data); if Stop then break; end; lpManifestNodes[Item].Attributes:=lpManifestNodes[Item].Attributes and (not HL_GCF_FLAG_ENCRYPTED); fIsChangeHeader[HEADER_MANIFEST_NODES]:=true; SaveChanges(); SetLength(buf, 0); end;
      
      







рдореИрдирд┐рдлреЗрд╕реНрдЯреАрдбрд░ рдХреЗ рд▓рд┐рдП рдЪреЗрдХрд╕рдо рдЧрдгрдирд╛


рдЗрд╕ рдорд╛рди рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдореНрди рд╢реАрд░реНрд╖ рд▓реЗрдЦ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:



CS рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝реАрд▓реНрдб рд░реАрд╕реЗрдЯ рдХрд░ рджрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ:



рдЧрдгрдирд╛ рд╕реНрд╡рдпрдВ рд╕рднреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕рдВрд░рдЪрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдбрд▓рд░ 32 рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рд╣реИрд╢ рдХреА рдЕрдиреБрдХреНрд░рдорд┐рдХ рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рдЙрдмрд╛рд▓рддреА рд╣реИ :



рдбреЗрд▓реНрдлреА

 function ManifestChecksum(Header: pCache_ManifestHeader; entries, names, hashs, table, MFP, UCF: pByte): uint32_t; var tmp1, tmp2: uint32; begin tmp1:=Header.Fingerprint; tmp2:=Header.Checksum; Header.Fingerprint:=0; Header.Checksum:=0; result:=adler32(0, pAnsiChar(Header), sizeof(TCache_ManifestHeader)); result:=adler32(result, pAnsiChar(entries), sizeof(TCache_ManifestNode)*Header^.NodeCount); result:=adler32(result, pAnsiChar(names), Header^.NameSize); result:=adler32(result, pAnsiChar(hashs), sizeof(uint32)*Header^.HashTableKeyCount); result:=adler32(result, pAnsiChar(table), sizeof(uint32)*Header^.NodeCount); if Header^.NumOfMinimumFootprintFiles>0 then result:=adler32(result, pAnsiChar(MFP), sizeof(uint32)*Header^.NumOfMinimumFootprintFiles); if Header^.NumOfUserConfigFiles>0 then result:=adler32(result, pAnsiChar(UCF), sizeof(uint32)*Header^.NumOfUserConfigFiles); Header.Fingerprint:=tmp1; Header.Checksum:=tmp2; end;
      
      







рдирд┐рд╖реНрдХрд░реНрд╖



рдЙрдирдХреЗ рд╡рд┐рд╡рд░рдг рдХреА рдмреЛрдЭрд┐рд▓рддрд╛ рдХреЗ рдХрд╛рд░рдг рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдЕрдиреНрдп рдХрд╛рд░реНрдпреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ (рд╕реЗрдХреНрдЯрд░ рдореИрдк рдмрджрд▓рддреЗ рд╕рдордп рд╡реНрдпрд╕реНрдд рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЗ рдмрд┐рдЯрдореИрдкреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛, рдЗрд╕ рдирдХреНрд╢реЗ рдХрд╛ рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛, рдФрд░ рдмрд╣реБрдд рдХреБрдЫ, рдмрд╣реБрдд) рдХреЛ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ (рдмрд╛рдХреА рдХрд╛рд░реНрдпрдХреНрд░рдореЛрдВ рдХреА рдЪрд░реНрдЪрд╛ рдЬреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореЗрдВ рдЪрд░реНрдЪрд╛ рдХреА рдЬрд╛рдПрдЧреА рд▓реЗрдЦ)ред рдпреЗ рд╕реНрд░реЛрдд рдХреЛрдб рдЖрдкрдХреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ (рдпрджрд┐ рдХрд┐рд╕реА рдХреЛ рдРрд╕реА рджреБрд░реНрд▓рднрддрд╛рдУрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ...)ред

рд╕рднреА рд╕реНрд░реЛрдд рдХреЛрдб рдХреЗ рдЕрдВрддрд┐рдо рдЕрджреНрдпрддрди рдХреА рдЕрдиреБрдорд╛рдирд┐рдд рддрд┐рдерд┐ 2011 рдХреА рджреВрд╕рд░реА рдЫрдорд╛рд╣реА рд╣реИред



рдкреБрдирд╢реНрдЪ: рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЛ рд▓рд┐рдЦрдиреЗ рд╕реЗ рдореБрдЭреЗ рдмрд╣реБрдд рдорджрдж рдорд┐рд▓реА рдЬрдм рд╡рд┐рд╖рдп рдСрдкрд░реЗрдЯрд┐рдВрдЧ рд╕рд┐рд╕реНрдЯрдо рдкрд░ рдПрдХ рд▓реИрдм рд▓рд┐рдЦ рд░рд╣рд╛ рдерд╛рд╡рд┐рд╢реНрд╡рд╡рд┐рджреНрдпрд╛рд▓рдп рдореЗрдВ - рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо (рдлрд╛рдЗрд▓ рдмрдирд╛рдирд╛, рд▓рд┐рдЦрдирд╛, рдкрдврд╝рдирд╛ рдФрд░ рд╣рдЯрд╛рдирд╛) рдХреЗ рдХрд╛рдо рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдерд╛ред рдореЗрд░рд╛ рдХрд╛рдо рдкрд╣рд▓реЗ рдФрд░ рд╢рд╛рдпрдж, рд╕рднреА рд╕рдордп рдХреЗ рд▓рд┐рдП рдПрдХрдорд╛рддреНрд░ рдерд╛, рдЬрд┐рд╕рдореЗрдВ рдмреНрд▓реЙрдХ рдФрд░ рд╕реЗрдХреНрдЯрд░реЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрди рдХреЗ рд╕рд╛рде рдлрд╛рдЗрд▓ рд╕рд┐рд╕реНрдЯрдо рдХреА рдЫрд╡рд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ - рдФрд░ рдпрд╣ рдмрд╕ рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХрд╛ рдПрдХ рдЫреЛрдЯрд╛ рд╕рдВрд╕реНрдХрд░рдг рдерд╛ (рдмрд┐рдирд╛ рдЪреЗрдХрд╕рдо рдХреЗ)ред рдореИрдВрдиреЗ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рднрд╛рдЧ рдХреЗ рд░реВрдк рдореЗрдВ рдХреИрд╢ рдХреЗ рд▓рд┐рдП рдПрдХ рдбреАрдлрд╝реНрд░реЗрдЧреНрдореЗрдВрдЯрд░ рднреА рдЬреЛрдбрд╝рд╛ ...



All Articles