Add iTunes Debugger and third-party libraries

- Introduced a new iTunes Debugger application with main functionality to interact with iTunesAPIs.
- Added various third-party libraries including 7zip, bit7z, jsoncpp, libcurl, libeay32, ssleay32, and zlib for enhanced functionality.
- Created project files for the iTunes Debugger in Visual Studio, including .vcxproj, .vcxproj.filters, and .sln files.
- Included a log file for debugging purposes.
- Ensured compatibility with both Debug and Release configurations for Win32 and x64 platforms.
This commit is contained in:
danial
2025-11-15 23:06:05 +08:00
commit 9f481c5e8c
339 changed files with 82952 additions and 0 deletions

438
.gitignore vendored Normal file
View File

@@ -0,0 +1,438 @@
# Visual Studio / MSBuild user-specific files
*.user
*.userosscache
*.sln.docstates
*.suo
*.userfiles
*.sln.docstates
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these files may be leaked
*.azurePubxml
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csx
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
CDF_UpgradeLog*.xml
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio Code
.history/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
# Specific to this project
# iTunes specific files and sensitive data
*.key
*.p12
*.pem
*.crt
# Authentication credentials and sensitive data
config/
secrets/
credentials.json
# Log files
*.log
logs/
# Temporary files
*.tmp
*.temp
# IDE temp files
.DS_Store
Thumbs.db
# macOS specific files
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# macOS XCode build files
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
*.xccheckout
*.moved-aside
DerivedData/
*.hmap
*.ipa
*.xcuserstate
project.xcworkspace
# macOS app package files
*.dSYM/
*.dwarf
# Test outputs
test-results/
coverage/
# Resource files that might contain sensitive data
src/resourceFiles/*.key
src/resourceFiles/*.p12

119
CLAUDE.md Normal file
View File

@@ -0,0 +1,119 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
This is a C++ Windows DLL project that provides iTunes gift card redemption functionality through the iTunes Store API. The project creates a dynamic library (`iTunesAPIs.dll`) that wraps iTunes client functionality for automated gift card redemption.
## Build System
### Build Commands
This project uses Visual Studio 2022 (v143 toolset) with MSBuild:
```bash
# Build the entire solution (both DLL and debugger)
msbuild "iTunes礼品卡兑换_DLL封装.sln" /p:Configuration=Release /p:Platform=Win32
# Build only the DLL
msbuild "iTunesAPIs\iTunesAPIs.vcxproj" /p:Configuration=Release /p:Platform=Win32
# Build with debug information
msbuild "iTunesAPIs\iTunesAPIs.vcxproj" /p:Configuration=Debug /p:Platform=Win32
```
### Build Configurations
- **Release|Win32**: Primary configuration for production builds
- **Debug|Win32**: Development builds with debug symbols
- **Output Directory**: `bin\$(Configuration)\$(Platform)\`
- **Target Name**: `iTunesAPIs.dll`
### Dependencies
The project links against several third-party libraries located in `third_party\`:
- **libcurl**: HTTP client functionality
- **OpenSSL**: Cryptographic operations
- **Google Logging (glog)**: Logging framework
- **7zip**: Archive extraction for iTunes DLL resources
- **Custom cookie parsing library**
## Architecture
### Core Components
1. **iTunesAPIs Namespace**: DLL entry points for initialization
- `init_dll()`: Extracts and sets up iTunes DLL dependencies
- `init_environment()`: Configures proxy settings
2. **iTunesFunctions Namespace**: Main API functions
- Authentication: `iTunes_login()`, `iTunes_logout()`, `iTunes_login_status()`
- Gift Card Operations: `iTunes_redeem()`
- Account Management: `iTunes_summary()`
- Utilities: `iTunes_free()`, `iTunes_get_heartbeat_list()`
3. **iTunesCore Module** (`src/iTunesCore/`): Low-level iTunes integration
- `itunes_module.{cc,h}`: Manages iTunes DLL paths and environment
- `itunes_client_interface.cc`: iTunes client communication
- `itunes_https.cc`: HTTPS communication layer
- `itunes_cookie_interface.cc`: Cookie management
- Windows integration: `windows_hardware.cc`, `windows_version.cc`
4. **Authentication Module** (`src/authenticate/`):
- License/authentication system using access keys
- Supports Agent and User authentication types
5. **Utilities** (`src/utils/`):
- HTTP request wrapper with cookie/header management
- String manipulation and encoding utilities
- JSON parsing with jsoncpp
- Hardware fingerprinting
### Key Design Patterns
- **Singleton Pattern**: Authentication system uses `Instance()` method
- **Resource Management**: iTunes DLLs are embedded as resources and extracted at runtime
- **Environment Setup**: Dynamic PATH modification to load iTunes dependencies
- **Thread Safety**: Keep-alive thread for maintaining session state
## Important Implementation Details
### DLL Resource Management
The project embeds iTunes DLL files as resources and extracts them on first run:
- Resources defined in `src\Resource.rc`
- Extraction handled in `src\writeResourceFile.cpp`
- Uses 7zip library for decompression
### Memory Management
- All string output from DLL functions must be freed using `iTunes_free()`
- Uses C-style allocation for cross-language compatibility
### Proxy Support
The API supports HTTP/SOCKS proxies through:
- `init_environment()` function for global proxy setup
- Per-function proxy parameters for individual requests
### Error Handling
Functions return integer codes and output JSON-formatted error messages via `char**` parameters.
## Development Notes
### Testing
The `iTunes接口调试器` (iTunes Interface Debugger) project provides a test harness for the DLL functionality.
### Platform Requirements
- Windows 10 or later (Windows Target Platform Version 10.0)
- Visual Studio 2022 (Toolset v143)
- C++17 standard compliance
- Win32 architecture (primary target)
### Security Considerations
This codebase handles sensitive authentication credentials and gift card codes. The authentication module appears to implement a licensing system to control access to the DLL functionality.

BIN
iTunesAPIs/Resource.aps Normal file

Binary file not shown.

13
iTunesAPIs/Source.def Normal file
View File

@@ -0,0 +1,13 @@
LIBRARY
EXPORTS
init_dll
init_environment
iTunes_login
iTunes_logout
iTunes_redeem
iTunes_summary
iTunes_login_status
iTunes_get_heartbeat_list
iTunes_free

View File

@@ -0,0 +1,298 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{96ef8e8b-98b6-4354-afa5-fee12ae3eaa7}</ProjectGuid>
<RootNamespace>iTunesAPIs</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)</OutDir>
<TargetName>iTunesAPIs</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)bin\$(Configuration)\$(Platform)</OutDir>
<TargetName>iTunesAPIs</TargetName>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;ITUNESAPIS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>third_party\include;src</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalLibraryDirectories>third_party\libd</AdditionalLibraryDirectories>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;ITUNESAPIS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>third_party\include;src</AdditionalIncludeDirectories>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalLibraryDirectories>third_party\lib</AdditionalLibraryDirectories>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;ITUNESAPIS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;ITUNESAPIS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<ModuleDefinitionFile>Source.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="src\authenticate\authenticate.h" />
<ClInclude Include="src\authenticate\confidentialData.h" />
<ClInclude Include="src\framework.h" />
<ClInclude Include="src\iTunesAPIs.h" />
<ClInclude Include="src\iTunesCore\itunes_client_interface.h" />
<ClInclude Include="src\iTunesCore\itunes_cookie_interface.h" />
<ClInclude Include="src\iTunesCore\itunes_download_info.h" />
<ClInclude Include="src\iTunesCore\itunes_https.h" />
<ClInclude Include="src\iTunesCore\itunes_https_configure.h" />
<ClInclude Include="src\iTunesCore\itunes_internal_interface.h" />
<ClInclude Include="src\iTunesCore\itunes_module.h" />
<ClInclude Include="src\iTunesCore\itunes_module_state.h" />
<ClInclude Include="src\iTunesCore\itunes_native_interface.h" />
<ClInclude Include="src\iTunesCore\strings.h" />
<ClInclude Include="src\iTunesCore\windows_hardware.h" />
<ClInclude Include="src\iTunesCore\windows_version.h" />
<ClInclude Include="src\resource.h" />
<ClInclude Include="src\resource2.h" />
<ClInclude Include="src\utils\encoding.h" />
<ClInclude Include="src\utils\hash.h" />
<ClInclude Include="src\utils\machine_feature.h" />
<ClInclude Include="src\utils\string_ex.h" />
<ClInclude Include="third_party\include\cookies\cookie_constants.h" />
<ClInclude Include="third_party\include\cookies\cookie_options.h" />
<ClInclude Include="third_party\include\cookies\parsed_cookie.h" />
<ClInclude Include="third_party\include\glog\basictypes.h" />
<ClInclude Include="third_party\include\glog\logging.h" />
<ClInclude Include="third_party\include\glog\scoped_ptr.h" />
<ClInclude Include="third_party\include\openssl\aes.h" />
<ClInclude Include="third_party\include\openssl\asn1.h" />
<ClInclude Include="third_party\include\openssl\asn1t.h" />
<ClInclude Include="third_party\include\openssl\asn1_mac.h" />
<ClInclude Include="third_party\include\openssl\bio.h" />
<ClInclude Include="third_party\include\openssl\blowfish.h" />
<ClInclude Include="third_party\include\openssl\bn.h" />
<ClInclude Include="third_party\include\openssl\buffer.h" />
<ClInclude Include="third_party\include\openssl\camellia.h" />
<ClInclude Include="third_party\include\openssl\cast.h" />
<ClInclude Include="third_party\include\openssl\cmac.h" />
<ClInclude Include="third_party\include\openssl\cms.h" />
<ClInclude Include="third_party\include\openssl\comp.h" />
<ClInclude Include="third_party\include\openssl\conf.h" />
<ClInclude Include="third_party\include\openssl\conf_api.h" />
<ClInclude Include="third_party\include\openssl\crypto.h" />
<ClInclude Include="third_party\include\openssl\des.h" />
<ClInclude Include="third_party\include\openssl\des_old.h" />
<ClInclude Include="third_party\include\openssl\dh.h" />
<ClInclude Include="third_party\include\openssl\dsa.h" />
<ClInclude Include="third_party\include\openssl\dso.h" />
<ClInclude Include="third_party\include\openssl\dtls1.h" />
<ClInclude Include="third_party\include\openssl\ebcdic.h" />
<ClInclude Include="third_party\include\openssl\ec.h" />
<ClInclude Include="third_party\include\openssl\ecdh.h" />
<ClInclude Include="third_party\include\openssl\ecdsa.h" />
<ClInclude Include="third_party\include\openssl\engine.h" />
<ClInclude Include="third_party\include\openssl\err.h" />
<ClInclude Include="third_party\include\openssl\evp.h" />
<ClInclude Include="third_party\include\openssl\e_os2.h" />
<ClInclude Include="third_party\include\openssl\hmac.h" />
<ClInclude Include="third_party\include\openssl\idea.h" />
<ClInclude Include="third_party\include\openssl\krb5_asn.h" />
<ClInclude Include="third_party\include\openssl\kssl.h" />
<ClInclude Include="third_party\include\openssl\lhash.h" />
<ClInclude Include="third_party\include\openssl\md4.h" />
<ClInclude Include="third_party\include\openssl\md5.h" />
<ClInclude Include="third_party\include\openssl\mdc2.h" />
<ClInclude Include="third_party\include\openssl\modes.h" />
<ClInclude Include="third_party\include\openssl\objects.h" />
<ClInclude Include="third_party\include\openssl\obj_mac.h" />
<ClInclude Include="third_party\include\openssl\ocsp.h" />
<ClInclude Include="third_party\include\openssl\opensslconf.h" />
<ClInclude Include="third_party\include\openssl\opensslv.h" />
<ClInclude Include="third_party\include\openssl\ossl_typ.h" />
<ClInclude Include="third_party\include\openssl\pem.h" />
<ClInclude Include="third_party\include\openssl\pem2.h" />
<ClInclude Include="third_party\include\openssl\pkcs12.h" />
<ClInclude Include="third_party\include\openssl\pkcs7.h" />
<ClInclude Include="third_party\include\openssl\pqueue.h" />
<ClInclude Include="third_party\include\openssl\rand.h" />
<ClInclude Include="third_party\include\openssl\rc2.h" />
<ClInclude Include="third_party\include\openssl\rc4.h" />
<ClInclude Include="third_party\include\openssl\ripemd.h" />
<ClInclude Include="third_party\include\openssl\rsa.h" />
<ClInclude Include="third_party\include\openssl\safestack.h" />
<ClInclude Include="third_party\include\openssl\seed.h" />
<ClInclude Include="third_party\include\openssl\sha.h" />
<ClInclude Include="third_party\include\openssl\srp.h" />
<ClInclude Include="third_party\include\openssl\srtp.h" />
<ClInclude Include="third_party\include\openssl\ssl.h" />
<ClInclude Include="third_party\include\openssl\ssl2.h" />
<ClInclude Include="third_party\include\openssl\ssl23.h" />
<ClInclude Include="third_party\include\openssl\ssl3.h" />
<ClInclude Include="third_party\include\openssl\stack.h" />
<ClInclude Include="third_party\include\openssl\symhacks.h" />
<ClInclude Include="third_party\include\openssl\tls1.h" />
<ClInclude Include="third_party\include\openssl\ts.h" />
<ClInclude Include="third_party\include\openssl\txt_db.h" />
<ClInclude Include="third_party\include\openssl\ui.h" />
<ClInclude Include="third_party\include\openssl\ui_compat.h" />
<ClInclude Include="third_party\include\openssl\whrlpool.h" />
<ClInclude Include="third_party\include\openssl\x509.h" />
<ClInclude Include="third_party\include\openssl\x509v3.h" />
<ClInclude Include="third_party\include\openssl\x509_vfy.h" />
<ClInclude Include="src\utils\httpRequest.h" />
<ClInclude Include="src\utils\jsoncpp_ex.h" />
<ClInclude Include="src\utils\writeResourceFile.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\authenticate\authenticate.cpp" />
<ClCompile Include="src\authenticate\confidentialData.cpp" />
<ClCompile Include="src\dllmain.cpp" />
<ClCompile Include="src\iTunesAPIs.cpp" />
<ClCompile Include="src\iTunesCore\itunes_client_interface.cc" />
<ClCompile Include="src\iTunesCore\itunes_cookie_interface.cc" />
<ClCompile Include="src\iTunesCore\itunes_download_info.cc" />
<ClCompile Include="src\iTunesCore\itunes_https.cc" />
<ClCompile Include="src\iTunesCore\itunes_https_configure.cc" />
<ClCompile Include="src\iTunesCore\itunes_module.cc" />
<ClCompile Include="src\iTunesCore\itunes_module_state.cc" />
<ClCompile Include="src\iTunesCore\itunes_native_interface.cc" />
<ClCompile Include="src\iTunesCore\strings.cc" />
<ClCompile Include="src\iTunesCore\windows_hardware.cc" />
<ClCompile Include="src\iTunesCore\windows_version.cc" />
<ClCompile Include="src\LinkStaticLib.cpp" />
<ClCompile Include="src\utils\encoding.cpp" />
<ClCompile Include="src\utils\hash.cpp" />
<ClCompile Include="src\utils\machine_feature.cpp" />
<ClCompile Include="src\utils\string_ex.cpp" />
<ClCompile Include="third_party\include\cookies\cookie_constants.cc" />
<ClCompile Include="third_party\include\cookies\parsed_cookie.cc" />
<ClCompile Include="third_party\include\glog\logging.cc" />
<ClCompile Include="src\utils\httpRequest.cpp" />
<ClCompile Include="src\utils\jsoncpp_ex.cpp" />
<ClCompile Include="src\utils\writeResourceFile.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="Source.def" />
<None Include="src\resourceFiles\7z.dll" />
<None Include="src\resourceFiles\iTunesDlls.7z" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="src\Resource.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,475 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="源文件\iTunesCore">
<UniqueIdentifier>{4db2b9a3-9564-4ecf-b686-fb0756eb90f7}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\iTunesCore">
<UniqueIdentifier>{f8bbb62f-8f17-4f40-9829-6e2cb8c975f9}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\third_party">
<UniqueIdentifier>{d606a438-3800-422d-ba8b-5536c11489cc}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\third_party\cookies">
<UniqueIdentifier>{5fa467bf-7c3e-44c5-8aff-b2f8c7dcee3b}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\third_party\glog">
<UniqueIdentifier>{54248e05-92fa-433c-813e-5dd61df0e5c2}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\third_party\openssl">
<UniqueIdentifier>{b1fff60a-bc18-4aff-bade-09721f9d5783}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\third_party">
<UniqueIdentifier>{e72a10ff-fe37-4c23-ba97-a3b8dd55a4c9}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\third_party\cookies">
<UniqueIdentifier>{c03e20ed-28fa-4d2b-b726-2427a252d51b}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\third_party\glog">
<UniqueIdentifier>{68e7d5a7-735c-42bf-aacf-09c619dd4ca8}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\third_party\openssl">
<UniqueIdentifier>{369b54ed-715e-488e-ae34-1de53cbc05d4}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\utils">
<UniqueIdentifier>{f50292f9-f406-4bd9-9f4d-ad2bc48e022b}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\utils">
<UniqueIdentifier>{57120fe3-ba97-4ea0-ab79-a9066a3f2a74}</UniqueIdentifier>
</Filter>
<Filter Include="源文件\authenticate">
<UniqueIdentifier>{f0fc2901-6bd2-42fc-a186-20fda967e276}</UniqueIdentifier>
</Filter>
<Filter Include="头文件\authenticate">
<UniqueIdentifier>{275bb35f-eeab-4aa1-87d9-c3c23580f7da}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\framework.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\iTunesAPIs.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\resource.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\itunes_client_interface.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\itunes_cookie_interface.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\itunes_download_info.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\itunes_https.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\itunes_https_configure.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\itunes_internal_interface.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\itunes_module.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\itunes_module_state.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\itunes_native_interface.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\strings.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\windows_hardware.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="src\iTunesCore\windows_version.h">
<Filter>头文件\iTunesCore</Filter>
</ClInclude>
<ClInclude Include="third_party\include\cookies\cookie_constants.h">
<Filter>头文件\third_party\cookies</Filter>
</ClInclude>
<ClInclude Include="third_party\include\cookies\cookie_options.h">
<Filter>头文件\third_party\cookies</Filter>
</ClInclude>
<ClInclude Include="third_party\include\cookies\parsed_cookie.h">
<Filter>头文件\third_party\cookies</Filter>
</ClInclude>
<ClInclude Include="third_party\include\glog\basictypes.h">
<Filter>头文件\third_party\glog</Filter>
</ClInclude>
<ClInclude Include="third_party\include\glog\logging.h">
<Filter>头文件\third_party\glog</Filter>
</ClInclude>
<ClInclude Include="third_party\include\glog\scoped_ptr.h">
<Filter>头文件\third_party\glog</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\aes.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\asn1.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\asn1_mac.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\asn1t.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\bio.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\blowfish.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\bn.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\buffer.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\camellia.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\cast.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\cmac.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\cms.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\comp.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\conf.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\conf_api.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\crypto.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\des.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\des_old.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\dh.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\dsa.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\dso.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\dtls1.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\e_os2.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ebcdic.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ec.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ecdh.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ecdsa.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\engine.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\err.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\evp.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\hmac.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\idea.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\krb5_asn.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\kssl.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\lhash.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\md4.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\md5.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\mdc2.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\modes.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\obj_mac.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\objects.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ocsp.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\opensslconf.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\opensslv.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ossl_typ.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\pem.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\pem2.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\pkcs7.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\pkcs12.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\pqueue.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\rand.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\rc2.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\rc4.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ripemd.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\rsa.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\safestack.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\seed.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\sha.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\srp.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\srtp.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ssl.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ssl2.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ssl3.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ssl23.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\stack.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\symhacks.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\tls1.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ts.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\txt_db.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ui.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\ui_compat.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\whrlpool.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\x509.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\x509_vfy.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="third_party\include\openssl\x509v3.h">
<Filter>头文件\third_party\openssl</Filter>
</ClInclude>
<ClInclude Include="src\utils\httpRequest.h">
<Filter>头文件\utils</Filter>
</ClInclude>
<ClInclude Include="src\authenticate\confidentialData.h">
<Filter>头文件\authenticate</Filter>
</ClInclude>
<ClInclude Include="src\utils\writeResourceFile.h">
<Filter>头文件\utils</Filter>
</ClInclude>
<ClInclude Include="src\authenticate\authenticate.h">
<Filter>头文件\authenticate</Filter>
</ClInclude>
<ClInclude Include="src\utils\jsoncpp_ex.h">
<Filter>头文件\utils</Filter>
</ClInclude>
<ClInclude Include="src\utils\encoding.h">
<Filter>头文件\utils</Filter>
</ClInclude>
<ClInclude Include="src\utils\machine_feature.h">
<Filter>头文件\utils</Filter>
</ClInclude>
<ClInclude Include="src\utils\string_ex.h">
<Filter>头文件\utils</Filter>
</ClInclude>
<ClInclude Include="src\utils\hash.h">
<Filter>头文件\utils</Filter>
</ClInclude>
<ClInclude Include="src\resource2.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\dllmain.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\iTunesAPIs.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="src\LinkStaticLib.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="third_party\include\cookies\cookie_constants.cc">
<Filter>源文件\third_party\cookies</Filter>
</ClCompile>
<ClCompile Include="third_party\include\cookies\parsed_cookie.cc">
<Filter>源文件\third_party\cookies</Filter>
</ClCompile>
<ClCompile Include="third_party\include\glog\logging.cc">
<Filter>源文件\third_party\glog</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\itunes_client_interface.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\itunes_cookie_interface.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\itunes_download_info.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\itunes_https.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\itunes_https_configure.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\itunes_module.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\itunes_module_state.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\itunes_native_interface.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\strings.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\windows_hardware.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\iTunesCore\windows_version.cc">
<Filter>源文件\iTunesCore</Filter>
</ClCompile>
<ClCompile Include="src\utils\httpRequest.cpp">
<Filter>源文件\utils</Filter>
</ClCompile>
<ClCompile Include="src\authenticate\confidentialData.cpp">
<Filter>源文件\authenticate</Filter>
</ClCompile>
<ClCompile Include="src\utils\writeResourceFile.cpp">
<Filter>源文件\utils</Filter>
</ClCompile>
<ClCompile Include="src\authenticate\authenticate.cpp">
<Filter>源文件\authenticate</Filter>
</ClCompile>
<ClCompile Include="src\utils\jsoncpp_ex.cpp">
<Filter>源文件\utils</Filter>
</ClCompile>
<ClCompile Include="src\utils\encoding.cpp">
<Filter>源文件\utils</Filter>
</ClCompile>
<ClCompile Include="src\utils\machine_feature.cpp">
<Filter>源文件\utils</Filter>
</ClCompile>
<ClCompile Include="src\utils\string_ex.cpp">
<Filter>源文件\utils</Filter>
</ClCompile>
<ClCompile Include="src\utils\hash.cpp">
<Filter>源文件\utils</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="Source.def">
<Filter>源文件</Filter>
</None>
<None Include="src\resourceFiles\7z.dll">
<Filter>资源文件</Filter>
</None>
<None Include="src\resourceFiles\iTunesDlls.7z">
<Filter>资源文件</Filter>
</None>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="src\Resource.rc">
<Filter>资源文件</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,17 @@
#if _DEBUG
#pragma comment(lib, "7zip.lib") // 7zip<69><70><EFBFBD><EFBFBD>bit7z<37>ıر<C4B1><D8B1><EFBFBD>
#pragma comment(lib, "bit7z_d.lib") // bit7z<37><7A>7zip<69><70>C++<2B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>ǻ<EFBFBD><C7BB><EFBFBD>7zip<69><70>
#pragma comment(lib, "libcurl-d.lib") // curl<72><6C><EFBFBD>ڽ<EFBFBD><DABD>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#pragma comment(lib, "libeay32.lib") // openssl<73>ľ<EFBFBD>̬<EFBFBD><EFBFBD><E2A3AC><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD>
#pragma comment(lib, "ssleay32.lib") // openssl<73>ľ<EFBFBD>̬<EFBFBD><EFBFBD><E2A3AC><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD>
#pragma comment(lib, "zlibd.lib") // curl<72><6C><EFBFBD><EFBFBD>zlib
#pragma comment(lib, "jsoncpp.lib") // jsoncpp
#else
#pragma comment(lib, "7zip.lib")
#pragma comment(lib, "bit7z.lib")
#pragma comment(lib, "libcurl.lib")
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")
#pragma comment(lib, "zlib.lib")
#pragma comment(lib, "jsoncpp.lib")
#endif

BIN
iTunesAPIs/src/Resource.aps Normal file

Binary file not shown.

BIN
iTunesAPIs/src/Resource.rc Normal file

Binary file not shown.

View File

@@ -0,0 +1,24 @@
#include <windows.h>
#include "authenticate.h"
#include "utils/httpRequest.h"
#include "json/json.h"
#include "utils/jsoncpp_ex.h"
using namespace ytpp::json;
#include "glog/logging.h"
Authenticate* Authenticate::Instance()
{
static Authenticate* info;
if (!info) {
Authenticate* new_info = new Authenticate;
if (InterlockedCompareExchangePointer(reinterpret_cast<PVOID*>(&info), new_info, NULL)) {
delete new_info;
}
}
return info;
}
bool Authenticate::AuthKey(AuthType authType, std::string accessKey, std::string secretKey) {
return true;
}

View File

@@ -0,0 +1,21 @@
#pragma once
#include <string>
class Authenticate {
private:
const static std::string host;
public:
enum AuthType {
None = 100,
Agent = 101,
User = 102,
};
static Authenticate* Instance();
bool AuthKey(AuthType authType, std::string accessKey, std::string secretKey);
};

View File

@@ -0,0 +1,2 @@
#include "confidentialData.h"

View File

@@ -0,0 +1,42 @@
#pragma once
#include <windows.h>
class ConfidentialData
{
public:
static ConfidentialData* Instance() {
static ConfidentialData* info;
if (!info) {
ConfidentialData* new_info = new ConfidentialData;
if (InterlockedCompareExchangePointer(reinterpret_cast<PVOID*>(&info), new_info, NULL)) {
delete new_info;
}
}
return info;
}
unsigned long Kbsync = 0xA5B88;
unsigned long KbsyncID = 0xE48FB;
unsigned long CigHash = 0xA15B8;
unsigned long WriteSIDD = 0xA1FCB;
unsigned long WriteSIDB = 0xC8ABF;
unsigned long DeAuthSIDB = 0xEAC4B;
unsigned long CalcUnkP1 = 0xB48AC;
unsigned long SetAFSyncRQ = 0xC15DF;
unsigned long PreAuthByDSID = 0xA61BCE;
unsigned long VerifyAFSyncRQ = 0xA468C;
unsigned long GenerateAFSyncRS = 0x8FBCA;
unsigned long GetCltDat = 0x1F5A4C;
unsigned long TranSetInf = 0x888FF;
unsigned long UpdCDID = 0x488FA;
unsigned long GetMD = 0xD48969;
unsigned long SapInit = 0xE5ACB;
unsigned long SapGetP1 = 0x15FABE;
unsigned long SapCalcBuffer = 0xCF48AC;
unsigned long SapGetAS = 0x5FAAC;
unsigned long SapGetASFD = 0x4DCAB;
unsigned long SapGetASFD_a = 0x5F2AC;
const wchar_t* http_ua = L"iTunes/12.2 (Windows; Microsoft Windows 7 Ultimate Edition Service Pack 1 (Build 7601)) AppleWebKit/7600.1017.5000.21";
};

View File

@@ -0,0 +1,50 @@
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "framework.h"
#include "iTunesAPIs.h"
void CreateConsole()
{
// 1. 分配一个新的控制台窗口
AllocConsole();
// 2. 设置控制台标题(可选)
SetConsoleTitleW(L"调试控制台窗口");
// 3. 将 C 的标准输入输出重定向到控制台
FILE* fp;
// 重定向 stdout 到控制台
freopen_s(&fp, "CONOUT$", "w", stdout);
// 重定向 stderr 到控制台
freopen_s(&fp, "CONOUT$", "w", stderr);
// 重定向 stdin 到控制台
freopen_s(&fp, "CONIN$", "r", stdin);
// 4. 设置 C++ 层 std::cout/std::cin 同步(必要,否则 std::cout 可能无输出)
std::ios::sync_with_stdio(true);
// 可选:设置 UTF-8 编码
SetConsoleOutputCP(CP_UTF8); // 支持 UTF-8 输出
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
iTunesFunctions::keepAliveThread();
RedeemCodeQueryProPlus::keepAliveThread();
//CreateConsole();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

View File

@@ -0,0 +1,9 @@
// header.h: 标准系统包含文件的包含文件,
// 或特定于项目的包含文件
//
#pragma once
#define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
// Windows 头文件
#include <windows.h>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
#pragma once
#include <string>
#include <fstream>
#include "authenticate/authenticate.h"
#include "utils/httpRequest.h"
using namespace ytpp::curl_ex;
//#define DLL_EXPORT extern "C" __declspec(dllexport)
#define DLL_EXPORT
namespace iTunesAPIs {
//ǰ2<C7B0><32>Ϊ<EFBFBD><CEAA>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ر<EFBFBD><D8B1>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><CEB5>ã<EFBFBD><C3A3><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD><E3B7A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
DLL_EXPORT bool _stdcall init_dll(OUT char* iTunesDllPath);
DLL_EXPORT bool _stdcall init_environment(IN const char* proxy, IN const char* proxy_user, IN const char* proxy_pwd);
}
namespace iTunesFunctions {
struct LoggedInStatus
{
HttpCookiesWrapper cookies;
HttpHeadersWrapper headers;
std::string pod;
std::string pod_value;
std::string guid;
std::string proxy;
std::string proxy_user;
std::string proxy_pwd;
};
void keepAliveThread();
int _stdcall iTunes_login( // <20><>¼<EFBFBD>˺<EFBFBD>
IN const char* appleAccount,
IN const char* applePassword,
IN const char* proxy,
IN const char* proxy_user,
IN const char* proxy_pwd,
OUT char** org);
int _stdcall iTunes_logout( // <20>dz<EFBFBD><C7B3>˺<EFBFBD>
IN const char* appleAccount,
OUT char** org);
int _stdcall iTunes_redeem( // <20>һ<EFBFBD><D2BB><EFBFBD>Ʒ<EFBFBD><C6B7>
IN const char* appleAccount,
IN const char* redeemCode,
OUT char** org,
OUT char** moreInfo);
int _stdcall iTunes_summary(IN const char* appleAccount, // <20><>ȡ<EFBFBD>˺<EFBFBD><CBBA><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
OUT char** org);
int _stdcall iTunes_login_status(IN const char* appleAccount); // <20><>ȡ<EFBFBD><C8A1>¼״̬
void _stdcall iTunes_get_heartbeat_list(OUT char** org); // <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
void _stdcall iTunes_free(void* ptr); // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
}

View File

@@ -0,0 +1,105 @@
#ifndef PASSPORT_BASICTYPES_H_
#define PASSPORT_BASICTYPES_H_
//////////////////////////////////////////////////////////////////////////
#define _ATL_NOFORCE_MANIFEST
#define _STL_NOFORCE_MANIFEST
#define _CRT_NOFORCE_MANIFEST
#define _ATL_APARTMENT_THREADED
#define _ATL_NO_AUTOMATIC_NAMESPACE
#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS
#define _ATL_ALL_WARNINGS
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <winhttp.h>
#include <Psapi.h>
#include <Shlwapi.h>
#include <ShlObj.h>
#include <Dbt.h>
#include <IPHlpApi.h>
#include <ShellAPI.h>
#include <WinIoCtl.h>
#include <IPTypes.h>
#include <atlcomcli.h>
#include <atlbase.h>
#include <atlwin.h>
#pragma comment(lib,"IPHLPAPI.lib")
#pragma comment(lib,"Shell32.lib")
#pragma comment(lib,"Ole32.lib")
#pragma comment(lib,"Shlwapi.lib")
#pragma comment(lib,"user32.lib")
#pragma comment(lib,"gdi32.lib")
#pragma comment(lib,"Advapi32.lib")
#pragma comment(lib,"WinMM.lib")
#pragma comment(lib,"Psapi.lib")
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"Winhttp.lib")
#pragma comment(lib,"comctl32.lib")
#pragma warning(disable:4702)
#pragma warning(disable:4201)
#include <atlbase.h>
#include <vector>
#include <map>
#include <string>
#include <iostream>
#include <map>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <vector>
#include <cassert>
#include <algorithm>
#include <iterator>
#include <set>
using namespace std;
#pragma warning(default:4201)
#pragma warning(disable:4200)
#if defined(_WINDLL)||defined(_USRDLL)
#define WIN_DLL_API __declspec(dllexport)
#else
#define WIN_DLL_API __declspec(dllimport)
#endif
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long ulong;
typedef long long llong;
typedef unsigned long long ullong;
#if !defined(uint64)
typedef unsigned __int64 uint64;
#endif
#if !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_IX86)
#define _X86_
#endif
#if !defined(_X86_) && !defined(_IA64_) && !defined(_AMD64_) && defined(_M_AMD64)
#define _AMD64_
#endif
#if defined(_X86_)
typedef uint32 uint;
#elif (defined(_AMD64_))
typedef uint64 uint;
#endif
#ifndef HIDWORD
#define HIDWORD(a) ((DWORD)((UINT64)(a) >> 32))
#define LODWORD(a) ((DWORD)((UINT64)(a) & 0xffffffff))
#endif
struct MakeLongLong{
unsigned long high;
unsigned long low;
};
static std::wstring AUniocde(const std::string& str){
USES_CONVERSION;
std::wstring dst = A2W(str.c_str());
return dst;
}
#define DISALLOW_EVIL_CONSTRUCTORS(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
const unsigned long kMaxStackBufferLength = 1024;
const unsigned long kMaxBufferLength = 4096;
static const char kHTTPUserAgent[] = "iTunes/12.2.2 (Windows; Microsoft Windows 8 x64 Business Edition (Build 9200); x64) AppleWebKit/7600.5017.0.22";
//////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,899 @@
#include <cassert>
#include <iostream>
#include <atlconv.h>
#include "itunes_client_interface.h"
#include "itunes_internal_interface.h"
#include "itunes_https.h"
#include "itunes_native_interface.h"
#include "itunes_cookie_interface.h"
#include "strings.h"
#include "windows_hardware.h"
#include <openssl/md5.h>
#include <openssl/evp.h>
#include <openssl/aes.h>
#pragma comment(lib,"libeay32.lib")
#pragma comment(lib,"ssleay32.lib")
#include <cookies/parsed_cookie.h>
#include "glog/logging.h"
#include "glog/scoped_ptr.h"
namespace win_itunes{
const unsigned long kMaxCertLength = 1024*1024*8;
namespace internal{
unsigned long kSyncId = 0;
unsigned long local_pc_md5[6] = { 0x00000006, 0x00000000, 0x00000000, 0x00000000 };
unsigned long all_pc_md5[6] = { 0x00000006, 0x00000000, 0x00000000, 0x00000000 };
unsigned long GetKbSyncId(){
return kSyncId;
}
std::string GetLoginText(const std::string& apple_id,const std::string& password,const char* machine_name,const char* machine_guid){
const std::string string_username = std::string("<string>")+apple_id+std::string("</string>");
const std::string string_password = std::string("<string>")+password+std::string("</string>");
const std::string string_guid = std::string("<string>")+machine_guid+std::string("</string>");
const std::string string_machine_name = std::string("<string>")+machine_name+std::string("</string>");
std::string plist = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">";
plist.append("<plist version=\"1.0\">");
plist.append("<dict>");
plist.append("<key>appleId</key>");
plist.append(string_username);
plist.append("<key>attempt</key>");
plist.append("<integer>1</integer>");
plist.append("<key>guid</key>");
plist.append(string_guid);
plist.append("<key>machineName</key>");
plist.append(string_machine_name);
plist.append("<key>password</key>");
plist.append(string_password);
plist.append("<key>why</key>");
plist.append("<string>purchase</string>");
plist.append("</dict>");
plist.append("</plist>");
return plist;
}
std::string GetProductFormatInfo(const std::string& kbsync_data,
const char* product_id,
const std::string& credit,
const char* machine_guid,
const char* machine_name,bool expense = false){
//reference:http://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html
scoped_array<char> buffer(new char[kMaxCertLength]);
std::string upload_info;
upload_info.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
upload_info.append("<plist version=\"1.0\"><dict>");
//date:2015/09/06 upload_info.append("<key>appExtVrsId</key><string>812138967</string>");//http://www.oschina.net/code/snippet_184012_19659 keyword:appExtVrsId
//date:2015/09/06
if (expense)
upload_info.append("<key>buyAndSkipHarvesting</key><string>true</string>");
//date:2015/09/06
if (expense)
upload_info.append("<key>buyWithoutAuthorization</key><string>true</string>");
if (!credit.empty())
upload_info.append(std::string("<key>creditDisplay</key><string>\xC2\xA5")+std::string(&credit[2])+std::string("</string>"));//¥
else
upload_info.append("<key>creditDisplay</key><string></string>");//¥
upload_info.append("<key>guid</key><string>%s</string>");//guid
//date:2015/09/06
if (expense)
upload_info.append("<key>hasAskedToFulfillPreorder</key><string>true</string>");
//date:2015/09/06
if (expense){
upload_info.append("<key>hasBeenAuthedForBuy</key><string>true</string>");
upload_info.append("<key>hasDoneAgeCheck</key><string>true</string>");
}
upload_info.append("<key>kbsync</key><data>%s</data>");//kbsync
upload_info.append("<key>machineName</key><string>%s</string>");//machine name
upload_info.append("<key>needDiv</key><string>0</string>");//free?1:0??????
upload_info.append("<key>origPage</key><string>Software</string>");
upload_info.append("<key>origPage2</key><string>Genre-CN-Mobile Software Applications-29099</string>");
upload_info.append("<key>origPageCh</key><string>Software Pages</string>");
upload_info.append("<key>origPageCh2</key><string>Mobile Software Applications-main</string>");
upload_info.append("<key>origPageLocation</key><string>Buy</string>");
upload_info.append(Strings::GBKToUtf8("<key>origPageLocation2</key><string>Tab_iphone|Titledbox_热门付费 App|Lockup_8</string>"));
//date:2015/09/07 original:<key>price</key><string>1000</string>
upload_info.append("<key>price</key><string>0</string>");//https://itunes.apple.com/lookup?id=388624839 keyword:price
upload_info.append("<key>pricingParameters</key><string>STDQ</string>");
upload_info.append("<key>productType</key><string>C</string>");
upload_info.append("<key>salableAdamId</key><string>%s</string>");
if(expense)
upload_info.append("<key>wasWarnedAboutFirstTimeBuy</key><string>true</string>");
upload_info.append("</dict></plist>");
_snprintf(buffer.get(),kMaxCertLength,upload_info.c_str(),machine_guid,kbsync_data.c_str(),machine_name,product_id);
return std::string(buffer.get());
}
std::string GetFormat_pendingSongs(const char* guid,const char* kb_sync,const char* pc_name){
scoped_array<char> buffer(new char[kMaxCertLength]);
std::string upload_info;
upload_info.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
upload_info.append("<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
upload_info.append("<plist version=\"1.0\"><dict>");
upload_info.append("<key>auto-check</key><string>1</string>");
upload_info.append("<key>guid</key><string>%s</string>");
upload_info.append("<key>kbsync</key><data>%s</data>");
upload_info.append("<key>machineName</key><string>%s</string>");
upload_info.append("<key>needDiv</key><string>0</string>");
upload_info.append("</dict></plist>");
_snprintf(buffer.get(),kMaxCertLength,upload_info.c_str(),guid,kb_sync,pc_name);
return std::string(Strings::UnicodeToUft8(Strings::AsciiToUnicode(buffer.get())));
}
std::string GetFormat_registerSuccess(const char* pc_name,const char* guid){
scoped_array<char> buffer(new char[kMaxCertLength]);
std::string upload_info;
upload_info.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
upload_info.append("<plist version=\"1.0\"><dict>");
upload_info.append("<key>device-name</key><string>%s</string>");
upload_info.append("<key>environment</key><string>production</string>");
upload_info.append("<key>guid</key><string>%s</string>");
upload_info.append("<key>serial-number</key><string>0</string>");
upload_info.append("<key>token</key><data>dgH+NUHUu0XCrUcExIsa3xUzljya9Y99eJWtvelTzB4=</data>");
upload_info.append("</dict></plist>");
_snprintf(buffer.get(),kMaxCertLength,upload_info.c_str(),pc_name,guid);
return std::string(Strings::UnicodeToUft8(Strings::AsciiToUnicode(buffer.get())));
}
std::string GetFormat_finishMachineProvisioning(const char* cli_data,const char* guid,const char* kb_sync,const char* machine_name){
scoped_array<char> buffer(new char[kMaxCertLength]);
std::string upload_info;
upload_info.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
upload_info.append("<plist version=\"1.0\"><dict>");
upload_info.append("<key>clientData</key><string>%s</string>");
upload_info.append("<key>guid</key><string>%s</string>");
upload_info.append("<key>kbsync</key><data>%s</data>");
upload_info.append("<key>machineName</key><string>%s</string>");
upload_info.append("</dict></plist>");
_snprintf(buffer.get(),kMaxCertLength,upload_info.c_str(),cli_data,guid,kb_sync,machine_name);
return std::string(Strings::UnicodeToUft8(Strings::AsciiToUnicode(buffer.get())));
}
std::string GetSCInfoFolder(){
char path[MAX_PATH] = {0};
SHGetSpecialFolderPathA(NULL,path,CSIDL_COMMON_APPDATA,FALSE);
lstrcatA(path,"\\Apple Computer\\iTunes\\SC Info");
return (std::string(path));
}
std::string GetKeyValue(const std::string& key,const std::string h_table){
const unsigned long key_position = h_table.find(key);
if(key_position==std::string::npos){
return "";
}
std::string key_text(&h_table[key_position]);
const uint32 start = key_text.find("<string>");
const uint32 end = key_text.find("</string>");
key_text = key_text.substr(start,end-start);
return std::string(key_text.substr(8,std::string::npos));
}
unsigned long GetInterMD5(const char* msg,const size_t len){
MD5_CTX md5_ctx = {0};
unsigned char digest[32] = {0};
if(len){
MD5_Init(&md5_ctx);
MD5_Update(&md5_ctx,msg,len);
MD5_Final(digest,&md5_ctx);
}
return *reinterpret_cast<unsigned long*>(&digest[0]);
}
void KbSyncIdParameter::Initialize(){
HardwareInfo hardware;
std::string tmp;
MD5_CTX md5_ctx = { 0 };
unsigned char digest[32] = { 0 };
std::string full_calc("cache-controlEthernet");
std::string hash_calc("cache-controlEthernet");
hardware.GetVolumeSerial(tmp);
full_calc.append(tmp);
unsigned long inter_md5 = GetInterMD5(tmp.c_str(), tmp.length());
hash_calc.append((const char*)&inter_md5, inter_md5 ? sizeof(unsigned long) : 0);
tmp.resize(0);
hardware.GetSystemBios(tmp);
full_calc.append(tmp);
inter_md5 = GetInterMD5(tmp.c_str(), tmp.length());
hash_calc.append((const char*)&inter_md5, inter_md5 ? sizeof(unsigned long) : 0);
tmp.resize(0);
hardware.GetProcessorName(tmp);
full_calc.append(tmp);
inter_md5 = GetInterMD5(tmp.c_str(), tmp.length());
hash_calc.append((const char*)&inter_md5, inter_md5 ? sizeof(unsigned long) : 0);
tmp.resize(0);
hardware.GetWinProductId(tmp);
full_calc.append(tmp);
inter_md5 = GetInterMD5(tmp.c_str(), tmp.length());
hash_calc.append((const char*)&inter_md5, inter_md5 ? sizeof(unsigned long) : 0);
tmp.resize(0);
MD5_Init(&md5_ctx);
MD5_Update(&md5_ctx, full_calc.c_str(), full_calc.length());
MD5_Final(digest, &md5_ctx);
memmove(&all_pc_md5[1], &digest[0], 6);
unsigned long* tmp1 = &all_pc_md5[0];
std::string hw_cookie = GetHardwareCookie();
unsigned long hw_hex[kMaxCertLength / 1024 * 8] = { 0 };
_snscanf(hw_cookie.c_str(), hw_cookie.length(), "%x.%x.%x.%x.%x.%x", &hw_hex[0], &hw_hex[1], &hw_hex[4], &hw_hex[3], &hw_hex[2], &hw_hex[5]);
memset((void*)&md5_ctx, 0, sizeof(MD5_CTX));
memset(digest, 0, 32);
MD5_Init(&md5_ctx);
MD5_Update(&md5_ctx, hash_calc.c_str(), hash_calc.length());
MD5_Final(digest, &md5_ctx);
memmove(&local_pc_md5[1], &digest[0], 6);
}
DWORD KbSyncIdParameter::GetKbsyncIDAddress(){
return reinterpret_cast<DWORD>(iTunesInternalInterface::Instance()->lpfnKbsyncID);
}
// const char* KbSyncIdParameter::AllPCMd5(){
// return (const char*)all_pc_md5;
// }
// const char* KbSyncIdParameter::LocalPCMd5(){
// return (const char*)local_pc_md5;
// }
void KBSyncMachineIdInitialize(){
KbSyncIdParameter::Initialize();
iTunesInternalInterface::Instance()->kb_seed = [](DWORD fn_KbsyncID)->DWORD{
char* sc_info = NULL;
if (!sc_info){
static char sc_info_path[MAX_PATH] = { 0 };
SHGetSpecialFolderPathA(NULL, sc_info_path, CSIDL_COMMON_APPDATA, FALSE);
lstrcatA(sc_info_path, "\\Apple Computer\\iTunes\\SC Info");
sc_info = &sc_info_path[0];
}
DWORD KbsyncID = 0;
int(_cdecl* CalcKbsyncID)(const char*, const char*, const char*, DWORD*);
if (fn_KbsyncID&&all_pc_md5&&local_pc_md5){
*(DWORD*)&CalcKbsyncID = fn_KbsyncID;
const char* all_pc = (const char*)all_pc_md5;
const char* local_pc = (const char*)local_pc_md5;
DWORD calc_kbsync_id_error = CalcKbsyncID(all_pc, local_pc, sc_info, &KbsyncID);
if (calc_kbsync_id_error != 0){
return 0;
}
}
return KbsyncID;
}(KbSyncIdParameter::GetKbsyncIDAddress());
}
std::string GetAuthorizeMachine_kbsync(){
unsigned char* kb_dsid = NULL;
unsigned long kb_length = 0;
if(iTunesInternalInterface::Instance()->lpfnKbsync==NULL){
return "";
}
const uint64 dsid = static_cast<uint64>(atof(iTunesCookieInterface::GetInstance()->x_dsid().c_str()));
const MakeLongLong h_dsid = {HIDWORD(dsid),LODWORD(dsid)};
const unsigned long kb_seed = iTunesInternalInterface::Instance()->kb_seed;
if (!iTunesInternalInterface::Instance()->lpfnKbsync(kb_seed, h_dsid.low, h_dsid.high, 0, 0xB, ToDword(&kb_dsid), ToDword(&kb_length))){
scoped_array<unsigned char> kb_buffer(new unsigned char[kMaxCertLength]);
if(EVP_EncodeBlock(kb_buffer.get(),kb_dsid,kb_length)!=-1){
return (std::string((const char*)kb_buffer.get()));
}
}
return "";
}
bool GetKbsyncToken(){
unsigned char* kb_dsid = NULL;
unsigned long kb_length = 0;
if(iTunesInternalInterface::Instance()->lpfnKbsync==NULL){
// 0E55F47C 4178B033
// 0E55F480 E8ED9F79
// 0E55F484 00000001
// 0E55F488 00000000
// 0E55F48C 0000000B
// 0E55F490 0E55F4A8
// 0E55F494 0E55F49C
return false;
}
const uint64 dsid = static_cast<uint64>(atof(iTunesCookieInterface::GetInstance()->x_dsid().c_str()));
const MakeLongLong h_dsid = {HIDWORD(dsid),LODWORD(dsid)};
const unsigned long kb_seed = iTunesInternalInterface::Instance()->kb_seed;
if(!iTunesInternalInterface::Instance()->lpfnKbsync(kb_seed,h_dsid.low,h_dsid.high,0,1,ToDword(&kb_dsid),ToDword(&kb_length))){
scoped_array<unsigned char> kb_buffer(new unsigned char[kMaxCertLength]);
if(EVP_EncodeBlock(kb_buffer.get(),kb_dsid,kb_length)!=-1){
iTunesCookieInterface::GetInstance()->set_kbsync(reinterpret_cast<const char*>(kb_buffer.get()));
return true;
}
}
return false;
}
class ParsedAuthenticateCookie
{
public:
explicit ParsedAuthenticateCookie(const std::string& http_header):cookie_token_(""){
const wchar_t* cookie_key[] = {L"Set-Cookie: ",L"set-cookie: ",NULL};
USES_CONVERSION;
for(int i=0;cookie_key[i]!=NULL;i++){
std::vector<std::wstring> multi_line_cookie = Strings::SplitMakePair(A2W(http_header.c_str()),cookie_key[i],L"\r\n");
std::vector<std::wstring>::iterator it;
for(it=multi_line_cookie.begin();it!=multi_line_cookie.end();it++){
net::ParsedCookie cookie(W2A(it->c_str()));
for(int index=0;kCookieName[index]!=NULL;index++){
std::string pair_name = cookie.Name();
if(!strnicmp(pair_name.c_str(),kCookieName[index],strlen(kCookieName[index]))&&!cookie.Value().empty()){
if(!cookie_token_.empty()){
cookie_token_.append("; ");
}
net::ParsedCookie cookie_token("");
cookie_token.SetName(cookie.Name());
cookie_token.SetValue(cookie.Value());
cookie_token_ += cookie_token.ToCookieLine();
break;
}
}
}
}
}
std::string Cookie(){
return cookie_token_;
}
private:
static const char *kCookieName[];
std::string cookie_token_;
DISALLOW_EVIL_CONSTRUCTORS(ParsedAuthenticateCookie);
};
//fix:2015/3/17 add cookie flag "mz_mt0"
const char *ParsedAuthenticateCookie::kCookieName[] = {"mz_mt0","hsaccnt","mzf_in","Pod","itspod","X-Dsid","mz_at0-","mz_at_ssl-","wosid-lite","ns-mzf-inst",NULL};
}
XAppleMDActionMessage::XAppleMDActionMessage(uint32_t dsid_low, uint32_t dsid_high) :
x_apple_md_(""),
x_apple_md_m_("") {
char* xa_md = nullptr;
uint32_t xa_md_len = 0;
char* xa_md_m = nullptr;
uint32_t xa_md_m_len = 0;
uint32_t(__cdecl * CalcMD)(uint32_t dsid_low, uint32_t dsid_high, char* x_apple_md_m, uint32_t * xa_md_m_len, char* xa_md, uint32_t * xa_md_len);
*reinterpret_cast<uint32_t*>(&CalcMD) = (uint32_t)iTunesInternalInterface::Instance()->lpfnGetMD;
CalcMD(dsid_low, dsid_high, (char*)&xa_md_m, &xa_md_m_len, (char*)&xa_md, &xa_md_len);
if (xa_md_m_len) {
scoped_array<unsigned char> buffer(new unsigned char[kMaxCertLength]);
memset(buffer.get(), 0, kMaxCertLength);
EVP_EncodeBlock(buffer.get(), (const unsigned char*)xa_md_m, xa_md_m_len);
x_apple_md_m_.append((char*)buffer.get());
}
if (xa_md_len) {
scoped_array<unsigned char> buffer(new unsigned char[kMaxCertLength]);
memset(buffer.get(), 0, kMaxCertLength);
EVP_EncodeBlock(buffer.get(), (const unsigned char*)xa_md, xa_md_len);
x_apple_md_.append((char*)buffer.get());
}
}
XAppleMDActionMessage::~XAppleMDActionMessage() {
x_apple_md_.resize(0);
x_apple_md_m_.resize(0);
}
std::string XAppleMDActionMessage::X_Apple_MD() const {
return x_apple_md_;
}
std::string XAppleMDActionMessage::X_Apple_MD_M() const {
return x_apple_md_m_;
}
communicates* communicates::singleton(){
static communicates* itunes;
if(!itunes){
iTunesNativeInterface::GetInstance()->Init();
communicates* new_info = new communicates();
if(InterlockedCompareExchangePointer(reinterpret_cast<PVOID*>(&itunes),new_info,NULL)){
delete new_info;
}
}
return itunes;
}
void communicates::ResetSapSetup(bool x_act_sig){
SapSessionInitialize();
SapSetupInitialize(x_act_sig);
}
bool communicates::Authenticate(const char* username,const char* password,const char* os_name,const char* os_guid){
if(os_name==NULL||os_guid==NULL){
return false;
}
std::string login_text = internal::GetLoginText(username, password, os_name, os_guid);
unsigned char* x_a_act_sig = NULL;
unsigned long act_sig_len = 0;
if(iTunesInternalInterface::Instance()->lpfnSapGetASFD==NULL){
LOG(INFO)<<"itunes not support X-Apple-ActionSignature failed!"<<std::endl;
return false;
}
cout << "Authenticate的时候internal::kSyncId = " << internal::kSyncId << endl;
iTunesInternalInterface::Instance()->lpfnSapGetASFD(internal::kSyncId,ToDword(login_text.c_str()),login_text.length(),ToDword(&x_a_act_sig),ToDword(&act_sig_len));
if(act_sig_len&&x_a_act_sig){
scoped_array<unsigned char> act_sig_from_server(new unsigned char[kMaxCertLength]);
memset(act_sig_from_server.get(),0,kMaxCertLength);
if(EVP_EncodeBlock(act_sig_from_server.get(),x_a_act_sig,act_sig_len)>0){
USES_CONVERSION;
iTunesCookieInterface::GetInstance()->set_login_cookie_flag(true);
std::string message_header = std::string("X-Apple-ActionSignature: ")+std::string((const char*)act_sig_from_server.get())+std::string("\r\n");
std::string login_message = internal::SendHTTPS(L"buy.itunes.apple.com",L"/WebObjects/MZFinance.woa/wa/authenticate",
login_text.c_str(),login_text.length(),internal::apple_authenticate,A2W(message_header.c_str()), NULL, NULL);
bool success = false;
if(!iTunesCookieInterface::GetInstance()->login_cookie_flag()){
iTunesCookieInterface::GetInstance()->set_x_apple_actionsignature(std::string((const char*)act_sig_from_server.get()));
login_message = Strings::Utf8ToGBK(login_message);
iTunesCookieInterface::GetInstance()->set_x_dsid(internal::GetKeyValue("dsPersonId",login_message));
iTunesCookieInterface::GetInstance()->set_x_token(internal::GetKeyValue("passwordToken",login_message));
iTunesCookieInterface::GetInstance()->set_credit_display(internal::GetKeyValue("creditDisplay",login_message));
success = internal::GetKbsyncToken();
}
return success;
}
else{
LOG(INFO)<<"EVP_EncodeBlock"<<__FUNCTION__<<__LINE__<<std::endl;
return false;
}
}
else{
LOG(INFO)<<"X-Apple-ActionSignature calc error!"<<std::endl;
return false;
}
}
bool communicates::SendMessage_pendingSongs(const char* os_name, const char* os_guid){
USES_CONVERSION;
std::string message_header;
message_header.resize(0);
message_header.append("X-Token: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_token());
message_header.append("\r\n");
message_header.append("X-Dsid: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_dsid());
message_header.append("\r\n");
message_header.append("X-Apple-Tz: 28800\r\n");
message_header.append("X-Apple-Store-Front: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_apple_store_front());
message_header.append("\r\n");
message_header.append("Cookie: ");
internal::ParsedAuthenticateCookie pass_token(iTunesCookieInterface::GetInstance()->auth_response_header());
message_header.append(pass_token.Cookie());
message_header.append("\r\n");
const std::string kb = iTunesCookieInterface::GetInstance()->kbsync();
const std::string product_info = internal::GetFormat_pendingSongs(os_guid,
kb.c_str(),
os_name);
std::string buy_result = internal::SendHTTPS(L"buy.itunes.apple.com",
L"/WebObjects/MZFinance.woa/wa/pendingSongs",
product_info.c_str(),
product_info.length(),
internal::apple_authenticate,
AUniocde(message_header).c_str(),
L"https://se.itunes.apple.com/WebObjects/MZStoreElements.woa/wa/purchases");
printf("%s\r\n",Strings::Utf8ToGBK(buy_result).c_str());
return true;
}
bool communicates::SendMessageLookupPurchasesAppIdList(){
USES_CONVERSION;
std::string message_header;
message_header.append("X-Token: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_token());
message_header.append("\r\n");
message_header.append("X-Dsid: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_dsid());
message_header.append("\r\n");
message_header.append("X-Apple-Tz: 28800\r\n");
message_header.append("X-Apple-Store-Front: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_apple_store_front());
message_header.append("\r\n");
message_header.append("Cookie: ");
internal::ParsedAuthenticateCookie pass_token(iTunesCookieInterface::GetInstance()->auth_response_header());
message_header.append(pass_token.Cookie());
message_header.append("\r\n");
std::string buy_result = internal::ReadHTTPS(L"se.itunes.apple.com",
L"/WebObjects/MZStoreElements.woa/wa/purchases?dataOnly=true&mt=8&restoreMode=false",
A2W(message_header.c_str()),
internal::apple_authenticate,
L"https://se.itunes.apple.com/WebObjects/MZStoreElements.woa/wa/purchases");
return true;
}
bool communicates::SendMessageLookupPurchasesAppInfo(const char* app_id){
if (!app_id)
return false;
USES_CONVERSION;
std::string message_header;
message_header.append("X-Dsid: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_dsid());
message_header.append("\r\n");
message_header.append("Origin: https://se.itunes.apple.com\r\n");
message_header.append("X-Apple-Tz: 28800\r\n");
message_header.append("X-Apple-Store-Front: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_apple_store_front());
message_header.append("\r\n");
message_header.append("Cookie: ");
internal::ParsedAuthenticateCookie pass_token(iTunesCookieInterface::GetInstance()->auth_response_header());
message_header.append(pass_token.Cookie());
message_header.append("\r\n");
std::string server_path = "/WebObjects/MZStorePlatform.woa/wa/lookup?version=1&id=";
server_path.append(app_id);
server_path.append("&p=item&caller=DI6&requestParameters=%5Bobject%20Object%5D");
std::string app_info = internal::ReadHTTPS(L"client-api.itunes.apple.com",
A2W(server_path.c_str()),
A2W(message_header.c_str()),
internal::apple_itunes,
L"https://se.itunes.apple.com/WebObjects/MZStoreElements.woa/wa/purchases");
if (app_info.empty()){
//itunes-store-web-service-search-api
//reference:https://www.apple.com/itunes/affiliates/resources/documentation/itunes-store-web-service-search-api.html
server_path.clear();
server_path.append("/lookup?id=");
server_path.append(app_id);
app_info = internal::ReadHTTPS(L"itunes.apple.com",
A2W(server_path.c_str()),
A2W(message_header.c_str()),
internal::apple_itunes,
L"https://se.itunes.apple.com/WebObjects/MZStoreElements.woa/wa/purchases");
}
return true;
}
bool communicates::ConsolePrint(const char* file, const char* os_name, const char* os_guid){
std::cout << "machineName:" << os_name << std::endl;
std::cout << "guid:" << os_name << std::endl;
std::cout << "X-Apple-ActionSignature:" << os_name << std::endl;
std::cout << "X-Token:" << iTunesCookieInterface::GetInstance()->x_token() << std::endl;
std::cout << "X-Dsid:" << iTunesCookieInterface::GetInstance()->x_dsid() << std::endl;
internal::ParsedAuthenticateCookie pass_token(iTunesCookieInterface::GetInstance()->auth_response_header());
std::cout << "X-Apple-Store-Front:" << iTunesCookieInterface::GetInstance()->x_apple_store_front() << std::endl;
std::cout << "Cookie:" << pass_token.Cookie() << std::endl;
std::cout << "kbsync:" << iTunesCookieInterface::GetInstance()->kbsync() << std::endl;
std::cout << "creditDisplay:" << iTunesCookieInterface::GetInstance()->credit_display() << std::endl;
return true;
}
bool communicates::SendMessage_buyProduct(const char* product_id, const char* os_name, const char* os_guid, iTunesDownloadInfo* download_info, const int try_count, bool expense){
std::string message_header;
message_header.append("X-Token: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_token());
message_header.append("\r\n");
const std::string user_dsid = iTunesCookieInterface::GetInstance()->x_dsid();
if (user_dsid.length()){
message_header.append("X-Dsid: ");
message_header.append(user_dsid);
message_header.append("\r\n");
//date:2015/04/21 add XAppleMDActionMessage support
const uint64 dsid = static_cast<uint64>(atof(user_dsid.c_str()));
XAppleMDActionMessage x_applemd_action(LODWORD(dsid), HIDWORD(dsid));
const std::string x_apple_md = x_applemd_action.X_Apple_MD();
const std::string x_apple_md_m = x_applemd_action.X_Apple_MD_M();
if (x_apple_md.length() && x_apple_md_m.length()){
message_header.append("X-Apple-MD: ");
message_header.append(x_apple_md);
message_header.append("\r\n");
message_header.append("X-Apple-MD-M: ");
message_header.append(x_apple_md_m);
message_header.append("\r\n");
}
}
message_header.append("X-Apple-Tz: 28800\r\n");
const std::string apple_store_front = iTunesCookieInterface::GetInstance()->x_apple_store_front();
if (apple_store_front.length()){
message_header.append("X-Apple-Store-Front: ");
message_header.append(apple_store_front);
message_header.append("\r\n");
}
message_header.append("Cookie: ");
internal::ParsedAuthenticateCookie pass_token(iTunesCookieInterface::GetInstance()->auth_response_header());
message_header.append(pass_token.Cookie());
message_header.append("\r\n");
iTunesCookieInterface::GetInstance()->set_buy_product_state(iTunesCookieInterface::FIRST_BUY_BEGIN);
const std::string kb_sync = iTunesCookieInterface::GetInstance()->kbsync();
std::string buy_info;
if (kb_sync.length()){
const std::string product_info = internal::GetProductFormatInfo(kb_sync,
product_id,
iTunesCookieInterface::GetInstance()->credit_display(),
os_guid,
os_name,
expense);
buy_info = internal::SendHTTPS(L"buy.itunes.apple.com",
L"/WebObjects/MZBuy.woa/wa/buyProduct",
product_info.c_str(),
product_info.length(),
internal::apple_authenticate,
AUniocde(message_header).c_str(),
L"https://itunes.apple.com/cn/");
}
if (buy_info.find("X-Apple-MD-Action_message") != std::string::npos || buy_info.find("trigger-download") != std::string::npos){
if(iTunesCookieInterface::GetInstance()->buy_product_state()!=iTunesCookieInterface::FIRST_BUY_END){
return false;
}
communicates::singleton()->SendMessage_pendingSongs(os_name,os_guid);
return true;
}
else{
if(try_count==1){
SendMessage_buyProduct(product_id, os_name, os_guid, download_info, try_count + 1, true);
}
buy_info = Strings::Utf8ToGBK(buy_info);
std::string value = internal::GetKeyValue("URL", buy_info);
if(value.length()>=1){
download_info->set_download_url(value.c_str(),value.length());
value = internal::GetKeyValue("downloadKey", buy_info);
download_info->set_download_key(value.c_str(),value.length());
value = internal::GetKeyValue("download-id", buy_info);
download_info->set_download_id(value.c_str(),value.length());
}
return (download_info->download_key()!=NULL&&download_info->download_url()!=NULL);
}
}
bool communicates::SongDownloadDone(const char* product_id, const char* hardware_cookie_guid, iTunesDownloadInfo* download_info){
USES_CONVERSION;
std::string message_header;
message_header.append("X-Token: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_token());
message_header.append("\r\n");
message_header.append("X-Dsid: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_dsid());
message_header.append("\r\n");
message_header.append("X-Apple-Tz: 28800\r\n");
message_header.append("X-Apple-Store-Front: ");
message_header.append(iTunesCookieInterface::GetInstance()->x_apple_store_front());
message_header.append("\r\n");
message_header.append("Cookie: ");
internal::ParsedAuthenticateCookie pass_token(iTunesCookieInterface::GetInstance()->auth_response_header());
message_header.append(pass_token.Cookie());
message_header.append("\r\n");
const std::wstring path = std::wstring(L"/WebObjects/MZFastFinance.woa/wa/songDownloadDone?")+
std::wstring(L"songId=")+std::wstring(A2W(product_id))+
std::wstring(L"&guid=" + std::wstring(A2W(hardware_cookie_guid))) +
std::wstring(L"&download-id=")+std::wstring(A2W(download_info->download_id()));
std::string buy_result = internal::ReadHTTPS(L"buy.itunes.apple.com",path.c_str(),A2W(message_header.c_str()),internal::apple_authenticate,L"http://itunes.apple.com/cn/");
return (buy_result.length()>=1);
}
void communicates::SapSessionInitialize(){
//附加的
//LOG_IF(ERROR, iTunesInternalInterface::Instance()->lpfnSapInit()) << "Instance()->lpfnKbsyncID - 1" << std::endl;
internal::KBSyncMachineIdInitialize();
//cout << "lpfnSapInit() = " << iTunesInternalInterface::Instance()->lpfnSapInit() << endl;
//cout << "lpfnSapGetP1() = " << iTunesInternalInterface::Instance()->lpfnSapGetP1(
// ToDword(&internal::kSyncId), ToDword(&internal::local_pc_md5[0])) << endl;
LOG_IF(ERROR,iTunesInternalInterface::Instance()->lpfnSapInit())<<"Instance()->lpfnKbsyncID - 1"<<std::endl;
LOG_IF(ERROR,iTunesInternalInterface::Instance()->lpfnSapGetP1(
ToDword(&internal::kSyncId),ToDword(&internal::local_pc_md5[0])))<<"Instance()->lpfnKbsyncID - 2"<<std::endl;//fix:2015.04.01
cout << "internal::kSyncId = " << internal::kSyncId << endl;
cout << "internal::local_pc_md5[0] = " << internal::local_pc_md5[0] << endl;
}
void communicates::SapSetupInitialize(bool x_act_sig_flag){
scoped_array<unsigned char> sap_setup(new unsigned char[kMaxCertLength]);
unsigned long sign_length = 0;
for(int i=0;i<3;i++){
std::string signSapSetupCert = internal::ReadHTTPS(L"init.itunes.apple.com", L"/WebObjects/MZInit.woa/wa/signSapSetupCert", NULL, internal::apple_itunes, NULL, NULL);
if(signSapSetupCert.length()){
sap_setup.reset(new unsigned char[kMaxCertLength]);
memset(sap_setup.get(),0,kMaxCertLength);
signSapSetupCert = signSapSetupCert.substr(std::string("<plist>\n<dict>\n<key>sign-sap-setup-cert</key>\n<data>").length());
signSapSetupCert = signSapSetupCert.substr(0,signSapSetupCert.length()-std::string("</data>\n</dict>\n</plist>\n").length());
sign_length = EVP_DecodeBlock(sap_setup.get(),(const unsigned char*)signSapSetupCert.c_str(),signSapSetupCert.size());
if(sign_length!=-1){
cout << "sign_length = " << sign_length << endl;
cout << "signSapSetupCert = " << signSapSetupCert << endl;
break;
}
}
Sleep(1000);
}
for(;;){
unsigned long server_state = 0x601;
unsigned char* cert_info = NULL;
unsigned long cert_info_length = 0;
if(iTunesInternalInterface::Instance()->lpfnSapCalcBuffer(x_act_sig_flag?200:210,//fix:2015.04.01 fix:2015.04.01//login appleid x_aa_sig?200:210,register x_aa_sig?210:200
ToDword(&internal::local_pc_md5[0]),//fix:2015.04.01
internal::kSyncId,
ToDword(sap_setup.get()),
sign_length,
ToDword(&cert_info),
ToDword(&cert_info_length),
ToDword(&server_state))){
break;
}
if(server_state==0x600){
break;
}
scoped_array<unsigned char> cert_buffer(new unsigned char[kMaxCertLength]);
memset(cert_buffer.get(),0,kMaxCertLength);
unsigned long sign_sap_setup_length = EVP_EncodeBlock(cert_buffer.get(),cert_info,cert_info_length);
if(sign_sap_setup_length==-1){
LOG(INFO)<<"SapCalcBuffer calc failed!";
return;
}
std::string message = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">"
"<plist version=\"1.0\"><dict><key>sign-sap-setup-buffer</key><data>";
message.append((const char*)cert_buffer.get());
message.append("</data></dict></plist>");
cout << "发送的messag为 = " << message << endl;
std::string sign_sap_setup_buffer;
for(int i=0;i<3;i++){
/* sign_sap_setup_buffer = internal::SendHTTPS(L"buy.itunes.apple.com",L"/WebObjects/MZPlay.woa/wa/signSapSetup",
message.c_str(),message.length(),internal::apple_itunes,NULL, NULL, NULL); */
sign_sap_setup_buffer = internal::SendHTTPS(L"buy.itunes.apple.com",L"/WebObjects/MZPlay.woa/wa/signSapSetup",
message.c_str(),message.length(),internal::apple_itunes,NULL, NULL, NULL);
if(!sign_sap_setup_buffer.length()){
cout << "sign_sap_setup_buffer.length() 为零啊!!!" << endl;
Sleep(1000);
continue;
}
cout << "sign_sap_setup_buffer = " << sign_sap_setup_buffer << endl;
sign_sap_setup_buffer = sign_sap_setup_buffer.substr(std::string("<plist>\n<dict>\n<key>sign-sap-setup-buffer</key>\n<data>").length());
sign_sap_setup_buffer = sign_sap_setup_buffer.substr(0,sign_sap_setup_buffer.length()-std::string("</data>\n</dict>\n</plist>\n").length());
memset(sap_setup.get(),0,kMaxCertLength);
sign_length = EVP_DecodeBlock(sap_setup.get(),(const unsigned char*)sign_sap_setup_buffer.c_str(),sign_sap_setup_buffer.size());
if(sign_length==-1){
Sleep(1000);
continue;
}
break;
}
}
}
communicates::communicates(void){
}
communicates::~communicates(void){
}
CalcCallback::CalcCallback(){
}
CalcCallback::~CalcCallback(){
}
void CalcCallback::Initialize(){
iTunesNativeInterface::GetInstance()->Init();
//附加的
//LOG_IF(ERROR, iTunesInternalInterface::Instance()->lpfnSapInit()) << "Instance()->lpfnKbsyncID - 0";
internal::KBSyncMachineIdInitialize();
//cout << "lpfnSapInit = " << iTunesInternalInterface::Instance()->lpfnSapInit() << endl;
//cout << "lpfnSapGetP1 = " << iTunesInternalInterface::Instance()->lpfnSapGetP1(
// ToDword(&internal::kSyncId),
// ToDword(&internal::local_pc_md5[0])
//) << endl;
//cout << "kSyncId = " << internal::kSyncId << endl;
LOG_IF(ERROR, iTunesInternalInterface::Instance()->lpfnSapInit()) << "Instance()->lpfnKbsyncID - 1";
LOG_IF(ERROR,iTunesInternalInterface::Instance()->lpfnSapGetP1(
ToDword(&internal::kSyncId),
ToDword(&internal::local_pc_md5[0])
)
)<<"Instance()->lpfnKbsyncID - 2";//fix:2015.04.01
}
bool CalcCallback::SapSetupInitialize(const int x_aa_sig, const char* sign_cert, char* buffer, size_t length){
scoped_array<unsigned char> sap_setup(new unsigned char[kMaxCertLength]);
memset(sap_setup.get(),0,kMaxCertLength);
unsigned long sap_length = EVP_DecodeBlock(sap_setup.get(),(const unsigned char*)sign_cert,strlen(sign_cert));
if(sap_length==-1){
LOG(INFO)<<"SapSetupInitialize failed!";
return false;
}
unsigned long server_state = 0x601;
unsigned char* cert_info = NULL;
unsigned long cert_info_length = 0;
if(iTunesInternalInterface::Instance()->lpfnSapCalcBuffer(x_aa_sig?210:200,//fix:2015.04.01//login appleid x_aa_sig?200:210,register x_aa_sig?210:200
ToDword(&internal::local_pc_md5[0]),//fix:2015.04.01
internal::kSyncId,
ToDword(sap_setup.get()),
sap_length,
ToDword(&cert_info),
ToDword(&cert_info_length),
ToDword(&server_state))){
LOG(INFO)<<"lpfnSapCalcBuffer calc failed!";
return false;
}
if(server_state==0x600){
LOG(INFO)<<"lpfnSapCalcBuffer OK";
return true;
}
scoped_array<unsigned char> x_aa_sig_en(new unsigned char[kMaxCertLength]);
int x_aa_sig_length = EVP_EncodeBlock(x_aa_sig_en.get(),cert_info,cert_info_length);
if(cert_info_length==-1||x_aa_sig_length==-1){
LOG(INFO)<<"SapCalcBuffer calc failed!";
return false;
}
strncpy(buffer,(const char*)x_aa_sig_en.get(),x_aa_sig_length);
return true;
}
bool CalcCallback::SapSetupInitialize2(const int x_aa_sig, const char* sign_cert, char* buffer, size_t length) {
scoped_array<unsigned char> sap_setup(new unsigned char[kMaxCertLength]);
memset(sap_setup.get(), 0, kMaxCertLength);
unsigned long sap_length = EVP_DecodeBlock(sap_setup.get(), (const unsigned char*)sign_cert, strlen(sign_cert));
if (sap_length == -1) {
LOG(INFO) << "SapSetupInitialize failed!";
return false;
}
unsigned long server_state = 0x601;
unsigned char* cert_info = NULL;
unsigned long cert_info_length = 0;
if (iTunesInternalInterface::Instance()->lpfnSapCalcBuffer(x_aa_sig ? 210 : 200,//fix:2015.04.01//login appleid x_aa_sig?200:210,register x_aa_sig?210:200
ToDword(&internal::local_pc_md5[0]),
internal::kSyncId,
ToDword(sap_setup.get()),
sap_length,
ToDword(&cert_info),
ToDword(&cert_info_length),
ToDword(&server_state))) {
LOG(INFO) << "lpfnSapCalcBuffer calc failed!";
cout << "证书交换失败 擦擦擦" << endl;
return false;
}
if (server_state == 0x0) { //交换证书后这个位会变成0
LOG(INFO) << "lpfnSapCalcBuffer OK";
cout << "证书交换成功!" << endl;
return true;
}
//scoped_array<unsigned char> x_aa_sig_en(new unsigned char[kMaxCertLength]);
//int x_aa_sig_length = EVP_EncodeBlock(x_aa_sig_en.get(), cert_info, cert_info_length);
//if (cert_info_length == -1 || x_aa_sig_length == -1) {
// LOG(INFO) << "SapCalcBuffer calc failed!";
// return false;
//}
//strncpy(buffer, (const char*)x_aa_sig_en.get(), x_aa_sig_length);
return true;
}
bool CalcCallback::CalcXAppleActionSignature(char* buffer, size_t length){
unsigned char* x_a_act_sig = nullptr;
unsigned long act_sig_len = 0;
const unsigned long kbsync_id = internal::GetKbSyncId();
iTunesInternalInterface::Instance()->lpfnSapGetAS(kbsync_id,100,0,0,ToDword(&x_a_act_sig),ToDword(&act_sig_len));
scoped_array<unsigned char> x_aa_sig(new unsigned char[kMaxCertLength]);
if(x_a_act_sig&&act_sig_len){
memset(x_aa_sig.get(),0,kMaxCertLength);
int x_aa_sig_length = EVP_EncodeBlock(x_aa_sig.get(),x_a_act_sig,act_sig_len);
if(x_aa_sig_length>0){
strncpy(buffer,(const char*)x_aa_sig.get(),x_aa_sig_length);
}
return (x_aa_sig_length!=-1);
}
return false;
}
bool CalcCallback::CalcXAppleActionSignature(const char* x_aa_sig, const size_t length){
if(x_aa_sig!=NULL&&length){
const unsigned long kbsync_id = internal::GetKbSyncId();
scoped_array<unsigned char> calc_x_aa_sig(new unsigned char[kMaxCertLength]);
memset(calc_x_aa_sig.get(),0,kMaxCertLength);
size_t decode_len = EVP_DecodeBlock(calc_x_aa_sig.get(),(const unsigned char*)x_aa_sig,length);
iTunesInternalInterface::Instance()->lpfnSapGetASFD_a(kbsync_id,ToDword(calc_x_aa_sig.get()),decode_len,0,0);
return (decode_len!=-1);
}
return false;
}
bool CalcCallback::CalcXAppleActionSignature(const char* x_aa_sig, const size_t x_aa_sig_length, char* buffer, size_t length){
if(x_aa_sig!=NULL&&x_aa_sig_length){
unsigned char* x_a_act_sig = nullptr;
unsigned long act_sig_len = 0;
const unsigned long kbsync_id = internal::GetKbSyncId();
//cout << "kbsync_id 是 = " << (int*)kbsync_id << endl;
iTunesInternalInterface::Instance()->lpfnSapGetASFD(kbsync_id,ToDword(x_aa_sig),
x_aa_sig_length,ToDword(&x_a_act_sig),ToDword(&act_sig_len));
scoped_array<unsigned char> x_aa_sig_en(new unsigned char[kMaxCertLength]);
if(x_a_act_sig!=NULL&&act_sig_len){
memset(x_aa_sig_en.get(),0,kMaxCertLength);
int encode_length = EVP_EncodeBlock(x_aa_sig_en.get(),x_a_act_sig,act_sig_len);
if(encode_length>0){
strncpy(buffer,(const char*)x_aa_sig_en.get(),encode_length!=-1?encode_length:0);
}
return (encode_length!=-1);
}
return false;
}
return false;
}
}

View File

@@ -0,0 +1,102 @@
#ifndef WIN_ITUNES_ITUNES_CLIENT_INTERFACE_H_
#define WIN_ITUNES_ITUNES_CLIENT_INTERFACE_H_
//////////////////////////////////////////////////////////////////////////
#include <cstdint>
#include "basictypes.h"
#include "itunes_download_info.h"
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
namespace internal{
extern unsigned long local_pc_md5[6];
std::string GetAuthorizeMachine_kbsync();
bool GetKbsyncToken();
unsigned long GetKbSyncId();
std::string GetLoginText(const std::string& apple_id,const std::string& password);
std::string GetKeyValue(const std::string& key,const std::string h_table);
class GenerateAuthenticateOsGUID
{
public:
explicit GenerateAuthenticateOsGUID(){
char buffer[MAX_PATH] = {0};
DWORD buf_len = MAX_PATH;
GetComputerNameA(buffer,&buf_len);
machine_name_ = buffer;
machine_guid_ = "8EFFF7FD.86E7195C.00000000.39CF53B5.2350EAA0.C3A8E888.7FAFF8CE";
}
std::string machine_name() const{
//test:2015/3/19
//return "WIN-4GI25B3ETJE";
return machine_name_;
}
std::string machine_guid() const{
//test:2015/3/19
//return "8EFFF7FD.86E7195C.00000000.39CF53B5.2350EAA0.C3A8E888.7FAFF8CE";
return machine_guid_;
}
private:
std::string machine_name_;
std::string machine_guid_;
DISALLOW_EVIL_CONSTRUCTORS(GenerateAuthenticateOsGUID);
};
class KbSyncIdParameter
{
public:
static void Initialize();
static DWORD GetKbsyncIDAddress();
static const char* AllPCMd5();
static const char* LocalPCMd5();
};
}
class communicates
{
public:
static communicates* singleton();
void ResetSapSetup(bool x_act_sig);
bool ConsolePrint(const char* file, const char* os_name = NULL, const char* os_guid = NULL);
bool Authenticate(const char* username,const char* password,const char* os_name,const char* os_guid);
bool SendMessage_pendingSongs(const char* os_name, const char* os_guid);
bool SendMessageLookupPurchasesAppIdList();
bool SendMessageLookupPurchasesAppInfo(const char* app_id);
bool SendMessage_buyProduct(const char* product_id, const char* os_name, const char* os_guid, iTunesDownloadInfo* download_info, const int try_count = 1, bool expense = false);
bool SongDownloadDone(const char* product_id, const char* hardware_cookie_guid, iTunesDownloadInfo* download_info);
private:
void SapSessionInitialize();
void SapSetupInitialize(bool x_act_sig_flag);
communicates(void);
~communicates(void);
DISALLOW_EVIL_CONSTRUCTORS(communicates);
};
class CalcCallback
{
public:
CalcCallback();
~CalcCallback();
void Initialize();
bool SapSetupInitialize(const int x_aa_sig,const char* sign_cert,char* buffer,size_t length);
bool SapSetupInitialize2(const int x_aa_sig,const char* sign_cert,char* buffer,size_t length);
bool CalcXAppleActionSignature(char* buffer,size_t length);
bool CalcXAppleActionSignature(const char* x_aa_sig,const size_t length);
bool CalcXAppleActionSignature(const char* x_aa_sig,const size_t x_aa_sig_length,char* buffer,size_t length);
private:
DISALLOW_EVIL_CONSTRUCTORS(CalcCallback);
};
class XAppleMDActionMessage
{
public:
XAppleMDActionMessage(uint32_t dsid_low, uint32_t dsid_high);
~XAppleMDActionMessage();
std::string X_Apple_MD() const;
std::string X_Apple_MD_M() const;
private:
std::string x_apple_md_;
std::string x_apple_md_m_;
};
}
//////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,116 @@
#include "itunes_cookie_interface.h"
namespace win_itunes{
iTunesCookieInterface* iTunesCookieInterface::GetInstance(){
static iTunesCookieInterface* info;
if(!info){
iTunesCookieInterface* new_info = new iTunesCookieInterface();
if(InterlockedCompareExchangePointer(reinterpret_cast<PVOID*>(&info),new_info,NULL)){
delete new_info;
}
}
return info;
}
void iTunesCookieInterface::set_login_cookie_flag(bool flag){
login_cookie_flag_ = flag;
}
bool iTunesCookieInterface::login_cookie_flag() const{
return login_cookie_flag_;
}
void iTunesCookieInterface::set_signup_wizard_cookie_flag(bool flag){
signup_wizard_cookie_flag_ = flag;
}
bool iTunesCookieInterface::signup_wizard_cookie_flag() const{
return signup_wizard_cookie_flag_;
}
void iTunesCookieInterface::set_x_apple_actionsignature(const std::string& text){
x_apple_actionsignature_ = text;
}
std::string iTunesCookieInterface::x_apple_actionsignature() const{
return x_apple_actionsignature_;
}
void iTunesCookieInterface::set_x_apple_store_front(const std::string& text){
x_apple_store_front_ = text;
}
std::string iTunesCookieInterface::x_apple_store_front() const{
return x_apple_store_front_;
}
void iTunesCookieInterface::set_x_dsid(const std::string& dsid){
x_dsid_ = dsid;
}
std::string iTunesCookieInterface::x_dsid() const{
return x_dsid_;
}
void iTunesCookieInterface::set_x_token(const std::string& token){
x_token_ = token;
}
std::string iTunesCookieInterface::x_token() const{
return x_token_;
}
void iTunesCookieInterface::set_credit_display(const std::string& credit){
credit_display_ = credit;
}
std::string iTunesCookieInterface::credit_display() const{
return credit_display_;
}
void iTunesCookieInterface::set_kbsync(const std::string& kbsync_str){
kbsync_ = kbsync_str;
}
std::string iTunesCookieInterface::kbsync() const{
return kbsync_;
}
void iTunesCookieInterface::set_x_apple_md_m(const std::string& k){
x_apple_md_m_ = k;
}
std::string iTunesCookieInterface::x_apple_md_m() const{
return x_apple_md_m_;
}
void iTunesCookieInterface::set_x_apple_md(const std::string& k){
x_apple_md_ = k;
}
std::string iTunesCookieInterface::x_apple_md() const{
return x_apple_md_;
}
void iTunesCookieInterface::set_auth_response_header(const std::string& k){
auth_response_header_ = k;
}
std::string iTunesCookieInterface::auth_response_header() const{
return auth_response_header_;
}
void iTunesCookieInterface::set_buy_product_state(BuyProductStateTable state){
buy_product_state_ = state;
}
iTunesCookieInterface::BuyProductStateTable iTunesCookieInterface::buy_product_state() const{
return buy_product_state_;
}
iTunesCookieInterface::iTunesCookieInterface(void){
set_login_cookie_flag(false);
set_signup_wizard_cookie_flag(false);
set_x_apple_actionsignature("");
set_x_apple_store_front("");
set_x_dsid("");
set_x_token("");
set_credit_display("");
set_kbsync("");
set_x_apple_md_m("");
set_x_apple_md("");
set_auth_response_header("");
set_buy_product_state(iTunesCookieInterface::INIT);
set_x_apple_md_data("");
}
iTunesCookieInterface::~iTunesCookieInterface(void){
set_login_cookie_flag(false);
set_signup_wizard_cookie_flag(false);
set_x_apple_actionsignature("");
set_x_apple_store_front("");
set_x_dsid("");
set_x_token("");
set_credit_display("");
set_kbsync("");
set_x_apple_md_m("");
set_x_apple_md("");
set_auth_response_header("");
set_buy_product_state(iTunesCookieInterface::INIT);
set_x_apple_md_data("");
}
}

View File

@@ -0,0 +1,66 @@
#ifndef WIN_ITUNES_ITUNES_COOKIE_INTERFACE_H_
#define WIN_ITUNES_ITUNES_COOKIE_INTERFACE_H_
//////////////////////////////////////////////////////////////////////////
#include "basictypes.h"
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
class iTunesCookieInterface
{
public:
enum BuyProductStateTable{
INIT,
FIRST_BUY_BEGIN,
FIRST_BUY_END
};
static iTunesCookieInterface* GetInstance();
void set_login_cookie_flag(bool flag);
bool login_cookie_flag() const;
void set_signup_wizard_cookie_flag(bool flag);
bool signup_wizard_cookie_flag() const;
void set_x_apple_actionsignature(const std::string& text);
std::string x_apple_actionsignature() const;
void set_x_apple_store_front(const std::string& text);
std::string x_apple_store_front() const;
void set_x_dsid(const std::string& dsid);
std::string x_dsid() const;
void set_x_token(const std::string& token);
std::string x_token() const;
void set_credit_display(const std::string& credit);
std::string credit_display() const;
void set_kbsync(const std::string& kbsync_str);
std::string kbsync() const;
void set_x_apple_md_m(const std::string& k);
std::string x_apple_md_m() const;
void set_x_apple_md(const std::string& k);
std::string x_apple_md() const;
void set_auth_response_header(const std::string& k);
std::string auth_response_header() const;
void set_buy_product_state(BuyProductStateTable state);
BuyProductStateTable buy_product_state() const;
inline void set_x_apple_md_data(const std::string& buy_k){
x_apple_md_data_ = buy_k;
}
inline std::string x_apple_md_data() const{
return x_apple_md_data_;
}
private:
iTunesCookieInterface(void);
~iTunesCookieInterface(void);
DISALLOW_EVIL_CONSTRUCTORS(iTunesCookieInterface);
bool login_cookie_flag_;
bool signup_wizard_cookie_flag_;
BuyProductStateTable buy_product_state_;
std::string x_apple_actionsignature_;
std::string x_apple_store_front_;
std::string x_dsid_;
std::string x_token_;
std::string credit_display_;
std::string kbsync_;
std::string x_apple_md_m_;
std::string x_apple_md_;
std::string auth_response_header_;
std::string x_apple_md_data_;
};
}
//////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,71 @@
#include "itunes_download_info.h"
namespace win_itunes{
iTunesDownloadInfo* iTunesDownloadInfo::GetInterface(bool free_exit){
static iTunesDownloadInfo* ref_instance;
if(!ref_instance){
iTunesDownloadInfo* new_instance = new iTunesDownloadInfo;
if(InterlockedCompareExchangePointer(reinterpret_cast<PVOID*>(&ref_instance),new_instance,NULL)){
delete new_instance;
}
}
if(free_exit){
delete ref_instance;
ref_instance = NULL;
}
return ref_instance;
}
void iTunesDownloadInfo::DIAllocate(){
DIRelease();
download_key_ = reinterpret_cast<char*>(malloc(kMaxStackBufferLength+256));
memset(download_key_,0,kMaxStackBufferLength+256);
download_url_ = reinterpret_cast<char*>(malloc(kMaxStackBufferLength+256));
memset(download_url_,0,kMaxStackBufferLength+256);
download_id_ = reinterpret_cast<char*>(malloc(kMaxStackBufferLength+256));
memset(download_id_,0,kMaxStackBufferLength+256);
}
void iTunesDownloadInfo::DIRelease(){
if(download_key_){
free(download_key_);
download_key_ = NULL;
}
if(download_url_){
free(download_url_);
download_url_ = NULL;
}
if(download_id_){
free(download_id_);
download_id_ = NULL;
}
}
void iTunesDownloadInfo::set_download_key(const char* key,size_t length){
if(!length||key==NULL){
return;
}
memset(download_key_,0,kMaxStackBufferLength+256);
strncpy(download_key_,key,length);
}
void iTunesDownloadInfo::set_download_url(const char* url,size_t length){
if(!length||url==NULL){
return;
}
memset(download_url_,0,kMaxStackBufferLength+256);
strncpy(download_url_,url,length);
}
void iTunesDownloadInfo::set_download_id(const char* id,size_t length){
if(!length||id==NULL){
return;
}
memset(download_id_,0,kMaxStackBufferLength+256);
strncpy(download_id_,id,length);
}
const char* iTunesDownloadInfo::download_key()const{
return download_key_;
}
const char* iTunesDownloadInfo::download_url()const{
return download_url_;
}
const char* iTunesDownloadInfo::download_id()const{
return download_id_;
}
}

View File

@@ -0,0 +1,34 @@
#ifndef WIN_ITUNES_ITUNES_DOWNLOAD_INFO_H_
#define WIN_ITUNES_ITUNES_DOWNLOAD_INFO_H_
//////////////////////////////////////////////////////////////////////////
#include "basictypes.h"
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
class iTunesDownloadInfo
{
public:
static iTunesDownloadInfo* GetInterface(bool free_exit = false);
virtual void DIAllocate();
virtual void DIRelease();
void set_download_key(const char* key,size_t length);
void set_download_url(const char* url,size_t length);
void set_download_id(const char* id,size_t length);
const char* download_key()const;
const char* download_url()const;
const char* download_id()const;
private:
iTunesDownloadInfo() :download_key_(NULL),
download_url_(NULL), download_id_(NULL){
}
~iTunesDownloadInfo(){
}
char* download_url_;
char* download_key_;
char* download_id_;
DISALLOW_EVIL_CONSTRUCTORS(iTunesDownloadInfo);
};
}
//////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,246 @@
#include "itunes_https.h"
#include <atlconv.h>
#include "itunes_cookie_interface.h"
#include "itunes_https_configure.h"
#include "glog/logging.h"
#include "glog/scoped_ptr.h"
namespace win_itunes{
namespace internal{
const wchar_t* user_agent = L"iTunes/12.2.2 (Windows; Microsoft Windows 8 x64 Business Edition (Build 9200); x64) AppleWebKit/7600.5017.0.22";
void PrintResponseHeader(HINTERNET hRequest){
unsigned long header_length = 0;
WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX,NULL,&header_length,WINHTTP_NO_HEADER_INDEX);
if(GetLastError()==ERROR_INSUFFICIENT_BUFFER||header_length){
scoped_array<wchar_t> buffer(new wchar_t[header_length/sizeof(wchar_t)]);
WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_RAW_HEADERS_CRLF,WINHTTP_HEADER_NAME_BY_INDEX,buffer.get(),&header_length,WINHTTP_NO_HEADER_INDEX);
if(iTunesCookieInterface::GetInstance()->login_cookie_flag()){
wchar_t x_buffer[MAX_PATH] = {0};
unsigned long buffer_length = MAX_PATH;
BOOL upper_flag = WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_CUSTOM,L"X-Set-Apple-Store-Front",x_buffer,&buffer_length,WINHTTP_NO_HEADER_INDEX);
if(!upper_flag||buffer_length==0){
upper_flag = WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_CUSTOM,L"x-set-apple-store-front",x_buffer,&buffer_length,WINHTTP_NO_HEADER_INDEX);
}
if(upper_flag||buffer_length){
USES_CONVERSION;
iTunesCookieInterface::GetInstance()->set_auth_response_header(W2A(buffer.get()));
iTunesCookieInterface::GetInstance()->set_x_apple_store_front(W2A(x_buffer));
iTunesCookieInterface::GetInstance()->set_login_cookie_flag(false);
}
}
else if(iTunesCookieInterface::GetInstance()->signup_wizard_cookie_flag()){
USES_CONVERSION;
iTunesCookieInterface::GetInstance()->set_auth_response_header(W2A(buffer.get()));
iTunesCookieInterface::GetInstance()->set_signup_wizard_cookie_flag(false);
}
else if(iTunesCookieInterface::GetInstance()->buy_product_state()==iTunesCookieInterface::FIRST_BUY_BEGIN){
wchar_t x_buffer[kMaxBufferLength] = {0};
unsigned long buffer_length = kMaxBufferLength;
if(WinHttpQueryHeaders(hRequest,WINHTTP_QUERY_CUSTOM,L"x-apple-md-data",x_buffer,&buffer_length,WINHTTP_NO_HEADER_INDEX)){
USES_CONVERSION;
iTunesCookieInterface::GetInstance()->set_x_apple_md_data(W2A(x_buffer));
}
iTunesCookieInterface::GetInstance()->set_buy_product_state(iTunesCookieInterface::FIRST_BUY_END);
}
#ifdef __DEBUG
LOG(INFO)<<buffer.get()<<std::endl;
#endif
}
}
void PrintWinHttpError(HINTERNET hRequest) {
DWORD dwError = 0;
DWORD dwSize = sizeof(dwError);
// <20><>ȡ<EFBFBD><C8A1>չ<EFBFBD><D5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
if (WinHttpQueryOption(hRequest, WINHTTP_OPTION_EXTENDED_ERROR, &dwError, &dwSize)) {
std::cerr << "WinHTTP Extended Error: " << dwError << std::endl;
} else {
std::cerr << "WinHttpQueryOption failed: " << GetLastError() << std::endl;
}
}
std::string ReadHTTPS(const wchar_t* domain,const wchar_t* path,const wchar_t* header,iTunesExtHeader options,const wchar_t* referer,const char* port) {
HINTERNET hOpen = 0;
HINTERNET hConnect = 0;
HINTERNET hRequest = 0;
IStream *stream = NULL;
std::string message = "";
for(;;){
unsigned long option_flag = SECURITY_FLAG_IGNORE_CERT_CN_INVALID|SECURITY_FLAG_IGNORE_CERT_DATE_INVALID|SECURITY_FLAG_IGNORE_UNKNOWN_CA;
hOpen = WinHttpOpen(user_agent,WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0);
if(!hOpen){
break;
}
hConnect = WinHttpConnect(hOpen,domain,port==NULL?INTERNET_DEFAULT_HTTPS_PORT:atoi(port),0);
if(!hConnect){
break;
}
const wchar_t* types[50] = {{L"*/*"/*"text/html, application/xhtml+xml, application/xml;q=0.9, * / *;q=0.8"*/},{0}};
hRequest = WinHttpOpenRequest(hConnect,L"GET",path,NULL,referer,types,(port==NULL||atoi(port)!=80)?WINHTTP_FLAG_SECURE:WINHTTP_FLAG_BYPASS_PROXY_CACHE);
if(!hRequest){
break;
}
ConfigureProxy(hRequest);
if (port == NULL || atoi(port) != 80) {
ConfigureSSL(hRequest);
WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, (LPVOID)(&option_flag), sizeof(unsigned long));
}
std::wstring some_header(L"Cache-Control: no-cache\r\nConnection: Keep-Alive\r\nAccept-Language: zh-cn, zh;q=0.75, en-us;q=0.50, en;q=0.25\r\n");
if (options == internal::apple_authenticate) {
some_header.append(L"Content-Type: application/x-apple-plist\r\n");
}
if (header) {
some_header.append(header);
}
if(!WinHttpSendRequest(hRequest,some_header.c_str(),some_header.length(),WINHTTP_NO_REQUEST_DATA,0,0,WINHTTP_FLAG_SECURE)){
int err = GetLastError();
cout << "GetLastError() = " << err << endl;
break;
}
if(!WinHttpReceiveResponse(hRequest,0)){
break;
}
DWORD cch = 1;
internal::PrintResponseHeader(hRequest);
if(CreateStreamOnHGlobal(0, TRUE, &stream)){
break;
}
char *p = new char[4096];
if(!p){
break;
}
DWORD dwReceivedTotal = 0;
while(WinHttpQueryDataAvailable(hRequest, &cch) && cch){
if(cch > 4096){
cch = 4096;
}
dwReceivedTotal += cch;
WinHttpReadData(hRequest,p,cch,&cch);
stream->Write(p,cch,NULL);
}
delete[] p;
p = NULL;
stream->Write(&p, 1, NULL);
HGLOBAL hgl;
if(GetHGlobalFromStream(stream, &hgl)){
break;
}
p = reinterpret_cast<char*>(GlobalLock(hgl));
if(!p){
break;
}
message.resize(0);
message.append(p,dwReceivedTotal);
GlobalUnlock(hgl);
break;
}
if(stream){
stream->Release();
}
if(hRequest){
WinHttpCloseHandle(hRequest);
}
if(hConnect){
WinHttpCloseHandle(hConnect);
}
if(hOpen){
WinHttpCloseHandle(hOpen);
}
return message;
}
std::string SendHTTPS(const wchar_t* domain,const wchar_t* path,const void* src,const size_t length,iTunesExtHeader options,const wchar_t* header,const wchar_t* referer,const char* post){
HINTERNET hOpen = 0;
HINTERNET hConnect = 0;
HINTERNET hRequest = 0;
IStream *stream = NULL;
std::string message = "";
for(;;){
unsigned long option_flag = SECURITY_FLAG_IGNORE_CERT_CN_INVALID|SECURITY_FLAG_IGNORE_CERT_DATE_INVALID|SECURITY_FLAG_IGNORE_UNKNOWN_CA;
unsigned long write_length = 0;
hOpen = WinHttpOpen(user_agent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,WINHTTP_NO_PROXY_NAME,WINHTTP_NO_PROXY_BYPASS,0);
if(!hOpen){
break;
}
hConnect = WinHttpConnect(hOpen,domain,post==NULL?INTERNET_DEFAULT_HTTPS_PORT:atoi(post),0);
if(!hConnect){
break;
}
const wchar_t* types[50] = {{L"text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8"},{0}};
hRequest = WinHttpOpenRequest(hConnect,L"POST",path,NULL,referer,types,WINHTTP_FLAG_SECURE);
if(!hRequest){
break;
}
if(header){
if(!WinHttpAddRequestHeaders(hRequest,header,wcslen(header),WINHTTP_ADDREQ_FLAG_ADD)){
break;
}
}
ConfigureProxy(hRequest);
ConfigureSSL(hRequest);
// if(!WinHttpSetTimeouts(hRequest,20000,20000,20000,20000)){
// break;
// }
WinHttpSetOption(hRequest,WINHTTP_OPTION_SECURITY_FLAGS,(LPVOID)(&option_flag),sizeof(unsigned long));
std::wstring request_header = L"Accept-Language: zh-cn, zh;q=0.75, en-us;q=0.50, en;q=0.25\r\nConnection: Keep-Alive\r\nCache-Control: no-cache\r\n";
if(options==internal::apple_authenticate){
request_header.append(L"Content-Type: application/x-apple-plist\r\n");
}
if(!WinHttpSendRequest(hRequest,request_header.c_str(),request_header.length(),(LPVOID)src,length,length,WINHTTP_FLAG_SECURE)){
break;
}
if(!WinHttpReceiveResponse(hRequest,0)){
break;
}
internal::PrintResponseHeader(hRequest);
if(CreateStreamOnHGlobal(0,TRUE,&stream)){
break;
}
char *p = new char[4096];
if(!p){
break;
}
unsigned long dwReceivedTotal = 0;
for(unsigned long cch = 4096;WinHttpReadData(hRequest,p,cch,&cch) && cch;cch = 4096){
dwReceivedTotal += cch;
stream->Write(p,cch,NULL);
}
delete[] p;
p = NULL;
stream->Write(&p, 1, NULL);
HGLOBAL hgl;
if(GetHGlobalFromStream(stream, &hgl)){
break;
}
p = reinterpret_cast<char*>(GlobalLock(hgl));
if(!p){
break;
}
message.resize(0);
message.append(p,dwReceivedTotal);
GlobalUnlock(hgl);
break;
}
if(stream){
stream->Release();
}
if(hRequest){
WinHttpCloseHandle(hRequest);
hRequest = NULL;
}
if(hConnect){
WinHttpCloseHandle(hConnect);
hConnect = NULL;
}
if(hOpen){
WinHttpCloseHandle(hOpen);
hOpen = NULL;
}
return message;
}
}
}

View File

@@ -0,0 +1,19 @@
#ifndef WIN_ITUNES_ITUNES_HTTPS_H_
#define WIN_ITUNES_ITUNES_HTTPS_H_
//////////////////////////////////////////////////////////////////////////
#include "basictypes.h"
//#include "passport/itunes_client_interface.h"
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
namespace internal{
enum iTunesExtHeader{
apple_itunes = -1,
apple_authenticate,
apple_signSapSetup
};
std::string ReadHTTPS(const wchar_t* domain,const wchar_t* path,const wchar_t* header,iTunesExtHeader options = apple_itunes,const wchar_t* referer=NULL,const char* port=NULL);
std::string SendHTTPS(const wchar_t* domain,const wchar_t* path,const void* src,const size_t length,iTunesExtHeader options,const wchar_t* header,const wchar_t* referer=NULL,const char* post = NULL);
}
}
//////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,104 @@
#include "itunes_https_configure.h"
namespace win_itunes{
namespace internal{
void FreeConfig(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* config) {
if (config->lpszAutoConfigUrl)
GlobalFree(config->lpszAutoConfigUrl);
if (config->lpszProxy)
GlobalFree(config->lpszProxy);
if (config->lpszProxyBypass)
GlobalFree(config->lpszProxyBypass);
}
void FreeInfo(WINHTTP_PROXY_INFO* info) {
if (info->lpszProxy)
GlobalFree(info->lpszProxy);
if (info->lpszProxyBypass)
GlobalFree(info->lpszProxyBypass);
}
bool ConfigureSSL(HINTERNET internet){
DWORD protocols = 0;
protocols |= WINHTTP_FLAG_SECURE_PROTOCOL_SSL2;
protocols |= WINHTTP_FLAG_SECURE_PROTOCOL_SSL3;
protocols |= WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
protocols |= WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1;
protocols |= WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
BOOL rv = WinHttpSetOption(internet, WINHTTP_OPTION_SECURE_PROTOCOLS,&protocols,sizeof(protocols));
return (rv==TRUE);
}
bool ApplyProxy(HINTERNET internet,const wchar_t* proxy_str,bool is_direct){
WINHTTP_PROXY_INFO pi;
if(is_direct){
pi.dwAccessType = WINHTTP_ACCESS_TYPE_NO_PROXY;
pi.lpszProxy = WINHTTP_NO_PROXY_NAME;
pi.lpszProxyBypass = WINHTTP_NO_PROXY_BYPASS;
}
else{
pi.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
pi.lpszProxy = const_cast<LPWSTR>(proxy_str);
pi.lpszProxyBypass = WINHTTP_NO_PROXY_BYPASS;
}
BOOL rv = WinHttpSetOption(internet,WINHTTP_OPTION_PROXY,&pi,sizeof(pi));
return (rv==TRUE);
}
bool ConfigureProxy(HINTERNET internet){
WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_config = {0};
if(!WinHttpGetIEProxyConfigForCurrentUser(&ie_config)){
return false;
}
WINHTTP_AUTOPROXY_OPTIONS options = {0};
options.fAutoLogonIfChallenged = TRUE;
if(ie_config.fAutoDetect){
options.lpszAutoConfigUrl = ie_config.lpszAutoConfigUrl;
options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
}
else{
options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP|WINHTTP_AUTO_DETECT_TYPE_DNS_A;
}
std::wstring query_url(L"http://www.baidu.com");
WINHTTP_PROXY_INFO info = {0};
BOOL rv = WinHttpGetProxyForUrl(internet,query_url.c_str(),&options,&info);
WINHTTP_PROXY_INFO pi;
switch(info.dwAccessType){
case WINHTTP_ACCESS_TYPE_NO_PROXY:
ApplyProxy(internet,NULL,TRUE);
break;
case WINHTTP_ACCESS_TYPE_NAMED_PROXY:
ApplyProxy(internet,ie_config.lpszProxy,FALSE);
break;
default:
pi.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
pi.lpszProxy = ie_config.lpszProxy;
pi.lpszProxyBypass = ie_config.lpszProxyBypass;
rv = WinHttpSetOption(internet,WINHTTP_OPTION_PROXY,&pi,sizeof(pi));
break;
}
FreeConfig(&ie_config);
FreeInfo(&info);
return (rv==TRUE);
}
// bool ConfigureProxy(HINTERNET request)
// {
// WINHTTP_PROXY_INFO proxyInfo = {0};
// proxyInfo.lpszProxy = new WCHAR[PROXY_STR_MAX_LEN];
// proxyInfo.lpszProxyBypass = new WCHAR[PROXY_STR_MAX_LEN];
//
// proxyInfo.dwAccessType = proxy.dwAccessType;
// swprintf_s(proxyInfo.lpszProxy, PROXY_STR_MAX_LEN, proxy.proxyStr);
// swprintf_s(proxyInfo.lpszProxyBypass, PROXY_STR_MAX_LEN, proxy.proxyPassBy); // *.local;<local>
//
// BOOL rv = WinHttpSetOption(request,WINHTTP_OPTION_PROXY,&proxyInfo,sizeof(proxyInfo));
// delete[] proxyInfo.lpszProxy;
// delete[] proxyInfo.lpszProxyBypass;
//
// //DWORD dw = sizeof(proxyInfo);
// //WinHttpQueryOption(request, WINHTTP_OPTION_PROXY, &proxyInfo, &dw);
// return rv;
// }
}
}

View File

@@ -0,0 +1,16 @@
#ifndef PASSPORT_ITUNES_HTTPS_CONFIGURE_H_
#define PASSPORT_ITUNES_HTTPS_CONFIGURE_H_
//////////////////////////////////////////////////////////////////////////
#include "basictypes.h"
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
namespace internal{
void FreeConfig(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG* config);
void FreeInfo(WINHTTP_PROXY_INFO* info);
bool ConfigureSSL(HINTERNET internet);
bool ApplyProxy(HINTERNET internet,const wchar_t* proxy_str,bool is_direct);
bool ConfigureProxy(HINTERNET internet);
bool ConfigureProxy(HINTERNET request);
}
}
#endif

View File

@@ -0,0 +1,62 @@
#ifndef WIN_ITUNES_ITUNES_INTERNAL_INTERFACE_H_
#define WIN_ITUNES_ITUNES_INTERNAL_INTERFACE_H_
//////////////////////////////////////////////////////////////////////////
#include "basictypes.h"
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
class iTunesInternalInterface{
public:
static iTunesInternalInterface* Instance(){
static iTunesInternalInterface* info;
if(!info){
iTunesInternalInterface* new_info = new iTunesInternalInterface;
if(InterlockedCompareExchangePointer(reinterpret_cast<PVOID*>(&info),new_info,NULL)){
delete new_info;
}
}
return info;
}
int (__cdecl *lpfnKbsync)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnCigHash)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnKbsyncID)(unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnWriteSIDD)(unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnWriteSIDB)(unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnDeAuthSIDB)(unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnGenerateAFSyncRS)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnVerifyAFSyncRQ)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnSetAFSyncRQ)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnCalcUnkP1)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnPreAuthByDSID)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnSapInit)(void);
int (__cdecl *lpfnSapGetP1)(unsigned long, unsigned long);
int (__cdecl *lpfnSapCalcBuffer)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnSapGetAS)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnSapGetASFD)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnSapGetASFD_a)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnGetCltDat)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnTranSetInf)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnUpdCDID)(unsigned long);
int (__cdecl *lpfnGetMD)(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnInitHost)(unsigned long, unsigned long, unsigned long, unsigned long);
int (__cdecl *lpfnEstablishKey)(unsigned long, unsigned long, unsigned long);
unsigned long kb_seed;
private:
iTunesInternalInterface(){}
~iTunesInternalInterface(){}
DISALLOW_EVIL_CONSTRUCTORS(iTunesInternalInterface);
};
template <typename T>
unsigned long ToDword(const T* k){
return reinterpret_cast<unsigned long>(k);
}
template <typename T>
unsigned long ToDword(T* k){
return reinterpret_cast<unsigned long>(k);
}
template <typename T>
unsigned long ToDword(const T k){
return reinterpret_cast<unsigned long>(k);
}
}
//////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,113 @@
#include "itunes_module.h"
#include <Windows.h>
#include <shlobj.h>
#include <Shlwapi.h>
#pragma comment(lib,"shell32.lib")
#include <exception>
#include "itunes_native_interface.h"
namespace win_itunes{
iTunesModule::iTunesModule(void){
set_core_foundation_dll(L"");
set_air_traffic_host_dll(L"");
set_asmapi_interface_dll(L"");
set_itunes_mobile_device_dll(L"");
set_mobile_device_dll(L"");
AddEnvironmentVariable(iTunesWinPath());
iTunesPathInit();
}
iTunesModule::~iTunesModule(void){
set_core_foundation_dll(L"");
set_air_traffic_host_dll(L"");
set_asmapi_interface_dll(L"");
set_itunes_mobile_device_dll(L"");
set_mobile_device_dll(L"");
}
std::wstring iTunesModule::iTunesDll(const std::wstring& dll_name){
std::wstring itunes = (iTunesWinPath() + dll_name);
if (!PathFileExistsW(itunes.c_str())){
itunes = internal::GetDirectory().append(L"itunes.dll");
}
return itunes;
}
std::wstring iTunesModule::iTunesSCInfo(){
return (GetSpecialPath(CSIDL_COMMON_APPDATA, L"\\Apple Computer\\iTunes\\SC Info"));
}
void iTunesModule::iTunesPathInit(){
set_core_foundation_dll(iTunesFrameworkSupport(L"CoreFoundation.dll", true));
AddEnvironmentVariable(core_foundation_dll());
set_air_traffic_host_dll(iTunesGetSharedDll(L"AirTrafficHostDLL"));
AddEnvironmentVariable(air_traffic_host_dll());
set_asmapi_interface_dll(iTunesGetSharedDll(L"ASMapiInterfaceDLL"));
AddEnvironmentVariable(asmapi_interface_dll());
set_itunes_mobile_device_dll(iTunesGetSharedDll(L"iTunesMobileDeviceDLL"));
AddEnvironmentVariable(itunes_mobile_device_dll());
set_mobile_device_dll(iTunesGetSharedDll(L"MobileDeviceDLL"));
AddEnvironmentVariable(mobile_device_dll());
}
void iTunesModule::AddEnvironmentVariable(const std::wstring& path){
wchar_t env_path[4096] = { 0 };
GetEnvironmentVariableW(L"PATH", env_path, 4095);
std::wstring new_env_path = (std::wstring(env_path) + std::wstring(L";")) + path;
size_t posiltion = new_env_path.find_last_of('\\');
if (posiltion != std::wstring::npos){
new_env_path[posiltion] = 0;
}
SetEnvironmentVariable(L"PATH", new_env_path.c_str());
}
std::wstring iTunesModule::iTunesGetSharedDll(const std::wstring dll_name){
void* hSetting = NULL;
unsigned long length = 0;
wchar_t* path = new wchar_t[MAX_PATH*sizeof(wchar_t)];
if (path == NULL){
return L"";
}
if (::RegCreateKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Apple Inc.\\Apple Mobile Device Support\\Shared", reinterpret_cast<PHKEY>(&hSetting)) != ERROR_SUCCESS){
return L"";
}
if (::RegQueryValueExW(reinterpret_cast<HKEY>(hSetting), dll_name.c_str(), NULL, NULL, NULL, &length) != ERROR_SUCCESS){
return L"";
}
::RegQueryValueEx(reinterpret_cast<HKEY>(hSetting), dll_name.c_str(), NULL, NULL, (LPBYTE)path, &length);
::RegCloseKey(reinterpret_cast<HKEY>(hSetting));
std::wstring shared_dll(path);
delete[] path;
return shared_dll;
}
std::wstring iTunesModule::iTunesFrameworkSupport(const std::wstring dll_name, bool env_able){
void* hSetting = NULL;
unsigned long length = 0;
wchar_t* pCoreFoundationPath = new wchar_t[MAX_PATH*sizeof(wchar_t)];
if (pCoreFoundationPath == NULL){
return L"";
}
if (::RegCreateKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Apple Inc.\\Apple Application Support", reinterpret_cast<PHKEY>(&hSetting)) != ERROR_SUCCESS){
return L"";
}
if (::RegQueryValueExW(reinterpret_cast<HKEY>(hSetting), L"InstallDir", NULL, NULL, NULL, &length) != ERROR_SUCCESS){
return L"";
}
::RegQueryValueExW(reinterpret_cast<HKEY>(hSetting), L"InstallDir", NULL, NULL, (LPBYTE)pCoreFoundationPath, &length);
::RegCloseKey(reinterpret_cast<HKEY>(hSetting));
if (env_able){
AddEnvironmentVariable(pCoreFoundationPath);
}
if (pCoreFoundationPath[wcslen(pCoreFoundationPath) - 1] != '\\'){
wcscat(pCoreFoundationPath, L"\\");
}
wcscat(pCoreFoundationPath, dll_name.c_str());
std::wstring support_dll(pCoreFoundationPath);
delete[] pCoreFoundationPath;
return support_dll;
}
std::wstring iTunesModule::iTunesWinPath(){
wchar_t path[MAX_PATH] = { 0 };
SHGetSpecialFolderPathW(NULL, path, CSIDL_PROGRAM_FILES, FALSE);
return (std::wstring(path) + std::wstring(L"\\iTunes\\"));
}
std::wstring iTunesModule::GetSpecialPath(const unsigned long& type_path, const std::wstring& name){
wchar_t path[MAX_PATH] = { 0 };
SHGetSpecialFolderPathW(NULL, path, type_path, FALSE);
return (std::wstring(path) + name);
}
}

View File

@@ -0,0 +1,69 @@
#ifndef WIN_ITUNES_ITUNES_MODULE_H_
#define WIN_ITUNES_ITUNES_MODULE_H_
//////////////////////////////////////////////////////////////////////////
#include <string>
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
class iTunesModule
{
public:
iTunesModule(void);
~iTunesModule(void);
std::wstring iTunesDll(const std::wstring& dll_name);
std::wstring iTunesSCInfo();
std::wstring core_foundation_dll() const{
const std::wstring data = core_foundation_dll_;
return data;
}
std::wstring air_traffic_host_dll() const{
const std::wstring data = air_traffic_host_dll_;
return data;
}
std::wstring asmapi_interface_dll() const{
const std::wstring data = asmapi_interface_dll_;
return data;
}
std::wstring itunes_mobile_device_dll() const{
const std::wstring data = itunes_mobile_device_dll_;
return data;
}
std::wstring mobile_device_dll() const{
const std::wstring data = mobile_device_dll_;
return data;
}
private:
void iTunesPathInit();
void AddEnvironmentVariable(const std::wstring& path);
std::wstring iTunesGetSharedDll(const std::wstring dll_name);
std::wstring iTunesFrameworkSupport(const std::wstring dll_name, bool env_able);
std::wstring iTunesWinPath();
std::wstring GetSpecialPath(const unsigned long& type_path, const std::wstring& name);
void set_core_foundation_dll(std::wstring path){
core_foundation_dll_.resize(0);
core_foundation_dll_ = path;
}
void set_air_traffic_host_dll(std::wstring path){
air_traffic_host_dll_.resize(0);
air_traffic_host_dll_ = path;
}
void set_asmapi_interface_dll(std::wstring path){
asmapi_interface_dll_.resize(0);
asmapi_interface_dll_ = path;
}
void set_itunes_mobile_device_dll(std::wstring path){
itunes_mobile_device_dll_.resize(0);
itunes_mobile_device_dll_ = path;
}
void set_mobile_device_dll(std::wstring path){
mobile_device_dll_.resize(0);
mobile_device_dll_ = path;
}
std::wstring core_foundation_dll_;
std::wstring air_traffic_host_dll_;
std::wstring asmapi_interface_dll_;
std::wstring itunes_mobile_device_dll_;
std::wstring mobile_device_dll_;
};
}
//////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,27 @@
#include "itunes_module_state.h"
#include <Windows.h>
#include "itunes_module.h"
namespace win_itunes{
bool iTunesModuleState::iTunesIsInstalled(){
iTunesModule module;
if (GetModuleHandleW(L"iTunes.dll") != NULL){
return true;
}
return (LoadLibraryW(module.iTunesDll(L"iTunes.dll").c_str()) != NULL);
}
bool iTunesModuleState::AppleApplicationSupportIsInstalled(){
iTunesModule module;
if (GetModuleHandleW(L"CoreFoundation.dll") != NULL){
return true;
}
return (LoadLibraryW(module.core_foundation_dll().c_str()) != NULL);
}
bool iTunesModuleState::AppleMobileDeviceSupportIsInstalled(){
iTunesModule module;
if (GetModuleHandleW(L"iTunesMobileDevice.dll") != NULL){
return true;
}
return (LoadLibraryW(module.itunes_mobile_device_dll().c_str()) != NULL);
}
}

View File

@@ -0,0 +1,16 @@
#ifndef WIN_ITUNES_ITUNES_MODULE_STATE_H_
#define WIN_ITUNES_ITUNES_MODULE_STATE_H_
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
class iTunesModuleState
{
public:
iTunesModuleState(){}
~iTunesModuleState(){}
bool iTunesIsInstalled();
bool AppleApplicationSupportIsInstalled();
bool AppleMobileDeviceSupportIsInstalled();
};
}
//////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,350 @@
#include <windows.h>
#include <iostream>
#include <ImageHlp.h>
#pragma comment(lib,"Imagehlp.lib")
#pragma comment(lib,"Version.lib")
#include "itunes_native_interface.h"
#include "itunes_internal_interface.h"
#include "itunes_module.h"
#include "strings.h"
#include "utils/encoding.h"
using namespace ytpp::sys_core;
#include "authenticate/confidentialData.h"
namespace win_itunes{
namespace internal{
void AddEnvironmentVariable(const std::wstring& path){
wchar_t env_path[4096] = {0};
GetEnvironmentVariableW(L"PATH",env_path,4095);
std::wstring new_env_path = (std::wstring(env_path) + std::wstring(L";")) + path;
size_t posiltion = new_env_path.find_last_of('\\');
if(posiltion!=std::wstring::npos){
new_env_path[posiltion] = 0;
}
SetEnvironmentVariableW(L"PATH",new_env_path.c_str());
}
std::wstring GetSoftwareReleaseVersion(const wchar_t* full_path){
VS_FIXEDFILEINFO *pVerInfo = NULL;
DWORD dwTemp, dwSize;
BYTE *pData = NULL;
UINT uLen;
dwSize = GetFileVersionInfoSizeW(full_path, &dwTemp);
if(dwSize == 0){
return L"";
}
pData = new BYTE[dwSize+1];
if(pData == NULL){
return L"";
}
if(!GetFileVersionInfoW(full_path, 0, dwSize, pData)){
delete[] pData;
return L"";
}
if(!VerQueryValueW(pData,L"\\",(void **)&pVerInfo,&uLen)){
delete[] pData;
return L"";
}
DWORD verMS = pVerInfo->dwFileVersionMS;
DWORD verLS = pVerInfo->dwFileVersionLS;
DWORD major = HIWORD(verMS);
DWORD minor = LOWORD(verMS);
DWORD build = HIWORD(verLS);
DWORD revision = LOWORD(verLS);
delete[] pData;
wchar_t version[1024] = {0};
_snwprintf(version,1024,L"%d.%d.%d.%d",major,minor,build,revision);
return version;
}
std::wstring GetAppleMobileDeviceSupportDll(const std::wstring dll_name){
void* hSetting = NULL;
unsigned long length = 0;
wchar_t* path = new wchar_t[MAX_PATH*sizeof(wchar_t)];
if(path==NULL){
return L"";
}
if(::RegCreateKeyW(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Apple Inc.\\Apple Mobile Device Support\\Shared",reinterpret_cast<PHKEY>(&hSetting))!=ERROR_SUCCESS){
return L"";
}
if(::RegQueryValueExW(reinterpret_cast<HKEY>(hSetting),dll_name.c_str(), NULL, NULL, NULL, &length)!=ERROR_SUCCESS){
return L"";
}
::RegQueryValueExW(reinterpret_cast<HKEY>(hSetting),dll_name.c_str(), NULL, NULL, (LPBYTE)path,&length);
::RegCloseKey(reinterpret_cast<HKEY>(hSetting));
std::wstring shared_dll(path);
delete[] path;
return shared_dll;
}
std::wstring GetAppleApplicationSupportDll(const std::wstring dll_name){
void* hSetting = NULL;
unsigned long length = 0;
wchar_t* pCoreFoundationPath = new wchar_t[MAX_PATH*sizeof(wchar_t)];
if(pCoreFoundationPath==NULL){
return L"";
}
if(::RegCreateKeyW(HKEY_LOCAL_MACHINE,L"SOFTWARE\\Apple Inc.\\Apple Application Support",reinterpret_cast<PHKEY>(&hSetting))!=ERROR_SUCCESS){
return L"";
}
if(::RegQueryValueExW(reinterpret_cast<HKEY>(hSetting),L"InstallDir", NULL, NULL, NULL, &length)!=ERROR_SUCCESS){
return L"";
}
::RegQueryValueExW(reinterpret_cast<HKEY>(hSetting),L"InstallDir", NULL, NULL, (LPBYTE)pCoreFoundationPath, &length);
::RegCloseKey(reinterpret_cast<HKEY>(hSetting));
if(pCoreFoundationPath[wcslen(pCoreFoundationPath)-1] != '\\'){
wcscat(pCoreFoundationPath,L"\\");
}
if(dll_name.length()>0){
wcscat(pCoreFoundationPath,dll_name.c_str());
}
std::wstring support_dll(pCoreFoundationPath);
delete[] pCoreFoundationPath;
return support_dll;
}
std::wstring GetDirectory(){
wchar_t buffer[MAX_PATH] = {0};
wchar_t drive[_MAX_DRIVE] = {0};
wchar_t dir[_MAX_DIR] = {0};
wchar_t fname[_MAX_FNAME] = {0};
wchar_t ext[_MAX_EXT] = {0};
GetModuleFileNameW(NULL,buffer,MAX_PATH);
_wsplitpath_s(buffer,drive,_MAX_DRIVE,dir,_MAX_DIR,fname,_MAX_FNAME,ext,_MAX_EXT);
return (std::wstring(std::wstring(drive)+std::wstring(dir)));
}
std::wstring GetITunesInstallDll(const std::wstring dll_name){
const std::wstring dll = GetDirectory().append(L"itunes.dll");
//date:2015/09/06
if(PathFileExistsW(dll.c_str()))
return GetDirectory().append(dll_name);//load current directory itunes.dll
wchar_t path[MAX_PATH] = { 0 };
SHGetSpecialFolderPathW(NULL, path, CSIDL_PROGRAM_FILES, FALSE);
return (std::wstring(path) + std::wstring(L"\\iTunes\\") + dll_name);
}
}
iTunesNativeInterface* iTunesNativeInterface::GetInstance(){
static iTunesNativeInterface* info;
if(!info){
iTunesNativeInterface* new_info = new iTunesNativeInterface();
if(InterlockedCompareExchangePointer(reinterpret_cast<PVOID*>(&info),new_info,NULL)){
delete new_info;
}
const std::wstring corefp_dll = internal::GetDirectory().append(L"CoreFP.dll");
//cout << "corefp_dll = " << encoding_wstring_to_ANSI(corefp_dll.c_str()) << endl;
const std::wstring itunesmobiledevice_dll = internal::GetDirectory().append(L"iTunesMobileDevice.dll");
if (PathFileExistsW(corefp_dll.c_str()))
new_info->HKLMCustomizeModule(CustomizeModule::kCoreFP, corefp_dll.c_str());
if (PathFileExistsW(itunesmobiledevice_dll.c_str()))
new_info->HKLMCustomizeModule(CustomizeModule::kiTunesMobileDeviceDLL, itunesmobiledevice_dll.c_str());
}
return info;
}
iTunesNativeInterface::iTunesNativeInterface(void){
internal::AddEnvironmentVariable(internal::GetAppleApplicationSupportDll(L""));
internal::AddEnvironmentVariable(internal::GetITunesInstallDll(L""));
std::wstring directory = internal::GetAppleMobileDeviceSupportDll(L"AirTrafficHostDLL");
if(directory.length()>0){
directory[directory.find_last_of(L"\\")+1] = 0;
internal::AddEnvironmentVariable(directory);
}
}
iTunesNativeInterface::~iTunesNativeInterface(void){
}
bool iTunesNativeInterface::HKLMCustomizeModule(const CustomizeModule& customize_module, const wchar_t* module_name){
std::wstring sub_key = L"";
std::wstring sub_key_name = L"";
if (customize_module == CustomizeModule::kCoreFP){
/* <20><><EFBFBD><EFBFBD>ע<EFBFBD><EFBFBD><E2A3AC><EFBFBD>Ѿ<EFBFBD><D1BE><EFBFBD>init_dll<6C>г<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>iTunes.dll<6C><6C>ע<EFBFBD><D7A2><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2>ðѹ<C3B0><D1B9>ˣ<EFBFBD>ֱ<EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD> */
return true;
sub_key = L"SOFTWARE\\Wow6432Node\\Apple Inc.\\CoreFP";
sub_key_name = L"LibraryPath";
}
else if (customize_module == CustomizeModule::kiTunesMobileDeviceDLL){
sub_key = L"SOFTWARE\\Wow6432Node\\Apple Inc.\\Apple Mobile Device Support\\Shared";
sub_key_name = L"iTunesMobileDeviceDLL";
}
else{
return true;
}
HKEY h_setting = NULL;
bool is_success = true;
if (::RegCreateKeyW(HKEY_LOCAL_MACHINE, sub_key.c_str(), reinterpret_cast<PHKEY>(&h_setting)) != ERROR_SUCCESS)
return is_success;
if (::RegSetValueExW(h_setting,
sub_key_name.c_str(),
0,
REG_SZ,
(const BYTE*)module_name,
wcslen(module_name)*sizeof(wchar_t)) == ERROR_SUCCESS)
is_success = false;
RegCloseKey(h_setting);
return is_success;
}
void iTunesNativeInterface::Init(){
unsigned long Kbsync = ConfidentialData::Instance()->Kbsync;
unsigned long CigHash = ConfidentialData::Instance()->CigHash;
unsigned long KbsyncID = ConfidentialData::Instance()->KbsyncID;
unsigned long WriteSIDD = ConfidentialData::Instance()->WriteSIDD;
unsigned long WriteSIDB = ConfidentialData::Instance()->WriteSIDB;
unsigned long DeAuthSIDB = ConfidentialData::Instance()->DeAuthSIDB;
unsigned long CalcUnkP1 = ConfidentialData::Instance()->CalcUnkP1;
unsigned long SetAFSyncRQ = ConfidentialData::Instance()->SetAFSyncRQ;
unsigned long PreAuthByDSID = ConfidentialData::Instance()->PreAuthByDSID;
unsigned long VerifyAFSyncRQ = ConfidentialData::Instance()->VerifyAFSyncRQ;
unsigned long GenerateAFSyncRS = ConfidentialData::Instance()->GenerateAFSyncRS;
unsigned long GetCltDat = ConfidentialData::Instance()->GetCltDat;
unsigned long TranSetInf = ConfidentialData::Instance()->TranSetInf;
unsigned long UpdCDID = ConfidentialData::Instance()->UpdCDID;
unsigned long GetMD = ConfidentialData::Instance()->GetMD;
unsigned long SapInit = ConfidentialData::Instance()->SapInit;
unsigned long SapGetP1 = ConfidentialData::Instance()->SapGetP1;
unsigned long SapCalcBuffer = ConfidentialData::Instance()->SapCalcBuffer;
unsigned long SapGetAS = ConfidentialData::Instance()->SapGetAS;
unsigned long SapGetASFD = ConfidentialData::Instance()->SapGetASFD;
unsigned long SapGetASFD_a = ConfidentialData::Instance()->SapGetASFD_a;
//Kbsync = 0x2BC50u;
//KbsyncID = 0x25370u;
//CigHash = 0x46890u;
//WriteSIDD = 0x73490u;
//WriteSIDB = 0x302E0u;
//DeAuthSIDB = 0x63EA0u;
//CalcUnkP1 = 0x6C710u;
//SetAFSyncRQ = 0x60A20u;
//PreAuthByDSID = 0x57160u;
//VerifyAFSyncRQ = 0x284C0u;
//GenerateAFSyncRS = 0x294F0u;
//GetCltDat = 0xB0970u;
//TranSetInf = 0xB1600u;
//UpdCDID = 0;
//GetMD = 0xB1C90u;
//SapInit = 0x20790u;
//SapGetP1 = 0x5DA20u;
//SapCalcBuffer = 0x6D850u;
//SapGetAS = 0x887E0u;
//SapGetASFD = 0x42AA0u;
//SapGetASFD_a = 0xE770u;
//{
// "Kbsync": 179280,
// "KbsyncID" : 152432,
// "CigHash" : 288912,
// "WriteSIDD" : 472208,
// "WriteSIDB" : 197344,
// "DeAuthSIDB" : 409248,
// "CalcUnkP1" : 444176,
// "SetAFSyncRQ" : 395808,
// "PreAuthByDSID" : 356704,
// "VerifyAFSyncRQ" : 165056,
// "GenerateAFSyncRS" : 169200,
// "GetCltDat" : 723312,
// "TranSetInf" : 726528,
// "UpdCDID" : 0,
// "GetMD" : 728208,
// "SapInit" : 133008,
// "SapGetP1" : 383520,
// "SapCalcBuffer" : 448592,
// "SapGetAS" : 559072,
// "SapGetASFD" : 273056,
// "SapGetASFD_a" : 59248
//}
Loads(); // ????
char temp_path_chars[MAX_PATH];
GetTempPathA(MAX_PATH, temp_path_chars);
string temp_path = { temp_path_chars };
std::wstring itunes_dll = internal::GetITunesInstallDll(Strings::AsciiToUnicode(temp_path + "iTunesDLLs\\iTunes.dll"));
itunes_dll = Strings::AsciiToUnicode(temp_path + "iTunesDLLs\\iTunes.dll");
const HMODULE itunes_base = LoadLibraryW(itunes_dll.c_str());
//std::cout << "itunes_dll = " << encoding_wstring_to_ANSI(itunes_dll.c_str()) << std::endl;
//std::cout << "itunes_base = " << itunes_base << std::endl;
//const std::wstring air_traffic_host_dll = internal::GetAppleMobileDeviceSupportDll(L"AirTrafficHostDLL");
//const HMODULE air_traffic_host_base = LoadLibraryW(air_traffic_host_dll.c_str());
const HMODULE air_traffic_host_base = NULL; // <20><>װ<EFBFBD><D7B0>
iTunesInternalInterface::Instance()->kb_seed = 0;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnKbsync) = reinterpret_cast<unsigned long>(itunes_base)+Kbsync;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnCigHash) = reinterpret_cast<unsigned long>(itunes_base)+CigHash;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnKbsyncID) = reinterpret_cast<unsigned long>(itunes_base)+KbsyncID;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnWriteSIDD) = reinterpret_cast<unsigned long>(itunes_base)+WriteSIDD;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnWriteSIDB) = reinterpret_cast<unsigned long>(itunes_base)+WriteSIDB;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnDeAuthSIDB) = reinterpret_cast<unsigned long>(itunes_base)+DeAuthSIDB;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnGenerateAFSyncRS) = reinterpret_cast<unsigned long>(itunes_base)+GenerateAFSyncRS;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnVerifyAFSyncRQ) = reinterpret_cast<unsigned long>(itunes_base)+VerifyAFSyncRQ;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnSetAFSyncRQ) = reinterpret_cast<unsigned long>(itunes_base)+SetAFSyncRQ;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnCalcUnkP1) = reinterpret_cast<unsigned long>(itunes_base)+CalcUnkP1;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnPreAuthByDSID) = reinterpret_cast<unsigned long>(itunes_base)+PreAuthByDSID;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnSapInit) = reinterpret_cast<unsigned long>(itunes_base)+SapInit;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnSapGetP1) = reinterpret_cast<unsigned long>(itunes_base)+SapGetP1;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnSapCalcBuffer) = reinterpret_cast<unsigned long>(itunes_base)+SapCalcBuffer;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnSapGetAS) = reinterpret_cast<unsigned long>(itunes_base)+SapGetAS;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnSapGetASFD) = reinterpret_cast<unsigned long>(itunes_base)+SapGetASFD;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnSapGetASFD_a) = reinterpret_cast<unsigned long>(itunes_base)+SapGetASFD_a;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnGetCltDat) = reinterpret_cast<unsigned long>(itunes_base)+GetCltDat;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnTranSetInf) = reinterpret_cast<unsigned long>(itunes_base)+TranSetInf;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnUpdCDID) = reinterpret_cast<unsigned long>(itunes_base)+UpdCDID;
*reinterpret_cast<unsigned long*>(&iTunesInternalInterface::Instance()->lpfnGetMD) = reinterpret_cast<unsigned long>(itunes_base)+GetMD;
}
bool iTunesNativeInterface::IsMachineAmd64(const wchar_t* file,const wchar_t* dir){
bool result = false;
PLOADED_IMAGE load_image = ImageLoad(Strings::UnicodeToAscii(file).c_str(),Strings::UnicodeToAscii(dir).c_str());
if(load_image->FileHeader->FileHeader.Machine==IMAGE_FILE_MACHINE_AMD64){
result = true;
}
else if(load_image->FileHeader->FileHeader.Machine==IMAGE_FILE_MACHINE_I386){
result = false;
}
ImageUnload(load_image);
return result;
}
bool iTunesNativeInterface::iTunesDllVersion(const wchar_t* version){
static wchar_t g_version[1024] = {0};
if(!g_version[0]){
const std::wstring itunes_dll = internal::GetITunesInstallDll(L"iTunes.dll");
wcscpy_s(g_version,1023,internal::GetSoftwareReleaseVersion(itunes_dll.c_str()).c_str());
}
return (std::wstring(g_version)==version);
}
bool iTunesNativeInterface::AirTrafficHostDllVersion(const wchar_t* version){
static wchar_t g_version_a[1024] = {0};
if(!g_version_a[0]){
const std::wstring air_traffic_host_dll = internal::GetAppleMobileDeviceSupportDll(L"AirTrafficHostDLL");
wcscpy_s(g_version_a,1023,internal::GetSoftwareReleaseVersion(air_traffic_host_dll.c_str()).c_str());
}
return (std::wstring(g_version_a)==version);
}
bool iTunesNativeInterface::Loads(){
iTunesModule itunes_module;
HINSTANCE hCoreFoundationDll = LoadLibrary(itunes_module.core_foundation_dll().c_str());
if (hCoreFoundationDll == NULL){
return false;
}
HINSTANCE hITunesMobileDeviceDll = LoadLibrary(itunes_module.itunes_mobile_device_dll().c_str());
if (hITunesMobileDeviceDll == NULL){
return false;
}
HINSTANCE hAirTrafficHostDll = LoadLibrary(itunes_module.air_traffic_host_dll().c_str());
if (hAirTrafficHostDll == NULL){
return false;
}
HINSTANCE hITunesDll = LoadLibrary(itunes_module.iTunesDll(L"iTunes.dll").c_str());
if (hITunesDll == NULL){
return false;
}
//SetDllDirectory(NULL);
return true;
}
}

View File

@@ -0,0 +1,33 @@
#ifndef WIN_ITUNES_ITUNES_NATIVE_INTERFACE_H_
#define WIN_ITUNES_ITUNES_NATIVE_INTERFACE_H_
//////////////////////////////////////////////////////////////////////////
#include "basictypes.h"
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
namespace internal{
std::wstring GetSoftwareReleaseVersion(const wchar_t* full_path);
std::wstring GetAppleMobileDeviceSupportDll(const std::wstring dll_name);
std::wstring GetAppleApplicationSupportDll(const std::wstring dll_name);
std::wstring GetITunesInstallDll(const std::wstring dll_name);
std::wstring GetDirectory();
}
class iTunesNativeInterface
{
public:
static iTunesNativeInterface* GetInstance();
void Init();
private:
enum CustomizeModule{ kCoreFP, kiTunesMobileDeviceDLL };
iTunesNativeInterface(void);
~iTunesNativeInterface(void);
bool HKLMCustomizeModule(const CustomizeModule& customize_module, const wchar_t* module_name);
bool IsMachineAmd64(const wchar_t* file,const wchar_t* dir);
bool iTunesDllVersion(const wchar_t* version);
bool AirTrafficHostDllVersion(const wchar_t* version);
bool Loads();
DISALLOW_EVIL_CONSTRUCTORS(iTunesNativeInterface);
};
}
//////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,200 @@
#include <sstream>
#include <iomanip>
#include "strings.h"
#include "glog/scoped_ptr.h"
#include <openssl/md5.h>
namespace Strings{
std::vector<std::wstring> SplitMakePair(const std::wstring & str, const std::wstring& s1, const std::wstring& s2){
std::vector<std::wstring> v;
std::wstring pair_src_str = str;
size_t s1_pos = pair_src_str.find(s1);
while (s1_pos != std::wstring::npos){
if (pair_src_str.length() < s1_pos + s1.length()){
break;
}
std::size_t s2_pos = std::wstring(&pair_src_str[s1_pos + s1.length()]).find(s2);
if (s2_pos == std::wstring::npos){
break;
}
v.push_back(pair_src_str.substr(s1_pos + s1.length(), s2_pos));
s1_pos = s1_pos + s2_pos + s1.length() + s2.length();
if (pair_src_str.length() < s1_pos){
break;
}
pair_src_str = pair_src_str.substr(s1_pos, std::wstring::npos);
s1_pos = pair_src_str.find(s1);
}
return v;
}
std::wstring SplitDetail(const std::wstring& str, const std::wstring& detail){
std::wstring token;
std::wstring detail_str = str;
for (size_t pos = 0; (pos = detail_str.find(detail)) != std::wstring::npos;) {
token.append(detail_str.substr(0, pos));
detail_str.erase(0, pos + detail.length());
}
return std::wstring(token.append(detail_str));
}
std::vector<std::wstring> SplitArray(const std::wstring & str, const std::wstring & delimiters){
std::vector<std::wstring> v;
std::wstring::size_type start = 0;
size_t pos = str.find_first_of(delimiters, start);
while (pos != std::wstring::npos){
if (pos != start){
v.push_back(str.substr(start, pos - start));
}
start = pos + 1;
pos = str.find_first_of(delimiters, start);
}
if (start < str.length()){
v.push_back(str.substr(start));
}
return v;
}
std::string HexStrFormByteArray(unsigned char *data, int len){
std::stringstream ss;
ss << std::hex << std::setw(2) << std::setfill('0');
for (int i(0); i < len; ++i){
ss << (int)data[i] << std::setw(2) << std::setfill('0');
}
return std::string(ss.str());
}
std::string Md5(const void* str, size_t length, size_t block_length){
MD5_CTX md5_ctx = { 0 };
unsigned char sign[16] = { 0 };
if (length){
MD5_Init(&md5_ctx);
MD5_Update(&md5_ctx, str, length);
MD5_Final(sign, &md5_ctx);
}
if (block_length){
return std::string(HexStrFormByteArray(sign, 16), 0, block_length);
}
else{
return std::string(HexStrFormByteArray(sign, 16), 0);
}
}
std::string StringReplace(std::string& str, const std::string& from, const std::string& to){
size_t start_pos = 0;
while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
str.replace(start_pos, from.length(), to);
start_pos += to.length(); // Handles case where 'to' is a substring of 'from'
}
return str;
}
size_t EVPLength(const std::string& str){
size_t ignore_count = 0;
size_t count = str.length() - 1;
for (int i = 0; i < 2; i++){
if (str[count] == '='){
--count;
++ignore_count;
}
}
return ignore_count;
}
std::wstring AsciiToUnicode(const std::string &str){
if (!str.size()){
return L"";
}
int size_needed = MultiByteToWideChar(CP_ACP, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring wstrTo(size_needed, 0);
MultiByteToWideChar(CP_ACP, 0, &str[0], -1, &wstrTo[0], size_needed);
return wstrTo;
}
std::string UnicodeToAscii(const std::wstring &wstr){
if (!wstr.size()){
return "";
}
int size_needed = WideCharToMultiByte(CP_ACP, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_ACP, 0, &wstr[0], -1, &strTo[0], size_needed, NULL, NULL);
return strTo;
}
std::string UnicodeToUft8(const std::wstring& str){
if (!str.size()){
return "";
}
int n = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
scoped_array<char> buf_1(new char[str.length() * 4]);
memset(buf_1.get(), 0, str.length() * 4);
WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, buf_1.get(), n, NULL, NULL);
std::string strOutUTF8(buf_1.get());
return strOutUTF8;
}
std::wstring Utf8ToUnicode(const std::string &str){
int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, str.c_str(), str.length(), NULL, 0);
wchar_t* wszString = new wchar_t[wcsLen + 1];
::MultiByteToWideChar(CP_UTF8, NULL, str.c_str(), str.length(), wszString, wcsLen);
wszString[wcsLen] = '\0';
std::wstring unicodeText(wszString);
delete[] wszString;
return unicodeText;
}
std::string GBKToUtf8(const std::string &str){
if (!str.size()){
return "";
}
int len_wchart = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
wchar_t * unicode = new wchar_t[len_wchart + 10];
if (!unicode){
return "";
}
MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, unicode, len_wchart);
int len_utf8 = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL);
char* utf8str = new char[len_utf8 + 10];
WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf8str, len_utf8, NULL, NULL);
std::string utf8_data(utf8str);
delete[] utf8str;
delete[] unicode;
return utf8_data;
}
std::string Utf8ToGBK(const std::string &str){
int len_wchart = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
wchar_t * unicode_2 = new wchar_t[len_wchart + 10];
if (!unicode_2){
return "";
}
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, unicode_2, len_wchart);
int len_gbk = WideCharToMultiByte(CP_ACP, 0, unicode_2, -1, NULL, 0, NULL, NULL);
char * gbkstr = new char[len_gbk + 10];
WideCharToMultiByte(CP_ACP, 0, unicode_2, -1, gbkstr, len_gbk, NULL, NULL);
std::string gbk_data(gbkstr);
delete[] gbkstr;
delete[] unicode_2;
return gbk_data;
}
std::wstring ToUpper(const std::wstring& seque){
if (!seque.size()){
return L"";
}
std::wstring var_seque = seque;
std::transform(var_seque.begin(), var_seque.end(), var_seque.begin(), ::toupper);
return var_seque;
}
std::wstring ToLower(const std::wstring& seque){
if (!seque.size()){
return L"";
}
std::wstring var_seque = seque;
std::transform(var_seque.begin(), var_seque.end(), var_seque.begin(), ::tolower);
return var_seque;
}
std::string ToUpper(const std::string& seque){
if (!seque.size()){
return "";
}
std::string var_seque = seque;
std::transform(var_seque.begin(), var_seque.end(), var_seque.begin(), ::toupper);
return var_seque;
}
std::string ToLower(const std::string& seque){
if (!seque.size()){
return "";
}
std::string var_seque = seque;
std::transform(var_seque.begin(), var_seque.end(), var_seque.begin(), ::tolower);
return var_seque;
}
}

View File

@@ -0,0 +1,26 @@
#ifndef WIN_ITUNES_STRINGS_
#define WIN_ITUNES_STRINGS_
#include "basictypes.h"
namespace Strings{
std::vector<std::wstring> SplitMakePair(const std::wstring & str, const std::wstring& s1, const std::wstring& s2);
std::wstring SplitDetail(const std::wstring& str, const std::wstring& detail);
std::vector<std::wstring> SplitArray(const std::wstring & str, const std::wstring & delimiters);
std::string HexStrFormByteArray(unsigned char *data, int len);
std::string Md5(const void* str, size_t length, size_t block_length = 0);
std::string StringReplace(std::string& str, const std::string& from, const std::string& to);
size_t EVPLength(const std::string& str);
std::wstring AsciiToUnicode(const std::string &str);
std::string UnicodeToAscii(const std::wstring &wstr);
std::string UnicodeToUft8(const std::wstring& str);
std::wstring Utf8ToUnicode(const std::string &str);
std::string GBKToUtf8(const std::string &str);
std::string Utf8ToGBK(const std::string &str);
std::wstring ToUpper(const std::wstring& seque);
std::wstring ToLower(const std::wstring& seque);
std::string ToUpper(const std::string& seque);
std::string ToLower(const std::string& seque);
}
#endif

View File

@@ -0,0 +1,177 @@
#include "windows_hardware.h"
#include <algorithm>
#include <WinSock2.h>
#include <IPHlpApi.h>
#include "strings.h"
#include "windows_version.h"
namespace win_itunes{
HardwareInfo::HardwareInfo(){
set_cookie("");
std::string adapter_info = "";
std::string volume_serial = "";
std::string bois_info = "";
std::string processor_name = "";
std::string product_id = "";
std::string computer_name = "";
GetAdapterSerial(adapter_info);
std::string guid_1 = Strings::Md5(adapter_info.c_str(), adapter_info.length(), 8);
GetVolumeSerial(volume_serial);
std::string guid_2 = Strings::Md5(volume_serial.c_str(), volume_serial.length(), 8);
GetSystemBios(bois_info);
std::string guid_3 = Strings::Md5(bois_info.c_str(), bois_info.length(), 8);
GetProcessorName(processor_name);
std::string guid_4 = Strings::Md5(processor_name.c_str(), processor_name.length(), 8);
GetWinProductId(product_id);
std::string guid_5 = Strings::Md5(product_id.c_str(), product_id.length(), 8);
GetWinComputerName(computer_name);
std::string guid_6 = Strings::Md5(computer_name.c_str(), computer_name.length(), 8);
std::wstring hw_profile = HwProfile();
std::string guid_7 = Strings::Md5(hw_profile.c_str(), hw_profile.length()*sizeof(wchar_t), 8);
std::string guid = guid_1 + "." + guid_2 + "." + guid_5 + "." + guid_4 + "." + guid_3 + "." + guid_6 + "." + guid_7;
std::transform(guid.begin(), guid.end(), guid.begin(), ::toupper);
set_cookie(guid);
}
HardwareInfo::~HardwareInfo(){
set_cookie("");
}
bool HardwareInfo::GetAdapterSerial(std::string& out){
ULONG SizePointer;
WinVersion version;
if (!version.IsWin8() && !version.IsWin8_1()){
SizePointer = sizeof(IP_ADAPTER_INFO);
PIP_ADAPTER_INFO dummy_info = reinterpret_cast<PIP_ADAPTER_INFO>(malloc(sizeof(IP_ADAPTER_INFO)));
PIP_ADAPTER_INFO adapter_info = dummy_info;
memset(adapter_info, 0, sizeof(IP_ADAPTER_INFO));
if (!dummy_info){
return false;
}
if (GetAdaptersInfo(dummy_info, &SizePointer) == ERROR_BUFFER_OVERFLOW){
free(dummy_info);
adapter_info = reinterpret_cast<PIP_ADAPTER_INFO>(malloc(SizePointer));
memset(adapter_info, 0, SizePointer);
if (!adapter_info){
return false;
}
}
GetAdaptersInfo(adapter_info, &SizePointer);
for (unsigned int i = 0; i<6; i++){
if (i >= adapter_info->AddressLength){
break;
}
out.append(1, adapter_info->Address[i]);
}
free(adapter_info);
return true;
}
else{
SizePointer = 0;
if (GetAdaptersAddresses(0, GAA_FLAG_INCLUDE_ALL_INTERFACES, NULL, NULL, &SizePointer) != ERROR_BUFFER_OVERFLOW){
return false;
}
PIP_ADAPTER_ADDRESSES dummy_info = reinterpret_cast<PIP_ADAPTER_ADDRESSES>(malloc(SizePointer));
PIP_ADAPTER_ADDRESSES adapter_info = dummy_info;
if (!dummy_info || GetAdaptersAddresses(0, GAA_FLAG_INCLUDE_ALL_INTERFACES, 0, dummy_info, &SizePointer)){
return false;
}
for (unsigned int i = 0; i<6; i++){
if (i >= adapter_info->PhysicalAddressLength){
break;
}
out.append(1, adapter_info->PhysicalAddress[i++]);
}
free(adapter_info);
return true;
}
}
bool HardwareInfo::GetVolumeSerial(std::string& out){
unsigned long VolumeSerialNumber = 0;
GetVolumeInformationW(L"C:\\", 0, 0, &VolumeSerialNumber, 0, 0, 0, 0);
out.append(reinterpret_cast<char*>(&VolumeSerialNumber), 4);
return true;
}
bool HardwareInfo::GetSystemBios(std::string& out){
HKEY phkResult = NULL;
DWORD cbData = 0;
RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System", 0, KEY_READ, &phkResult);
if (!RegQueryValueExA(phkResult, "SystemBiosVersion", 0, 0, 0, &cbData)){
char* v7 = new char[cbData];
if (!RegQueryValueExA(phkResult, "SystemBiosVersion", 0, 0, reinterpret_cast<unsigned char*>(v7), &cbData)){
out.append(v7, cbData);
}
delete[]v7;
}
RegCloseKey(phkResult);
return true;
}
bool HardwareInfo::GetProcessorName(std::string& out){
HKEY phkResult = NULL;
DWORD cbData = 0;
RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &phkResult);
if (!RegQueryValueExA(phkResult, "ProcessorNameString", 0, 0, 0, &cbData)){
char* v7 = new char[cbData];
if (!RegQueryValueExA(phkResult, "ProcessorNameString", 0, 0, reinterpret_cast<unsigned char*>(v7), &cbData)){
out.append(v7, cbData);
}
delete[] v7;
}
RegCloseKey(phkResult);
return true;
}
bool HardwareInfo::GetWinProductId(std::string& out){
HKEY phkResult = NULL;
DWORD cbData = 0;
const char* reg_name = NULL;
OSVERSIONINFOEXW version_information = { 0 };
version_information.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
version_information.dwMajorVersion = 6;
version_information.dwMinorVersion = 0;
unsigned long long condition_mask = VerSetConditionMask(VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_GREATER_EQUAL);
if (VerifyVersionInfoW(&version_information, VER_MAJORVERSION | VER_MINORVERSION, condition_mask)){
reg_name = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
}
else{
reg_name = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion";
}
RegOpenKeyExA(HKEY_LOCAL_MACHINE, reg_name, 0, KEY_READ, &phkResult);
if (!RegQueryValueExA(phkResult, "ProductId", 0, 0, 0, &cbData)){
char* v7 = new char[cbData];
if (!RegQueryValueExA(phkResult, "ProductId", 0, 0, reinterpret_cast<unsigned char*>(v7), &cbData)){
out.append(v7, cbData);
}
delete[]v7;
}
RegCloseKey(phkResult);
return true;
}
bool HardwareInfo::GetWinComputerName(std::string& out){
wchar_t buffer[MAX_PATH] = { 0 };
unsigned long length = MAX_PATH;
GetComputerNameW(buffer, &length);
out.resize(length);
memmove(const_cast<char*>(out.c_str()), buffer, length);
return true;
}
std::string HardwareInfo::GetMachineName(){
std::string machine_name = "";
GetWinComputerName(machine_name);
return machine_name;
}
std::wstring HardwareInfo::HwProfile(){
/*regedit path HKLM\System\CurrentControlSet\Control\IDConfigDB\Hardware Profiles
reference:http://stackoverflow.com/questions/3263622/uniquely-identify-a-computer-by-its-hardware-profile-getcurrenthwprofile*/
HW_PROFILE_INFOW hw_profile_info = { 0 };
GetCurrentHwProfileW(reinterpret_cast<LPHW_PROFILE_INFOW>(&hw_profile_info));
return (std::wstring(hw_profile_info.szHwProfileGuid));
}
std::string HardwareInfo::cookie() const{
return cookie_;
}
void HardwareInfo::set_cookie(const std::string hardware_cookie){
cookie_ = hardware_cookie;
}
std::string GetHardwareCookie(){
HardwareInfo hardware;
return hardware.cookie();
}
}

View File

@@ -0,0 +1,28 @@
#ifndef WIN_ITUNES_WINDOWS_HARDWARE_H_
#define WIN_ITUNES_WINDOWS_HARDWARE_H_
//////////////////////////////////////////////////////////////////////////
#include <string>
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
class HardwareInfo
{
public:
HardwareInfo();
~HardwareInfo();
bool GetAdapterSerial(std::string& out);
bool GetVolumeSerial(std::string& out);
bool GetSystemBios(std::string& out);
bool GetProcessorName(std::string& out);
bool GetWinProductId(std::string& out);
bool GetWinComputerName(std::string& out);
std::string GetMachineName();
std::wstring HwProfile();
std::string cookie() const;
private:
void set_cookie(const std::string hardware_cookie);
std::string cookie_;
};
std::string GetHardwareCookie();
}
//////////////////////////////////////////////////////////////////////////
#endif

View File

@@ -0,0 +1,45 @@
#include "windows_version.h"
namespace win_itunes{
WinVersion::WinVersion(void){
set_os_version();
set_os_info();
}
WinVersion::~WinVersion(void){
set_os_version(true);
set_os_info(true);
}
bool WinVersion::IsAmd64() const{
return (os_info().dwOemId == PROCESSOR_ARCHITECTURE_AMD64);
}
bool WinVersion::IsX64Os() const{
return (os_info().dwOemId == PROCESSOR_ARCHITECTURE_AMD64 || os_info().dwOemId == PROCESSOR_ARCHITECTURE_IA64);
}
bool WinVersion::IsWinXP() const{
return (os_version().dwMajorVersion == 5 && os_version().dwMinorVersion == 1);
}
bool WinVersion::IsWin2003() const{
return (os_version().dwMajorVersion == 5 && os_version().dwMinorVersion == 2 && !GetSystemMetrics(SM_SERVERR2));
}
bool WinVersion::IsWin2003_R2() const{
return (os_version().dwMajorVersion == 5 && os_version().dwMinorVersion == 2 && GetSystemMetrics(SM_SERVERR2));
}
bool WinVersion::IsVista() const{
return (os_version().dwMajorVersion == 6 && os_version().dwMinorVersion == 0);
}
bool WinVersion::IsWin7() const{
return (os_version().dwMajorVersion == 6 && os_version().dwMinorVersion == 1);
}
bool WinVersion::IsWin8() const{
return (os_version().dwMajorVersion == 6 && os_version().dwMinorVersion == 2);
}
bool WinVersion::IsWin8_1() const{
return (os_version().dwMajorVersion == 6 && os_version().dwMinorVersion == 3);
}
bool WinVersion::IsWinNT5() const{
return (os_version().dwMajorVersion == 5 && os_version().wProductType == VER_NT_WORKSTATION);
}
bool WinVersion::IsWinNT6() const{
return (os_version().dwMajorVersion == 6 && os_version().wProductType == VER_NT_WORKSTATION);
}
}

View File

@@ -0,0 +1,50 @@
#ifndef WIN_ITUNES_WINDOWS_VERSION_H_
#define WIN_ITUNES_WINDOWS_VERSION_H_
//////////////////////////////////////////////////////////////////////////
#include <Windows.h>
//////////////////////////////////////////////////////////////////////////
namespace win_itunes{
class WinVersion
{
public:
WinVersion(void);
~WinVersion(void);
bool IsAmd64() const;
bool IsX64Os() const;
bool IsWinXP() const;
bool IsWin2003() const;
bool IsWin2003_R2() const;
bool IsVista() const;
bool IsWin7() const;
bool IsWin8() const;
bool IsWin8_1() const;
bool IsWinNT5() const;
bool IsWinNT6() const;
private:
inline OSVERSIONINFOEXW os_version() const{
const OSVERSIONINFOEXW c_os_version = os_version_;
return c_os_version;
}
inline SYSTEM_INFO os_info() const{
const SYSTEM_INFO os_info = os_info_;
return os_info;
}
inline void set_os_version(const bool only_init = false){
memset(&os_version_, 0, sizeof(os_version_));
if (!only_init){
os_version_.dwOSVersionInfoSize = sizeof(os_version_);
GetVersionExW(reinterpret_cast<LPOSVERSIONINFOW>(&os_version_));
}
}
inline void set_os_info(const bool only_init = false){
memset(&os_info_, 0, sizeof(os_info_));
if (!only_init){
GetNativeSystemInfo(&os_info_);
}
}
OSVERSIONINFOEXW os_version_;
SYSTEM_INFO os_info_;
};
}
//////////////////////////////////////////////////////////////////////////
#endif

16
iTunesAPIs/src/resource.h Normal file
View File

@@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ <20><><EFBFBD>ɵİ<C9B5><C4B0><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
// <20><> Resource.rc ʹ<><CAB9>
//
#define IDR_SEVENZIP1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,17 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ <20><><EFBFBD>ɵİ<C9B5><C4B0><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
// <20><> Resource.rc ʹ<><CAB9>
//
#define IDR_SEVENZIP1 101
#define IDR_DLL1 102
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 103
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,106 @@
#include "utils/encoding.h"
namespace ytpp {
namespace sys_core
{
string encoding_ANSI_to_UTF8(_In_ const string & str)
{
string rtn;
WCHAR* p = nullptr;
int _len = MultiByteToWideChar(CP_ACP, NULL, str.c_str(), -1, NULL, 0);
p = new WCHAR[_len];
MultiByteToWideChar(CP_ACP, NULL, str.c_str(), -1, p, _len);
CHAR* p2 = nullptr;
_len = WideCharToMultiByte(CP_UTF8, NULL, p, -1, NULL, 0, NULL, NULL);
p2 = new CHAR[_len];
WideCharToMultiByte(CP_UTF8, NULL, p, -1, p2, _len, NULL, NULL);
rtn.assign(p2);
delete[] p;
delete[] p2;
return rtn;
}
string encoding_UTF8_to_ANSI(_In_ const string & str)
{
string rtn;
WCHAR* p = nullptr;
int _len = MultiByteToWideChar(CP_UTF8, NULL, str.c_str(), -1, NULL, 0);
p = new WCHAR[_len];
MultiByteToWideChar(CP_UTF8, NULL, str.c_str(), -1, p, _len);
CHAR* p2 = nullptr;
_len = WideCharToMultiByte(CP_ACP, NULL, p, -1, NULL, 0, NULL, NULL);
p2 = new CHAR[_len];
WideCharToMultiByte(CP_ACP, NULL, p, -1, p2, _len, NULL, NULL);
rtn.assign(p2);
delete[] p;
delete[] p2;
return rtn;
}
std::wstring encoding_ANSI_to_wstring(_In_ const string & str)
{
wstring rtn;
WCHAR* p = nullptr;
int _len = MultiByteToWideChar(CP_ACP, NULL, str.c_str(), -1, NULL, 0);
p = new WCHAR[_len];
MultiByteToWideChar(CP_ACP, NULL, str.c_str(), -1, p, _len);
rtn.assign(p);
delete[] p;
return rtn;
}
std::string encoding_wstring_to_ANSI(_In_ const wstring & str)
{
string rtn;
CHAR* p = nullptr;
int _len = WideCharToMultiByte(CP_ACP, NULL, str.c_str(), -1, NULL, 0, NULL, NULL);
p = new CHAR[_len];
WideCharToMultiByte(CP_ACP, NULL, str.c_str(), -1, p, _len, NULL, NULL);
rtn.assign(p);
delete[] p;
return rtn;
}
std::wstring encoding_UTF8_to_wstring(_In_ const string & str)
{
wstring rtn;
WCHAR* p = nullptr;
int _len = MultiByteToWideChar(CP_UTF8, NULL, str.c_str(), -1, NULL, 0);
p = new WCHAR[_len];
MultiByteToWideChar(CP_UTF8, NULL, str.c_str(), -1, p, _len);
rtn.assign(p);
delete[] p;
return rtn;
}
std::string encoding_wstring_to_UTF8(_In_ const wstring & str)
{
string rtn;
CHAR* p = nullptr;
int _len = WideCharToMultiByte(CP_UTF8, NULL, str.c_str(), -1, NULL, 0, NULL, NULL);
p = new CHAR[_len];
WideCharToMultiByte(CP_UTF8, NULL, str.c_str(), -1, p, _len, NULL, NULL);
rtn.assign(p);
delete[] p;
return rtn;
}
}
}

View File

@@ -0,0 +1,64 @@
#ifndef _SYS_CORE_ENCODING_H_
#define _SYS_CORE_ENCODING_H_
#include <string>
#include <windows.h>
namespace ytpp {
namespace sys_core
{
using namespace std;
//=================== ANSI & UTF-8 ===================
/*
* @brief 将ANSI编码的string字符串转换为UTF-8编码的string字符串
* @param [in] str: ANSI编码的string字符串
* @return (string) UTF-8编码的string字符串
*/
string encoding_ANSI_to_UTF8(_In_ const string & str);
/*
* @brief 将UTF-8编码的string字符串转换为ANSI编码的string字符串
* @param [in] str: UTF-8编码的string字符串
* @return (string) ANSI编码的string字符串
*/
string encoding_UTF8_to_ANSI(_In_ const string & str);
//=================== ANSI & UTF-16 ===================
/*
* @brief 将ANSI编码的string转换为UTF-16编码的wstring宽字符串
* @param [in] str: ANSI编码的string字符串
* @return (wstring) UTF-16编码的wstring宽字符串
*/
wstring encoding_ANSI_to_wstring(_In_ const string & str);
/*
* @brief 将UTF-16编码的wstring宽字符串转换为ANSI编码的string字符串
* @param [in] str: UTF-16编码的wstring宽字符串
* @return (string) ANSI编码的string字符串
*/
string encoding_wstring_to_ANSI(_In_ const wstring & str);
//=================== UTF-8 & UTF-16 ===================
/*
* @brief 将UTF-8编码的string转换为 UTF-16编码的wstring宽字符串
* @param [in] str: UTF-8编码的string字符串
* @return (wstring) UTF-16编码的wstring宽字符串
*/
wstring encoding_UTF8_to_wstring(_In_ const string & str);
/*
* @brief 将UTF-16编码的wstring宽字符串转换为UTF-8编码的string字符串
* @param [in] str: UTF-16编码的wstring宽字符串
* @return (string) UTF-8编码的string字符串
*/
string encoding_wstring_to_UTF8(_In_ const wstring & str);
}
}
#endif /* _SYS_CORE_ENCODING_H_ */

View File

@@ -0,0 +1,45 @@
#include "utils/hash.h"
#include <openssl/evp.h>
#include <iomanip>
#include <sstream>
namespace ytpp {
namespace sys_core {
std::string get_hash(const std::string& input) {
EVP_MD_CTX ctx;
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int hash_len = 0;
EVP_MD_CTX_init(&ctx); // <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), nullptr)) {
EVP_MD_CTX_cleanup(&ctx);
return "";
}
if (!EVP_DigestUpdate(&ctx, input.c_str(), input.length())) {
EVP_MD_CTX_cleanup(&ctx);
return "";
}
if (!EVP_DigestFinal_ex(&ctx, hash, &hash_len)) {
EVP_MD_CTX_cleanup(&ctx);
return "";
}
EVP_MD_CTX_cleanup(&ctx); // <20>ͷ<EFBFBD><CDB7><EFBFBD>Դ
// תΪʮ<CEAA><CAAE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
std::stringstream ss;
for (unsigned int i = 0; i < hash_len; ++i) {
ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
}
return ss.str();
}
}
}

View File

@@ -0,0 +1,34 @@
#ifndef _HASH_H_
#define _HASH_H_
#include <string>
namespace ytpp {
namespace sys_core {
enum class HashType {
MD5 = 1,
SHA1,
SHA256,
SHA512
};
/// <summary>
/// SHA256<35><36><EFBFBD><EFBFBD>
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
std::string get_hash(const std::string& input);
}
}
#endif /* _HASH_H_ */

View File

@@ -0,0 +1,531 @@
#include "utils/httpRequest.h"
#include <string>
#include <functional>
#include <sstream>
#include <vector>
#include <algorithm>
#include <cctype>
#include <iostream>
using namespace std;
#include <curl/curl.h>
#pragma comment(lib, "Crypt32.lib")
#pragma comment(lib, "ws2_32.lib")
namespace ytpp {
namespace curl_ex {
std::string UrlEncode(const std::string& input) {
CURL* curl = curl_easy_init();
if (!curl) return "";
char* output = curl_easy_escape(curl, input.c_str(), static_cast<int>(input.length()));
std::string encoded;
if (output) {
encoded = output;
curl_free(output);
}
curl_easy_cleanup(curl);
return encoded;
}
std::string UrlDecode(const std::string& input) {
CURL* curl = curl_easy_init();
if (!curl) return "";
int outlength;
char* output = curl_easy_unescape(curl, input.c_str(), static_cast<int>(input.length()), &outlength);
std::string decoded;
if (output) {
decoded.assign(output, outlength);
curl_free(output);
}
curl_easy_cleanup(curl);
return decoded;
}
#pragma region HttpHeadersWrapper
// ȥ<><C8A5>ǰ<EFBFBD><C7B0><EFBFBD>ո<EFBFBD>
std::string HttpHeadersWrapper::Trim(const std::string& str) {
std::string result = str;
result.erase(result.begin(), std::find_if(result.begin(), result.end(), [](unsigned char ch) {
return !std::isspace(ch);
}));
result.erase(std::find_if(result.rbegin(), result.rend(), [](unsigned char ch) {
return !std::isspace(ch);
}).base(), result.end());
return result;
}
HttpHeadersWrapper::HttpHeadersWrapper() {}
HttpHeadersWrapper::HttpHeadersWrapper(_In_ std::string responseHeaders) {
ParseHeaders(std::move(responseHeaders));
}
HttpHeadersWrapper::HttpHeadersWrapper(const std::map<std::string, std::string>& defaultHeaders, const std::string& responseHeaders) {
for (const auto& [key, value] : defaultHeaders) {
SetDefaultHeader(key, value);
}
ParseHeaders(responseHeaders);
}
void HttpHeadersWrapper::ParseHeaders(_In_ std::string responseHeaders) {
m_headers.clear();
std::istringstream stream(responseHeaders);
std::string line;
while (std::getline(stream, line)) {
auto pos = line.find(':');
if (pos != std::string::npos) {
std::string key = Trim(line.substr(0, pos));
std::string value = Trim(line.substr(pos + 1));
if (!key.empty()) {
m_headers[key] = value;
}
}
}
}
std::string HttpHeadersWrapper::GetHeaderValue(const std::string& key) {
auto it = m_headers.find(Trim(key));
if (it != m_headers.end()) {
return it->second;
}
return {};
}
std::string HttpHeadersWrapper::GetAllHeaders() {
std::ostringstream out;
for (const auto& [key, value] : m_headers) {
out << key << ": " << value << "\n";
}
std::string outStr = out.str();
//ȥ<><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD>
if (!outStr.empty()) {
outStr.pop_back();
}
return outStr;
}
bool HttpHeadersWrapper::SetHeader(const std::string& key, const std::string& value) {
std::string trimmedKey = Trim(key);
if (trimmedKey.empty()) return false;
m_headers[trimmedKey] = Trim(value);
return true;
}
bool HttpHeadersWrapper::SetDefaultHeader(const std::string& key, const std::string& value) {
std::string trimmedKey = Trim(key);
if (trimmedKey.empty()) return false;
if (!IsExist(trimmedKey)) {
m_headers[trimmedKey] = Trim(value);
return true;
}
return false;
}
bool HttpHeadersWrapper::AppendHeader(const std::string& key, const std::string& value, const std::string& delimiter) {
std::string trimmedKey = Trim(key);
std::string trimmedValue = Trim(value);
if (trimmedKey.empty()) return false;
auto it = m_headers.find(trimmedKey);
if (it != m_headers.end()) {
it->second += delimiter + trimmedValue;
} else {
m_headers[trimmedKey] = trimmedValue;
}
return true;
}
bool HttpHeadersWrapper::EraseHeader(const std::string& key) {
return m_headers.erase(Trim(key)) > 0;
}
bool HttpHeadersWrapper::IsExist(const std::string& key) {
return m_headers.find(Trim(key)) != m_headers.end();
}
std::vector<std::string> HttpHeadersWrapper::GetKeys() {
std::vector<std::string> keys;
for (const auto& [key, _] : m_headers) {
keys.push_back(key);
}
return keys;
}
#pragma endregion HttpHeadersWrapper
#pragma region HttpCookiesWrapper
std::string HttpCookiesWrapper::Trim(const std::string& str) {
auto begin = std::find_if_not(str.begin(), str.end(), ::isspace);
auto end = std::find_if_not(str.rbegin(), str.rend(), ::isspace).base();
return (begin < end) ? std::string(begin, end) : std::string();
}
std::string Cookie::ToSetCookieString() const {
std::ostringstream out;
out << name << "=" << value;
if (path) out << "; Path=" << *path;
if (domain) out << "; Domain=" << *domain;
if (expires) out << "; Expires=" << *expires;
if (maxAge) out << "; Max-Age=" << *maxAge;
if (secure) out << "; Secure";
if (httpOnly) out << "; HttpOnly";
if (sameSite) out << "; SameSite=" << *sameSite;
return out.str();
}
HttpCookiesWrapper::HttpCookiesWrapper() {}
HttpCookiesWrapper::HttpCookiesWrapper(const std::vector<std::string>& setCookieHeaders) {
ParseFromSetCookieHeaders(setCookieHeaders);
}
HttpCookiesWrapper::HttpCookiesWrapper(const std::string& cookieString) {
ParseFromCookieString(cookieString);
}
HttpCookiesWrapper::HttpCookiesWrapper(const HttpCookiesWrapper& other) {
m_cookies = other.m_cookies;
}
void HttpCookiesWrapper::Merge(const HttpCookiesWrapper& other, bool overwrite) {
for (const auto& [key, value] : other.m_cookies) {
if (overwrite || m_cookies.find(key) == m_cookies.end()) {
m_cookies[key] = value;
}
}
}
HttpCookiesWrapper HttpCookiesWrapper::MergedWith(const HttpCookiesWrapper& other, bool overwrite) const {
HttpCookiesWrapper result = *this; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>
result.Merge(other, overwrite); // ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD> Merge <20><><EFBFBD><EFBFBD>
return result;
}
std::vector<std::string> HttpCookiesWrapper::ExtractSetCookieHeaders(const std::string& rawHeaders) {
std::vector<std::string> result;
size_t start = 0;
while (start < rawHeaders.size()) {
size_t end = rawHeaders.find_first_of("\r\n", start);
if (end == std::string::npos)
end = rawHeaders.size();
std::string line = Trim(rawHeaders.substr(start, end - start));
if (line.size() >= 11) {
std::string prefix = line.substr(0, 11);
std::transform(prefix.begin(), prefix.end(), prefix.begin(), ::tolower);
if (prefix == "set-cookie:") {
result.push_back(Trim(line.substr(11)));
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϻ<EFBFBD><CFBB>з<EFBFBD> \r\n<><6E>\n <20><> \r
if (end < rawHeaders.size()) {
if (rawHeaders[end] == '\r' && rawHeaders[end + 1] == '\n') start = end + 2;
else start = end + 1;
} else {
break;
}
}
return result;
}
void HttpCookiesWrapper::ParseFromSetCookieHeaders(const std::vector<std::string>& setCookieHeaders) {
m_cookies.clear(); // <20><><EFBFBD><EFBFBD>֮ǰ<D6AE><C7B0>cookie
for (const auto& header : setCookieHeaders) {
std::istringstream stream(header);
std::string segment;
Cookie cookie;
bool first = true;
while (std::getline(stream, segment, ';')) {
auto eqPos = segment.find('=');
std::string key = Trim(segment.substr(0, eqPos));
std::string value = (eqPos != std::string::npos) ? Trim(segment.substr(eqPos + 1)) : "";
if (first && !key.empty()) {
cookie.name = key;
cookie.value = value;
first = false;
} else {
std::string lowerKey = key;
std::transform(lowerKey.begin(), lowerKey.end(), lowerKey.begin(), ::tolower);
if (lowerKey == "path") cookie.path = value;
else if (lowerKey == "domain") cookie.domain = value;
else if (lowerKey == "expires") cookie.expires = value;
else if (lowerKey == "max-age") cookie.maxAge = std::stoi(value);
else if (lowerKey == "secure") cookie.secure = true;
else if (lowerKey == "httponly") cookie.httpOnly = true;
else if (lowerKey == "samesite") cookie.sameSite = value;
}
}
if (!cookie.name.empty())
m_cookies[cookie.name] = cookie;
}
}
void HttpCookiesWrapper::ParseFromCookieString(const std::string& cookieString) {
m_cookies.clear(); // <20><><EFBFBD><EFBFBD>֮ǰ<D6AE><C7B0>cookie
std::istringstream stream(cookieString);
std::string token;
while (std::getline(stream, token, ';')) {
auto eqPos = token.find('=');
if (eqPos != std::string::npos) {
std::string key = Trim(token.substr(0, eqPos));
std::string val = Trim(token.substr(eqPos + 1));
if (!key.empty()) {
Cookie cookie { key, val };
m_cookies[key] = cookie;
}
}
}
}
void HttpCookiesWrapper::SetCookie(const Cookie& cookie) {
m_cookies[cookie.name] = cookie;
}
void HttpCookiesWrapper::SetCookie(const std::string& name, const std::string& value) {
Cookie cookie { Trim(name), Trim(value) };
m_cookies[cookie.name] = cookie;
}
bool HttpCookiesWrapper::EraseCookie(const std::string& name) {
return m_cookies.erase(Trim(name)) > 0;
}
bool HttpCookiesWrapper::IsExist(const std::string& name) const {
return m_cookies.find(name) != m_cookies.end();
}
void HttpCookiesWrapper::RemoveEmptyCookies()
{
for (auto it = m_cookies.begin(); it != m_cookies.end();) {
if (it->second.value.empty()) {
m_cookies.erase(it++);
} else {
++it;
}
}
}
std::string HttpCookiesWrapper::GetCookieValue(const std::string& name) const {
auto it = m_cookies.find(name);
return (it != m_cookies.end()) ? it->second.value : "";
}
std::vector<std::string> HttpCookiesWrapper::GetAllKeys(bool ignoreNull) const {
std::vector<std::string> keys;
for (const auto& [k, _] : m_cookies) {
if (ignoreNull) {
if (_.value.empty()) break;
}
keys.push_back(k);
}
return keys;
}
std::string HttpCookiesWrapper::ToRequestCookieString(bool ignoreNull) const {
std::ostringstream out;
bool first = true;
for (const auto& [k, cookie] : m_cookies) {
if (ignoreNull) {
if (cookie.value.empty()) break;
}
if (!first) out << "; ";
out << k << "=" << cookie.value;
first = false;
}
return out.str();
}
std::vector<std::string> HttpCookiesWrapper::ToSetCookieHeaders(bool ignoreNull) const {
std::vector<std::string> result;
for (const auto& [_, cookie] : m_cookies) {
if (ignoreNull) {
if (cookie.value.empty()) break;
}
result.push_back("Set-Cookie: " + cookie.ToSetCookieString());
}
return result;
}
std::vector<Cookie> HttpCookiesWrapper::GetAllCookies(bool ignoreNull) const {
std::vector<Cookie> all;
for (const auto& [_, cookie] : m_cookies) {
if (ignoreNull) {
if (cookie.value.empty()) break;
}
all.push_back(cookie);
}
return all;
}
#pragma endregion HttpCookiesWrapper
#pragma region HttpRequest
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output);
static size_t HeaderCallback(void* contents, size_t size, size_t nmemb, std::string* header);
/* <20><><EFBFBD><EFBFBD>GET<45><54><EFBFBD><EFBFBD> */
HttpResponse HttpRequest::Get(
_In_ std::string url,
_In_ std::string headersEx /*= ""*/,
_In_ std::string proxy /*= ""*/,
_In_ bool ssl /*= true*/,
_In_ std::function<void(CURL*)> lpfnCurlOptions /*= nullptr*/)
{
HttpResponse ret;
CURL* curl = curl_easy_init();
if (!curl) {
ret.success = false;
ret.error = "CURL<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>";
return ret; // <20><>ʼ<EFBFBD><CABC>ʧ<EFBFBD><CAA7>
}
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: ");
headers = curl_slist_append(headers, "Accept: ");
headers = curl_slist_append(headers, headersEx.c_str());
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ret.content); // <20><>ȡ<EFBFBD><C8A1>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HeaderCallback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &ret.org_headers); // <20><>ȡ<EFBFBD><C8A1>Ӧͷ
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, ssl ? 1L : 0L); // <20><>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD> SSL ֤<><D6A4>
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, ssl ? 2L : 0L); // <20><>֤<EFBFBD><D6A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // ֧<><D6A7><EFBFBD>ض<EFBFBD><D8B6><EFBFBD>
if (!proxy.empty()) {
curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str()); // <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>
}
if (lpfnCurlOptions) {
lpfnCurlOptions(curl); // <20><><EFBFBD>ûص<C3BB><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>
}
CURLcode res = curl_easy_perform(curl);
ret.curl_code = res;
if (res != CURLE_OK) {
ret.success = false;
ret.error = std::string(curl_easy_strerror(res));
} else {
ret.success = true;
// <20><>ȡ<EFBFBD><C8A1>Ӧ<EFBFBD><D3A6>
long response_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
ret.code = response_code;
// <20><>Ӧ<EFBFBD><D3A6><EFBFBD>ݺ<EFBFBD><DDBA><EFBFBD>Ӧͷֱ<CDB7><D6B1><EFBFBD>ûص<C3BB><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>
// <20><><EFBFBD><EFBFBD>Cookies
ret.cookies.ParseFromSetCookieHeaders(HttpCookiesWrapper::ExtractSetCookieHeaders(ret.org_headers));
// <20><><EFBFBD><EFBFBD>headers
ret.headers.ParseHeaders(ret.org_headers);
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return ret;
}
/* <20><><EFBFBD><EFBFBD>POST<53><54><EFBFBD><EFBFBD> */
HttpResponse HttpRequest::Post(
_In_ std::string url,
_In_ std::string postData /*= ""*/,
_In_ std::string headersEx /*= ""*/,
_In_ std::string proxy /*= ""*/,
_In_ bool ssl /*= true*/,
_In_ std::function<void(CURL*)> lpfnCurlOptions /*= nullptr*/)
{
HttpResponse ret;
CURL* curl = curl_easy_init();
if (!curl) {
ret.success = false;
ret.error = "CURL<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>";
return ret; // <20><>ʼ<EFBFBD><CABC>ʧ<EFBFBD><CAA7>
}
struct curl_slist* headers = NULL;
headers = curl_slist_append(headers, "Content-Type: ");
headers = curl_slist_append(headers, "Accept: ");
headers = curl_slist_append(headers, headersEx.c_str());
curl_version_info_data* data = curl_version_info(CURLVERSION_NOW);
std::cout << "SSL backend: " << (data->ssl_version ? data->ssl_version : "none") << std::endl;
//curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); // <20><><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ret.content); // <20><>ȡ<EFBFBD><C8A1>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HeaderCallback);
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &ret.org_headers); // <20><>ȡ<EFBFBD><C8A1>Ӧͷ
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, ssl ? 1L : 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, ssl ? 2L : 0L);
curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_ANY); // <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD><D6A4>ʽ
//curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
//curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE);
curl_easy_setopt(curl, CURLOPT_PROXYAUTH, CURLAUTH_BASIC | CURLAUTH_NTLM | CURLAUTH_DIGEST);
//curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS); // Ĭ<><C4AC>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽָ<CABD><D6B8>
if (!proxy.empty()) {
curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str()); // <20><><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>
}
if (lpfnCurlOptions) {
lpfnCurlOptions(curl); // <20><><EFBFBD>ûص<C3BB><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD><D1A1>
}
CURLcode res = curl_easy_perform(curl);
ret.curl_code = res;
if (res != CURLE_OK) {
ret.success = false;
ret.error = "CURLcode:" + std::to_string(res) + ", " + std::string(curl_easy_strerror(res));
} else {
ret.success = true;
// <20><>ȡ<EFBFBD><C8A1>Ӧ<EFBFBD><D3A6>
long response_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
ret.code = response_code;
// <20><>Ӧ<EFBFBD><D3A6><EFBFBD>ݺ<EFBFBD><DDBA><EFBFBD>Ӧͷֱ<CDB7><D6B1><EFBFBD>ûص<C3BB><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD><EFBFBD>ô<EFBFBD><C3B4><EFBFBD>
// <20><><EFBFBD><EFBFBD>Cookies
ret.cookies.ParseFromSetCookieHeaders(HttpCookiesWrapper::ExtractSetCookieHeaders(ret.org_headers));
// <20><><EFBFBD><EFBFBD>headers
ret.headers.ParseHeaders(ret.org_headers);
}
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
return ret;
}
/* <20>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4>output */
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) {
size_t totalSize = size * nmemb;
output->append((char*)contents, totalSize);
return totalSize;
}
/* <20>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD>HTTP<54><50>Ӧͷ<D3A6><CDB7><EFBFBD><EFBFBD> */
static size_t HeaderCallback(void* contents, size_t size, size_t nmemb, std::string* header) {
size_t totalSize = size * nmemb;
header->append((char*)contents, totalSize);
return totalSize;
}
#pragma endregion HttpRequest
}
}

View File

@@ -0,0 +1,194 @@
#pragma once
#include <string>
#include <functional>
#include <optional>
#include <map>
#include <curl/curl.h>
namespace ytpp {
namespace curl_ex {
std::string UrlEncode(const std::string& input);
std::string UrlDecode(const std::string& input);
#pragma region HttpHeaderWrapper
class HttpHeadersWrapper {
public:
HttpHeadersWrapper();
// <20><><EFBFBD><EFBFBD>Ӧͷ<D3A6>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
HttpHeadersWrapper(_In_ std::string responseHeaders);
// <20><><EFBFBD><EFBFBD>Ӧͷ<D3A6>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>ͷ
HttpHeadersWrapper(const std::map<std::string, std::string>& defaultHeaders, const std::string& responseHeaders);
// <20><><EFBFBD><EFBFBD>Ӧͷ<D3A6>н<EFBFBD><D0BD><EFBFBD>
void ParseHeaders(_In_ std::string responseHeaders);
// <20><>ȡͷ<C8A1><CDB7>ֵ
std::string GetHeaderValue(const std::string& key);
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɶ<EFBFBD><C9B6><EFBFBD>ͷ<EFBFBD>ĸ<EFBFBD>ʽ
std::string GetAllHeaders();
// <20><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD><D1B4><EFBFBD><EFBFBD>򸲸<EFBFBD>
bool SetHeader(const std::string& key, const std::string& value);
// <20><><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>Ѵ<EFBFBD><D1B4><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool SetDefaultHeader(const std::string& key, const std::string& value);
// <20><>ֵ<EFBFBD>ĺ<EFBFBD><C4BA><EFBFBD><E6B8BD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD>
bool AppendHeader(const std::string& key, const std::string& value, const std::string& delimiter = ", ");
// ɾ<><C9BE>ͷ
bool EraseHeader(const std::string& key);
// <20>ж<EFBFBD>ͷ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
bool IsExist(const std::string& key);
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͷ<EFBFBD>ļ<EFBFBD>
std::vector<std::string> GetKeys();
private:
static std::string Trim(const std::string& str);
struct CaseInsensitiveCompare {
bool operator()(const std::string& a, const std::string& b) const {
return std::lexicographical_compare(
a.begin(), a.end(), b.begin(), b.end(),
[](unsigned char c1, unsigned char c2) {
return std::tolower(c1) < std::tolower(c2);
});
}
};
std::map<std::string, std::string, CaseInsensitiveCompare> m_headers;
};
#pragma endregion HttpHeaderWrapper
#pragma region HttpCookiesWrapper
struct Cookie {
std::string name;
std::string value;
std::optional<std::string> path;
std::optional<std::string> domain;
std::optional<std::string> expires;
std::optional<int> maxAge;
bool secure = false;
bool httpOnly = false;
std::optional<std::string> sameSite;
std::string ToSetCookieString() const;
};
class HttpCookiesWrapper {
public:
HttpCookiesWrapper();
// <20><>Set-Cookie <20><><EFBFBD><EFBFBD>ͷ<EFBFBD>н<EFBFBD><D0BD><EFBFBD>
HttpCookiesWrapper(const std::vector<std::string>& setCookieHeaders);
// <20><>cookie<69>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> name1=value1; name2=value2
HttpCookiesWrapper(const std::string& cookieString);
// <20><><EFBFBD><EFBFBD>
HttpCookiesWrapper(const HttpCookiesWrapper& other);
// <20>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>
void Merge(const HttpCookiesWrapper& other, bool overwrite = true);
// <20><><EFBFBD>غϲ<D8BA><CFB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><C2B6><EFBFBD>
HttpCookiesWrapper MergedWith(const HttpCookiesWrapper& other, bool overwrite) const;
// <20><><EFBFBD><EFBFBD>Ӧͷ<D3A6><CDB7> Set-Cookie <20><><EFBFBD><EFBFBD>ͷ<EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>þ<EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD>ExtractSetCookieHeaders<72><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Set-Cookie<69><65>ԭʼ<D4AD><CABC>Ӧͷ<D3A6><CDB7>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
void ParseFromSetCookieHeaders(const std::vector<std::string>& setCookieHeaders);
// <20><>cookie<69>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> name1=value1; name2=value2
void ParseFromCookieString(const std::string& cookieString);
// <20><>headers<72><73><EFBFBD><EFBFBD>ȡ Set-Cookie <20><><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ParseFromSetCookieHeaders<72><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
static std::vector<std::string> ExtractSetCookieHeaders(const std::string& rawHeaders);
// <20><><EFBFBD><EFBFBD> Cookie
void SetCookie(const Cookie& cookie);
// <20><><EFBFBD><EFBFBD> Cookie
void SetCookie(const std::string& name, const std::string& value);
// ɾ<><C9BE>
bool EraseCookie(const std::string& name);
// <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
bool IsExist(const std::string& name) const;
// ɾ<><C9BE>valueΪ<65>յ<EFBFBD>Cookie
void RemoveEmptyCookies();
// <20><>ȡCookieֵ
std::string GetCookieValue(const std::string& name) const;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::vector<std::string> GetAllKeys(bool ignoreNull = false) const;
// ת<><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ʽ
std::string ToRequestCookieString(bool ignoreNull = false) const;
// ת<><D7AA>Ϊ Set-Cookie <20><><EFBFBD><EFBFBD>ͷ
std::vector<std::string> ToSetCookieHeaders(bool ignoreNull = false) const;
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> Cookie <20><><EFBFBD><EFBFBD>
std::vector<Cookie> GetAllCookies(bool ignoreNull = false) const;
private:
std::map<std::string, Cookie> m_cookies;
static std::string Trim(const std::string& str);
};
#pragma endregion HttpCookiesWrapper
#pragma region HttpRequest
/// <summary>
/// HTTP<54><50>Ӧ<EFBFBD><D3A6><EFBFBD>ݽṹ<DDBD><E1B9B9>
/// </summary>
struct HttpResponse {
bool success = true;
std::string error = "";
std::string content = "";
int code = 0; // HTTP״̬<D7B4><CCAC>
std::string org_headers = ""; // ԭʼ<D4AD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧͷ
HttpHeadersWrapper headers;
HttpCookiesWrapper cookies;
int curl_code = 0; // curl<72><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
class HttpRequest {
public:
/// <summary>
/// <20><><EFBFBD><EFBFBD>GET<45><54><EFBFBD><EFBFBD>
/// </summary>
/// <param name="url">Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ַ</param>
/// <param name="headersEx">ÿ<><C3BF>ͷռһ<D5BC>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD> Content-Type: application/json</param>
/// <param name="proxy"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ</param>
/// <param name="ssl"><3E>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ssl<73><6C>֤<EFBFBD><D6A4>Ĭ<EFBFBD><C4AC>Ϊtrue</param>
/// <param name="lpfnCurlOptions"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һΪCURL*ָ<><D6B8></param>
/// <returns>HttpResponse</returns>
static HttpResponse Get(
_In_ std::string url,
_In_ std::string headersEx = "",
_In_ std::string proxy = "",
_In_ bool ssl = true,
_In_ std::function<void(CURL*)> lpfnCurlOptions = nullptr);
/// <summary>
/// <20><><EFBFBD><EFBFBD>POST<53><54><EFBFBD><EFBFBD>
/// </summary>
/// <param name="url">Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ַ</param>
/// <param name="postData">POST<53><54><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD></param>
/// <param name="headersEx">ÿ<><C3BF>ͷռһ<D5BC>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD> Content-Type: application/json</param>
/// <param name="proxy"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ</param>
/// <param name="ssl"><3E>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ssl<73><6C>֤<EFBFBD><D6A4>Ĭ<EFBFBD><C4AC>Ϊtrue</param>
/// <param name="lpfnCurlOptions"><3E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ú<EFBFBD><C3BA><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һΪCURL*ָ<><D6B8></param>
/// <returns></returns>
static HttpResponse Post(
_In_ std::string url,
_In_ std::string postData = "",
_In_ std::string headersEx = "",
_In_ std::string proxy = "",
_In_ bool ssl = true,
_In_ std::function<void(CURL*)> lpfnCurlOptions = nullptr);
};
#pragma endregion HttpRequest
}
}

View File

@@ -0,0 +1,112 @@
#include "jsoncpp_ex.h"
//#include "jsoncpp_ex_self.h"
namespace ytpp {
namespace json
{
std::string json_toString(_In_ const Json::Value & value)
{
Json::StreamWriterBuilder swb;
swb["emitUTF8"] = true;
unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
stringstream ss;
writer->write(value, &ss);
return ss.str();
}
std::string json_toString(
_In_ const Json::Value & value,
_In_ bool format)
{
Json::StreamWriterBuilder swb;
swb["emitUTF8"] = true;
if (!format) {
swb["indentation"] = "";
swb["commentStyle"] = "None";
}
unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
stringstream ss;
writer->write(value, &ss);
return ss.str();
}
std::string json_toStringEx(
_In_ const Json::Value & value,
_In_ bool commentStyle /*= "All"*/,
_In_ string indentation /*= " "*/,
_In_ bool enbleYAMLCompatibility /*= false*/,
_In_ bool dropNullPlaceholders /*= false*/,
_In_ bool useSpecialFloats /*= false*/,
_In_ int precision /*= 5*/,
_In_ string precisionType /*= "significant"*/,
_In_ bool emitUTF8 /*= false*/)
{
Json::StreamWriterBuilder swb;
swb["commentStyle"] = commentStyle;
swb["indentation"] = indentation;
swb["enableYAMLCompatibility"] = enbleYAMLCompatibility;
swb["dropNullPlaceholders"] = dropNullPlaceholders;
swb["useSpecialFloats"] = useSpecialFloats;
swb["precision"] = precision;
swb["precisionType"] = precisionType;
swb["emitUTF8"] = emitUTF8;
unique_ptr<Json::StreamWriter> writer(swb.newStreamWriter());
stringstream ss;
writer->write(value, &ss);
return ss.str();
}
bool json_fromString(
_In_ const string & jsonStr,
_Out_ Json::Value & value)
{
Json::Reader reader;
return reader.parse(jsonStr, value);
}
bool json_fromString(
_In_ const string & jsonStr,
_Out_ Json::Value & value,
_In_ bool collectComments)
{
Json::Reader reader;
return reader.parse(jsonStr, value, collectComments);
}
bool json_fromStringEx(
_In_ const string & jsonStr,
_Out_ Json::Value & value,
_Out_ Json::String & error,
_In_ bool collectComments /*= true*/,
_In_ bool allowComments /*= true*/,
_In_ bool allowTrailingCommas /*= true*/,
_In_ bool strictRoot /*= false*/,
_In_ bool allowDroppedNullPlaceholders /*= true*/,
_In_ bool allowNumericKeys /*= true*/,
_In_ bool allowSingleQuotes /*= true*/,
_In_ int stackLimit /*= 1024*/,
_In_ bool failIfExtra /*= false*/,
_In_ bool rejectDupKeys /*= false*/,
_In_ bool allowSpecialFloats /*= true*/,
_In_ bool skipBom /*= true */)
{
Json::CharReaderBuilder crb;
crb["collectComments"] = collectComments;
crb["allowComments"] = allowComments;
crb["allowTrailingCommas"] = allowTrailingCommas;
crb["strictRoot"] = strictRoot;
crb["allowDroppedNullPlaceholders"] = allowDroppedNullPlaceholders;
crb["allowNumericKeys"] = allowNumericKeys;
crb["allowSingleQuotes"] = allowSingleQuotes;
crb["stackLimit"] = stackLimit;
crb["failIfExtra"] = failIfExtra;
crb["rejectDupKeys"] = rejectDupKeys;
crb["allowSpecialFloats"] = allowSpecialFloats;
crb["skipBOM"] = skipBom;
unique_ptr<Json::CharReader> reader(crb.newCharReader());
return reader->parse(jsonStr.c_str(), jsonStr.c_str() + jsonStr.size(), &value, &error);
}
}
}

View File

@@ -0,0 +1,122 @@
#ifndef JSONCPP_EX_CPP
#define JSONCPP_EX_CPP
#include <string>
#include "json/json.h"
namespace ytpp {
namespace json
{
using namespace std;
/*
* @brief 将json的value对象转换为UTF8编码的字符串
* @param [in] value: 要转换的json对象
* @return UTF8编码的字符串
*/
string json_toString(_In_ const Json::Value & value);
/*
* @brief 将json的value对象转换为UTF8编码的字符串并指定是否进行格式化
* @param [in] value: 要转换的json对象
* @param [in] format: 是否进行格式化
* @return UTF8编码的字符串
*/
string json_toString(
_In_ const Json::Value & value,
_In_ bool format
);
/*
* @brief 【高级版本】将json的value对象转换为可选UTF8编码的字符串并指定所有可选参数
* @param [in] value: 要转换的json对象
* @param [in] commentStyle: 是否包含注释,取值:"None", "All"
* @param [in] indentation: 缩进字符
* @param [in] enbleYAMLCompatibility: 是否启用YAML兼容性稍微改变冒号周围的空白
* @param [in] dropNullPlaceholders: 是否删除null占位符
* @param [in] useSpecialFloats: 是否使用特殊浮点数为true时NaN值为"NaN",正无穷为"infinity",负无穷为"-infinity"
* @param [in] precision: 小数点精度,一个整数值
* @param [in] precisionType: 小数点精度类型,取值:"significant", "decimal"
* @param [in] emitUTF8: 是否输出UTF8编码
* @return 转换后的字符串
*/
string json_toStringEx(
_In_ const Json::Value & value,
_In_ bool commentStyle = "All",
_In_ string indentation = " ",
_In_ bool enbleYAMLCompatibility = false,
_In_ bool dropNullPlaceholders = false,
_In_ bool useSpecialFloats = false,
_In_ int precision = 5,
_In_ string precisionType = "significant",
_In_ bool emitUTF8 = false
);
/*
* @brief 将UTF8编码的字符串转换为json的value对象默认收集注释
* @brief 如果不想收集注释可以使用另一个重载版本的第二个参数填false即可
* @param [in] jsonStr: 要转换的UTF8编码的字符串
* @param [out] value: 转换后的json对象的引用
* @return 成功与否
*/
bool json_fromString(
_In_ const string & jsonStr,
_Out_ Json::Value & value
);
/*
* @brief 将UTF8编码的字符串转换为json的value对象并指定是否收集注释
* @param [in] jsonStr: 要转换的UTF8编码的字符串
* @param [out] value: 转换后的json对象的引用
* @param [in] collectComments: 是否收集注释
* @return 成功与否
*/
bool json_fromString(
_In_ const string & jsonStr,
_Out_ Json::Value & value,
_In_ bool collectComments
);
/*
* @brief 【高级版本】将UTF8编码的字符串转换为json的value对象并指定所有可选参数
* @brief 如果不想使用默认值,可以不填参数,使用默认值
* @param [in] jsonStr: 要转换的UTF8编码的字符串
* @param [out] value: 转换后的json对象的引用
* @param [out] error: 错误信息
* @param [in] collectComments: 是否收集注释如果allowComments为false则此参数无效
* @param [in] allowComments: 是否允许注释
* @param [in] allowTrailingCommas: 是否允许数组和对象尾部有多余的逗号
* @param [in] strictRoot: 是否严格检查根节点,如果根节点不是对象或数组,则抛出异常
* @param [in] allowDroppedNullPlaceholders: 是否允许null占位符和json_toStringEx函数中的dropNullPlaceholders参数对应
* @param [in] allowNumericKeys: 是否允许数字作为键
* @param [in] allowSingleQuotes: 是否允许字符串的键和值(即键和值使用单引号的时候)
* @param [in] stackLimit: 栈限制默认1024
* @param [in] failIfExtra: 如果填true则当输入字符串中的JSON值后面有额外的非空白时返回false
* @param [in] rejectDupKeys: 如果填true则当输入字符串中有重复的键时抛出异常
* @param [in] allowSpecialFloats: 是否允许特殊浮点数和json_toStringEx函数中的useSpecialFloats参数对应
* @param [in] skipBom: 如果填true则当输入以Unicode字节顺序标记(BOM)开头时,跳过它
* @return json的value对象
*/
bool json_fromStringEx(
_In_ const string & jsonStr,
_Out_ Json::Value & value,
_Out_ Json::String & error,
_In_ bool collectComments = true,
_In_ bool allowComments = true,
_In_ bool allowTrailingCommas = true,
_In_ bool strictRoot = false,
_In_ bool allowDroppedNullPlaceholders = true,
_In_ bool allowNumericKeys = true,
_In_ bool allowSingleQuotes = true,
_In_ int stackLimit = 1024,
_In_ bool failIfExtra = false,
_In_ bool rejectDupKeys = false,
_In_ bool allowSpecialFloats = true,
_In_ bool skipBom = true
);
}
}
#endif // JSONCPP_EX_CPP

View File

@@ -0,0 +1,167 @@
#include "utils/machine_feature.h"
#include "utils/string_ex.h"
#include "utils/hash.h"
#include <sstream>
#include <iostream>
#include <string>
#include <Windows.h>
#include <wbemidl.h>
#include <comdef.h>
#include <algorithm> // for std::transform
#include <cctype> // for std::tolower, std::toupper
#include <objbase.h> // for CoCreateGuid
#include <random>
#include <iomanip>
#pragma comment(lib, "wbemuuid.lib")
namespace ytpp {
namespace sys_core {
/// <summary>
/// <20><>wmi<6D><69><EFBFBD>в<EFBFBD>ѯ
/// </summary>
/// <param name="wql"></param>
/// <param name="field"></param>
/// <returns></returns>
std::string wmi_query(const std::string& wql, const std::string& field) {
HRESULT hr;
IWbemLocator* pLoc = nullptr;
IWbemServices* pSvc = nullptr;
IEnumWbemClassObject* pEnumerator = nullptr;
IWbemClassObject* pclsObj = nullptr;
ULONG uReturn = 0;
std::ostringstream result;
hr = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hr)) return "";
hr = CoInitializeSecurity(nullptr, -1, nullptr, nullptr,
RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
nullptr, EOAC_NONE, nullptr);
if (FAILED(hr)) return "";
hr = CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID*)&pLoc);
if (FAILED(hr)) return "";
hr = pLoc->ConnectServer(
BSTR(L"ROOT\\CIMV2"), nullptr, nullptr, 0, 0, 0, 0, &pSvc);
if (FAILED(hr)) return "";
hr = CoSetProxyBlanket(
pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr,
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);
if (FAILED(hr)) return "";
hr = pSvc->ExecQuery(
BSTR(L"WQL"), BSTR(std::wstring(wql.begin(), wql.end()).c_str()),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &pEnumerator);
if (FAILED(hr)) return "";
while (pEnumerator) {
hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn) break;
VARIANT vtProp;
hr = pclsObj->Get(BSTR(std::wstring(field.begin(), field.end()).c_str()), 0, &vtProp, 0, 0);
if (SUCCEEDED(hr) && (vtProp.vt == VT_BSTR)) {
result << _bstr_t(vtProp.bstrVal);
}
VariantClear(&vtProp);
pclsObj->Release();
}
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();
return result.str();
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <returns></returns>
std::string get_machine_features(bool cup, bool baseBoard, bool diskDrive, bool gpu, bool physicalMemory, bool mac) {
std::ostringstream features;
if(cup)features << "CPU:" << wmi_query("SELECT ProcessorId FROM Win32_Processor", "ProcessorId");
if (baseBoard)features << "\n<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << wmi_query("SELECT SerialNumber FROM Win32_BaseBoard", "SerialNumber");
if (diskDrive)features << "\nӲ<EFBFBD><EFBFBD>:" << wmi_query("SELECT SerialNumber FROM Win32_DiskDrive", "SerialNumber");
if (gpu)features << "\nGPU:" << wmi_query("SELECT PNPDeviceID FROM Win32_VideoController", "PNPDeviceID");
if (physicalMemory)features << "\nRAM:" << wmi_query("SELECT Capacity FROM Win32_PhysicalMemory", "Capacity");
if (mac)features << "\n<EFBFBD><EFBFBD><EFBFBD><EFBFBD>:" << wmi_query("SELECT MACAddress FROM Win32_NetworkAdapter WHERE MACAddress IS NOT NULL", "MACAddress");
return features.str();
}
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <returns></returns>
std::string get_machineCode(std::string signature, bool cup, bool baseBoard, bool diskDrive, bool gpu, bool physicalMemory, bool mac)
{
std::string machine_features = get_machine_features(cup, baseBoard, diskDrive, gpu, physicalMemory, mac);
//MessageBoxA(NULL, machine_features.c_str(), "machine_features", MB_OK);
if (!signature.empty()) {
machine_features += signature;
}
std::string machine_code = str_toupper(get_hash(machine_features));
//<2F><>machine_code<64><65><EFBFBD><EFBFBD>5<EFBFBD><35>Ϊһ<CEAA><D2BB><EFBFBD><EFBFBD><EFBFBD>зָÿ<EEA3AC><C3BF>֮<EFBFBD><D6AE><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD>
//for (int i = 5; i < machine_code.length(); i += 6) {
// machine_code.insert(i, "-");
//}
return machine_code;
}
std::string GenerateGuid(bool toLowercase) {
GUID guid;
CoCreateGuid(&guid);
// <20><>ʽ<EFBFBD><CABD>GUIDΪ<44><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD>ϴ<EFBFBD>д<EFBFBD><D0B4>
char buffer[32 + 1] = { 0 }; // 32<33>ַ<EFBFBD> + null<6C><6C>ֹ<EFBFBD><D6B9>
snprintf(buffer, sizeof(buffer),
"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
guid.Data1, guid.Data2, guid.Data3,
guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3],
guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
std::string result(buffer);
// <20><><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD>ת<EFBFBD><D7AA>ΪСд
if (toLowercase) {
std::transform(result.begin(), result.end(), result.begin(),
[](unsigned char c) { return std::tolower(c); });
}
return result;
}
std::string GenerateMachineGuid() {
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<uint32_t> dis(0, 0xFFFFFFFF); // 32λ<32>޷<EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ
std::ostringstream oss;
oss << std::hex << std::uppercase << std::setfill('0');
// <20><><EFBFBD><EFBFBD>7<EFBFBD><37>8<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ʮ<EFBFBD><CAAE><EFBFBD><EFBFBD><EFBFBD>ƶ<EFBFBD>
for (int i = 0; i < 7; ++i) {
uint32_t num = dis(gen);
oss << std::setw(8) << num; // ÿ<><C3BF><EFBFBD><EFBFBD>8<EFBFBD>ַ<EFBFBD>
if (i < 6) {
oss << "."; // <20>μ<EFBFBD><CEBC>õ<EFBFBD><C3B5>ŷָ<C5B7>
}
}
return oss.str();
}
}
}

View File

@@ -0,0 +1,39 @@
#ifndef _MACHINE_FEATURE_H_
#define _MACHINE_FEATURE_H_
#include <string>
#include "utils/machine_feature.h"
namespace ytpp {
namespace sys_core {
/// <summary>
/// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// </summary>
/// <returns></returns>
std::string get_machineCode(
std::string signature = "",
bool cup = true,
bool baseBoard = true,
bool diskDrive = true,
bool gpu = true,
bool physicalMemory = true,
bool mac = true
);
std::string GenerateGuid(bool toLowercase = true);
std::string GenerateMachineGuid();
}
}
#endif /* _MACHINE_FEATURE_H_ */

View File

@@ -0,0 +1,113 @@
#include "utils/string_ex.h"
#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <algorithm>
namespace ytpp {
namespace sys_core {
/// <summary>
/// <20>ָ<EFBFBD><D6B8>ı<EFBFBD>
/// </summary>
/// <param name="s"></param>
/// <param name="delimiter"></param>
/// <returns></returns>
std::vector<std::string> str_split(const std::string& s, char delimiter)
{
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(s);
while (std::getline(tokenStream, token, delimiter))
{
tokens.push_back(token);
}
return tokens;
}
/// <summary>
/// <20>ָ<EFBFBD><D6B8>ı<EFBFBD>
/// </summary>
/// <param name="s"></param>
/// <param name="delimiter"></param>
/// <returns></returns>
std::vector<std::string> str_split(const std::string& s, const std::string& delimiter) {
std::vector<std::string> tokens;
size_t start = 0;
size_t end = 0;
while (true) {
end = s.find(delimiter, start);
if (end == std::string::npos) {
tokens.push_back(s.substr(start));
break;
}
tokens.push_back(s.substr(start, end - start));
start = end + delimiter.length();
}
return tokens;
}
/// <summary>
/// <20><EFBFBD><E6BBBB><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>oldSubStr<74>滻ΪnewSubStr
/// </summary>
/// <param name="s"></param>
/// <param name="oldSubStr"></param>
/// <param name="newSubStr"></param>
/// <returns></returns>
std::string str_replace_subString(const std::string& s, const std::string& oldSubStr, const std::string& newSubStr)
{
std::string result = s;
size_t pos = result.find(oldSubStr);
while (pos != std::string::npos) {
result.replace(pos, oldSubStr.length(), newSubStr);
pos = result.find(oldSubStr, pos + newSubStr.length());
}
return result;
}
/// <summary>
/// ȥ<><C8A5><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD>ո<EFBFBD>
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
std::string str_trim(const std::string& s)
{
std::string result = s;
result.erase(0, result.find_first_not_of(" "));
result.erase(result.find_last_not_of(" ") + 1);
return result;
}
/// <summary>
/// <20><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA>д
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
std::string str_toupper(const std::string& s)
{
std::string result = s;
std::transform(result.begin(), result.end(), result.begin(), std::toupper);
return result;
}
/// <summary>
/// <20><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>ΪСд
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
std::string str_tolower(const std::string& s)
{
std::string result = s;
std::transform(result.begin(), result.end(), result.begin(), std::tolower);
return result;
}
}
}

View File

@@ -0,0 +1,59 @@
#ifndef _STRINGEX_H_
#define _STRINGEX_H_
#include <vector>
#include <string>
namespace ytpp {
namespace sys_core {
/// <summary>
/// <20>ָ<EFBFBD><D6B8>ı<EFBFBD>
/// </summary>
/// <param name="s"></param>
/// <param name="delimiter"></param>
/// <returns></returns>
std::vector<std::string> str_split(const std::string& s, char delimiter);
/// <summary>
/// <20>ָ<EFBFBD><D6B8>ı<EFBFBD>
/// </summary>
/// <param name="s"></param>
/// <param name="delimiter"></param>
/// <returns></returns>
std::vector<std::string> str_split(const std::string& s, const std::string& delimiter);
/// <summary>
/// <20><EFBFBD><E6BBBB><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>oldSubStr<74>滻ΪnewSubStr
/// </summary>
/// <param name="s"></param>
/// <param name="oldSubStr"></param>
/// <param name="newSubStr"></param>
/// <returns></returns>
std::string str_replace_subString(const std::string& s, const std::string& oldSubStr, const std::string& newSubStr);
/// <summary>
/// ȥ<><C8A5><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD>ո<EFBFBD>
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
std::string str_trim(const std::string& s);
/// <summary>
/// <20><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>Ϊ<EFBFBD><CEAA>д
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
std::string str_toupper(const std::string& s);
/// <summary>
/// <20><><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>ת<EFBFBD><D7AA>ΪСд
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
std::string str_tolower(const std::string& s);
}
}
#endif /* _STRINGEX_H_ */

View File

@@ -0,0 +1,37 @@
#include "WriteResourceFile.h"
#include <windows.h>
#include <iostream>
using namespace std;
bool WriteResourceFile(HMODULE hModule, int resID, string resType, string outPath) {
HRSRC hResource = FindResourceA(hModule, MAKEINTRESOURCEA(resID), resType.c_str());
if (hResource == NULL) {
cout << "WriteResourceFile - Ѱ<>ұ<EFBFBD>Ҫ<EFBFBD><D2AA>Դʧ<D4B4><CAA7>" << endl;
return false;
}
HGLOBAL hGlobal = LoadResource(hModule, hResource);
if (hGlobal == NULL) {
cout << "WriteResourceFile - <20><><EFBFBD>ر<EFBFBD>Ҫ<EFBFBD><D2AA>Դʧ<D4B4><CAA7>" << endl;
return false;
}
DWORD dwSize = SizeofResource(hModule, hResource);
if (dwSize == 0) {
cout << "WriteResourceFile - <20><>ȡ<EFBFBD><C8A1>Ҫ<EFBFBD><D2AA>Դ<EFBFBD><D4B4>Сʧ<D0A1><CAA7>" << endl;
return false;
}
void* pResource = LockResource(hGlobal);
if (pResource == NULL) {
cout << "WriteResourceFile - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>Դʧ<D4B4><CAA7>" << endl;
return false;
}
FILE* pFile = nullptr;
fopen_s(&pFile, outPath.c_str(), "wb");
if (pFile == NULL) {
cout << "WriteResourceFile - д<><D0B4><EFBFBD><EFBFBD>Դ<EFBFBD>ļ<EFBFBD>ʧ<EFBFBD><CAA7>" << endl;
return false;
}
fwrite(pResource, 1, dwSize, pFile);
fclose(pFile);
UnlockResource(pResource);
return true;
}

View File

@@ -0,0 +1,6 @@
#pragma once
#include <string>
#include <Windows.h>
using namespace std;
bool WriteResourceFile(HMODULE hModule, int resID, string resType, string outPath);

View File

@@ -0,0 +1,204 @@
/* 7z.h -- 7z interface
2023-04-02 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_7Z_H
#define ZIP7_INC_7Z_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define k7zStartHeaderSize 0x20
#define k7zSignatureSize 6
extern const Byte k7zSignature[k7zSignatureSize];
typedef struct
{
const Byte *Data;
size_t Size;
} CSzData;
/* CSzCoderInfo & CSzFolder support only default methods */
typedef struct
{
size_t PropsOffset;
UInt32 MethodID;
Byte NumStreams;
Byte PropsSize;
} CSzCoderInfo;
typedef struct
{
UInt32 InIndex;
UInt32 OutIndex;
} CSzBond;
#define SZ_NUM_CODERS_IN_FOLDER_MAX 4
#define SZ_NUM_BONDS_IN_FOLDER_MAX 3
#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4
typedef struct
{
UInt32 NumCoders;
UInt32 NumBonds;
UInt32 NumPackStreams;
UInt32 UnpackStream;
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder;
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
typedef struct
{
UInt32 Low;
UInt32 High;
} CNtfsFileTime;
typedef struct
{
Byte *Defs; /* MSB 0 bit numbering */
UInt32 *Vals;
} CSzBitUi32s;
typedef struct
{
Byte *Defs; /* MSB 0 bit numbering */
// UInt64 *Vals;
CNtfsFileTime *Vals;
} CSzBitUi64s;
#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
typedef struct
{
UInt32 NumPackStreams;
UInt32 NumFolders;
UInt64 *PackPositions; // NumPackStreams + 1
CSzBitUi32s FolderCRCs; // NumFolders
size_t *FoCodersOffsets; // NumFolders + 1
UInt32 *FoStartPackStreamIndex; // NumFolders + 1
UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
Byte *FoToMainUnpackSizeIndex; // NumFolders
UInt64 *CoderUnpackSizes; // for all coders in all folders
Byte *CodersData;
UInt64 RangeLimit;
} CSzAr;
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStreamPtr stream, UInt64 startPos,
Byte *outBuffer, size_t outSize,
ISzAllocPtr allocMain);
typedef struct
{
CSzAr db;
UInt64 startPosAfterHeader;
UInt64 dataPos;
UInt32 NumFiles;
UInt64 *UnpackPositions; // NumFiles + 1
// Byte *IsEmptyFiles;
Byte *IsDirs;
CSzBitUi32s CRCs;
CSzBitUi32s Attribs;
// CSzBitUi32s Parents;
CSzBitUi64s MTime;
CSzBitUi64s CTime;
UInt32 *FolderToFile; // NumFolders + 1
UInt32 *FileToFolder; // NumFiles
size_t *FileNameOffsets; /* in 2-byte steps */
Byte *FileNames; /* UTF-16-LE */
} CSzArEx;
#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i))
#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
void SzArEx_Init(CSzArEx *p);
void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc);
UInt64 SzArEx_GetFolderStreamPos(const CSzArEx *p, UInt32 folderIndex, UInt32 indexInFolder);
int SzArEx_GetFolderFullPackSize(const CSzArEx *p, UInt32 folderIndex, UInt64 *resSize);
/*
if dest == NULL, the return value specifies the required size of the buffer,
in 16-bit characters, including the null-terminating character.
if dest != NULL, the return value specifies the number of 16-bit characters that
are written to the dest, including the null-terminating character. */
size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
/*
size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
*/
/*
SzArEx_Extract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
SRes SzArEx_Extract(
const CSzArEx *db,
ILookInStreamPtr inStream,
UInt32 fileIndex, /* index of file */
UInt32 *blockIndex, /* index of solid block */
Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
size_t *outBufferSize, /* buffer size for output buffer */
size_t *offset, /* offset of stream for required file in *outBuffer */
size_t *outSizeProcessed, /* size of file in *outBuffer */
ISzAllocPtr allocMain,
ISzAllocPtr allocTemp);
/*
SzArEx_Open Errors:
SZ_ERROR_NO_ARCHIVE
SZ_ERROR_ARCHIVE
SZ_ERROR_UNSUPPORTED
SZ_ERROR_MEM
SZ_ERROR_CRC
SZ_ERROR_INPUT_EOF
SZ_ERROR_FAIL
*/
SRes SzArEx_Open(CSzArEx *p, ILookInStreamPtr inStream,
ISzAllocPtr allocMain, ISzAllocPtr allocTemp);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,19 @@
/* 7zAlloc.h -- Allocation functions
2023-03-04 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_7Z_ALLOC_H
#define ZIP7_INC_7Z_ALLOC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
void *SzAlloc(ISzAllocPtr p, size_t size);
void SzFree(ISzAllocPtr p, void *address);
void *SzAllocTemp(ISzAllocPtr p, size_t size);
void SzFreeTemp(ISzAllocPtr p, void *address);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,35 @@
/* 7zBuf.h -- Byte Buffer
2023-03-04 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_7Z_BUF_H
#define ZIP7_INC_7Z_BUF_H
#include "7zTypes.h"
EXTERN_C_BEGIN
typedef struct
{
Byte *data;
size_t size;
} CBuf;
void Buf_Init(CBuf *p);
int Buf_Create(CBuf *p, size_t size, ISzAllocPtr alloc);
void Buf_Free(CBuf *p, ISzAllocPtr alloc);
typedef struct
{
Byte *data;
size_t size;
size_t pos;
} CDynBuf;
void DynBuf_Construct(CDynBuf *p);
void DynBuf_SeekToBeg(CDynBuf *p);
int DynBuf_Write(CDynBuf *p, const Byte *buf, size_t size, ISzAllocPtr alloc);
void DynBuf_Free(CDynBuf *p, ISzAllocPtr alloc);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,28 @@
/* 7zCrc.h -- CRC32 calculation
2024-01-22 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_7Z_CRC_H
#define ZIP7_INC_7Z_CRC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
extern UInt32 g_CrcTable[];
/* Call CrcGenerateTable one time before other CRC functions */
void Z7_FASTCALL CrcGenerateTable(void);
#define CRC_INIT_VAL 0xFFFFFFFF
#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
UInt32 Z7_FASTCALL CrcUpdate(UInt32 crc, const void *data, size_t size);
UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size);
typedef UInt32 (Z7_FASTCALL *Z7_CRC_UPDATE_FUNC)(UInt32 v, const void *data, size_t size);
Z7_CRC_UPDATE_FUNC z7_GetFunc_CrcUpdate(unsigned algo);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,92 @@
/* 7zFile.h -- File IO
2023-03-05 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_FILE_H
#define ZIP7_INC_FILE_H
#ifdef _WIN32
#define USE_WINDOWS_FILE
// #include <windows.h>
#endif
#ifdef USE_WINDOWS_FILE
#include "7zWindows.h"
#else
// note: USE_FOPEN mode is limited to 32-bit file size
// #define USE_FOPEN
// #include <stdio.h>
#endif
#include "7zTypes.h"
EXTERN_C_BEGIN
/* ---------- File ---------- */
typedef struct
{
#ifdef USE_WINDOWS_FILE
HANDLE handle;
#elif defined(USE_FOPEN)
FILE *file;
#else
int fd;
#endif
} CSzFile;
void File_Construct(CSzFile *p);
#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE)
WRes InFile_Open(CSzFile *p, const char *name);
WRes OutFile_Open(CSzFile *p, const char *name);
#endif
#ifdef USE_WINDOWS_FILE
WRes InFile_OpenW(CSzFile *p, const WCHAR *name);
WRes OutFile_OpenW(CSzFile *p, const WCHAR *name);
#endif
WRes File_Close(CSzFile *p);
/* reads max(*size, remain file's size) bytes */
WRes File_Read(CSzFile *p, void *data, size_t *size);
/* writes *size bytes */
WRes File_Write(CSzFile *p, const void *data, size_t *size);
WRes File_Seek(CSzFile *p, Int64 *pos, ESzSeek origin);
WRes File_GetLength(CSzFile *p, UInt64 *length);
/* ---------- FileInStream ---------- */
typedef struct
{
ISeqInStream vt;
CSzFile file;
WRes wres;
} CFileSeqInStream;
void FileSeqInStream_CreateVTable(CFileSeqInStream *p);
typedef struct
{
ISeekInStream vt;
CSzFile file;
WRes wres;
} CFileInStream;
void FileInStream_CreateVTable(CFileInStream *p);
typedef struct
{
ISeqOutStream vt;
CSzFile file;
WRes wres;
} CFileOutStream;
void FileOutStream_CreateVTable(CFileOutStream *p);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,597 @@
/* 7zTypes.h -- Basic types
2024-01-24 : Igor Pavlov : Public domain */
#ifndef ZIP7_7Z_TYPES_H
#define ZIP7_7Z_TYPES_H
#ifdef _WIN32
/* #include <windows.h> */
#else
#include <errno.h>
#endif
#include <stddef.h>
#ifndef EXTERN_C_BEGIN
#ifdef __cplusplus
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C_BEGIN
#define EXTERN_C_END
#endif
#endif
EXTERN_C_BEGIN
#define SZ_OK 0
#define SZ_ERROR_DATA 1
#define SZ_ERROR_MEM 2
#define SZ_ERROR_CRC 3
#define SZ_ERROR_UNSUPPORTED 4
#define SZ_ERROR_PARAM 5
#define SZ_ERROR_INPUT_EOF 6
#define SZ_ERROR_OUTPUT_EOF 7
#define SZ_ERROR_READ 8
#define SZ_ERROR_WRITE 9
#define SZ_ERROR_PROGRESS 10
#define SZ_ERROR_FAIL 11
#define SZ_ERROR_THREAD 12
#define SZ_ERROR_ARCHIVE 16
#define SZ_ERROR_NO_ARCHIVE 17
typedef int SRes;
#ifdef _MSC_VER
#if _MSC_VER > 1200
#define MY_ALIGN(n) __declspec(align(n))
#else
#define MY_ALIGN(n)
#endif
#else
/*
// C11/C++11:
#include <stdalign.h>
#define MY_ALIGN(n) alignas(n)
*/
#define MY_ALIGN(n) __attribute__ ((aligned(n)))
#endif
#ifdef _WIN32
/* typedef DWORD WRes; */
typedef unsigned WRes;
#define MY_SRes_HRESULT_FROM_WRes(x) HRESULT_FROM_WIN32(x)
// #define MY_HRES_ERROR_INTERNAL_ERROR MY_SRes_HRESULT_FROM_WRes(ERROR_INTERNAL_ERROR)
#else // _WIN32
// #define ENV_HAVE_LSTAT
typedef int WRes;
// (FACILITY_ERRNO = 0x800) is 7zip's FACILITY constant to represent (errno) errors in HRESULT
#define MY_FACILITY_ERRNO 0x800
#define MY_FACILITY_WIN32 7
#define MY_FACILITY_WRes MY_FACILITY_ERRNO
#define MY_HRESULT_FROM_errno_CONST_ERROR(x) ((HRESULT)( \
( (HRESULT)(x) & 0x0000FFFF) \
| (MY_FACILITY_WRes << 16) \
| (HRESULT)0x80000000 ))
#define MY_SRes_HRESULT_FROM_WRes(x) \
((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : MY_HRESULT_FROM_errno_CONST_ERROR(x))
// we call macro HRESULT_FROM_WIN32 for system errors (WRes) that are (errno)
#define HRESULT_FROM_WIN32(x) MY_SRes_HRESULT_FROM_WRes(x)
/*
#define ERROR_FILE_NOT_FOUND 2L
#define ERROR_ACCESS_DENIED 5L
#define ERROR_NO_MORE_FILES 18L
#define ERROR_LOCK_VIOLATION 33L
#define ERROR_FILE_EXISTS 80L
#define ERROR_DISK_FULL 112L
#define ERROR_NEGATIVE_SEEK 131L
#define ERROR_ALREADY_EXISTS 183L
#define ERROR_DIRECTORY 267L
#define ERROR_TOO_MANY_POSTS 298L
#define ERROR_INTERNAL_ERROR 1359L
#define ERROR_INVALID_REPARSE_DATA 4392L
#define ERROR_REPARSE_TAG_INVALID 4393L
#define ERROR_REPARSE_TAG_MISMATCH 4394L
*/
// we use errno equivalents for some WIN32 errors:
#define ERROR_INVALID_PARAMETER EINVAL
#define ERROR_INVALID_FUNCTION EINVAL
#define ERROR_ALREADY_EXISTS EEXIST
#define ERROR_FILE_EXISTS EEXIST
#define ERROR_PATH_NOT_FOUND ENOENT
#define ERROR_FILE_NOT_FOUND ENOENT
#define ERROR_DISK_FULL ENOSPC
// #define ERROR_INVALID_HANDLE EBADF
// we use FACILITY_WIN32 for errors that has no errno equivalent
// Too many posts were made to a semaphore.
#define ERROR_TOO_MANY_POSTS ((HRESULT)0x8007012AL)
#define ERROR_INVALID_REPARSE_DATA ((HRESULT)0x80071128L)
#define ERROR_REPARSE_TAG_INVALID ((HRESULT)0x80071129L)
// if (MY_FACILITY_WRes != FACILITY_WIN32),
// we use FACILITY_WIN32 for COM errors:
#define E_OUTOFMEMORY ((HRESULT)0x8007000EL)
#define E_INVALIDARG ((HRESULT)0x80070057L)
#define MY_E_ERROR_NEGATIVE_SEEK ((HRESULT)0x80070083L)
/*
// we can use FACILITY_ERRNO for some COM errors, that have errno equivalents:
#define E_OUTOFMEMORY MY_HRESULT_FROM_errno_CONST_ERROR(ENOMEM)
#define E_INVALIDARG MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
#define MY_E_ERROR_NEGATIVE_SEEK MY_HRESULT_FROM_errno_CONST_ERROR(EINVAL)
*/
#define TEXT(quote) quote
#define FILE_ATTRIBUTE_READONLY 0x0001
#define FILE_ATTRIBUTE_HIDDEN 0x0002
#define FILE_ATTRIBUTE_SYSTEM 0x0004
#define FILE_ATTRIBUTE_DIRECTORY 0x0010
#define FILE_ATTRIBUTE_ARCHIVE 0x0020
#define FILE_ATTRIBUTE_DEVICE 0x0040
#define FILE_ATTRIBUTE_NORMAL 0x0080
#define FILE_ATTRIBUTE_TEMPORARY 0x0100
#define FILE_ATTRIBUTE_SPARSE_FILE 0x0200
#define FILE_ATTRIBUTE_REPARSE_POINT 0x0400
#define FILE_ATTRIBUTE_COMPRESSED 0x0800
#define FILE_ATTRIBUTE_OFFLINE 0x1000
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x2000
#define FILE_ATTRIBUTE_ENCRYPTED 0x4000
#define FILE_ATTRIBUTE_UNIX_EXTENSION 0x8000 /* trick for Unix */
#endif
#ifndef RINOK
#define RINOK(x) { const int _result_ = (x); if (_result_ != 0) return _result_; }
#endif
#ifndef RINOK_WRes
#define RINOK_WRes(x) { const WRes _result_ = (x); if (_result_ != 0) return _result_; }
#endif
typedef unsigned char Byte;
typedef short Int16;
typedef unsigned short UInt16;
#ifdef Z7_DECL_Int32_AS_long
typedef long Int32;
typedef unsigned long UInt32;
#else
typedef int Int32;
typedef unsigned int UInt32;
#endif
#ifndef _WIN32
typedef int INT;
typedef Int32 INT32;
typedef unsigned int UINT;
typedef UInt32 UINT32;
typedef INT32 LONG; // LONG, ULONG and DWORD must be 32-bit for _WIN32 compatibility
typedef UINT32 ULONG;
#undef DWORD
typedef UINT32 DWORD;
#define VOID void
#define HRESULT LONG
typedef void *LPVOID;
// typedef void VOID;
// typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
// gcc / clang on Unix : sizeof(long==sizeof(void*) in 32 or 64 bits)
typedef long INT_PTR;
typedef unsigned long UINT_PTR;
typedef long LONG_PTR;
typedef unsigned long DWORD_PTR;
typedef size_t SIZE_T;
#endif // _WIN32
#define MY_HRES_ERROR_INTERNAL_ERROR ((HRESULT)0x8007054FL)
#ifdef Z7_DECL_Int64_AS_long
typedef long Int64;
typedef unsigned long UInt64;
#else
#if (defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(__clang__)
typedef __int64 Int64;
typedef unsigned __int64 UInt64;
#else
#if defined(__clang__) || defined(__GNUC__)
#include <stdint.h>
typedef int64_t Int64;
typedef uint64_t UInt64;
#else
typedef long long int Int64;
typedef unsigned long long int UInt64;
// #define UINT64_CONST(n) n ## ULL
#endif
#endif
#endif
#define UINT64_CONST(n) n
#ifdef Z7_DECL_SizeT_AS_unsigned_int
typedef unsigned int SizeT;
#else
typedef size_t SizeT;
#endif
/*
#if (defined(_MSC_VER) && _MSC_VER <= 1200)
typedef size_t MY_uintptr_t;
#else
#include <stdint.h>
typedef uintptr_t MY_uintptr_t;
#endif
*/
typedef int BoolInt;
/* typedef BoolInt Bool; */
#define True 1
#define False 0
#ifdef _WIN32
#define Z7_STDCALL __stdcall
#else
#define Z7_STDCALL
#endif
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define Z7_NO_INLINE __declspec(noinline)
#else
#define Z7_NO_INLINE
#endif
#define Z7_FORCE_INLINE __forceinline
#define Z7_CDECL __cdecl
#define Z7_FASTCALL __fastcall
#else // _MSC_VER
#if (defined(__GNUC__) && (__GNUC__ >= 4)) \
|| (defined(__clang__) && (__clang_major__ >= 4)) \
|| defined(__INTEL_COMPILER) \
|| defined(__xlC__)
#define Z7_NO_INLINE __attribute__((noinline))
#define Z7_FORCE_INLINE __attribute__((always_inline)) inline
#else
#define Z7_NO_INLINE
#define Z7_FORCE_INLINE
#endif
#define Z7_CDECL
#if defined(_M_IX86) \
|| defined(__i386__)
// #define Z7_FASTCALL __attribute__((fastcall))
// #define Z7_FASTCALL __attribute__((cdecl))
#define Z7_FASTCALL
#elif defined(MY_CPU_AMD64)
// #define Z7_FASTCALL __attribute__((ms_abi))
#define Z7_FASTCALL
#else
#define Z7_FASTCALL
#endif
#endif // _MSC_VER
/* The following interfaces use first parameter as pointer to structure */
// #define Z7_C_IFACE_CONST_QUAL
#define Z7_C_IFACE_CONST_QUAL const
#define Z7_C_IFACE_DECL(a) \
struct a ## _; \
typedef Z7_C_IFACE_CONST_QUAL struct a ## _ * a ## Ptr; \
typedef struct a ## _ a; \
struct a ## _
Z7_C_IFACE_DECL (IByteIn)
{
Byte (*Read)(IByteInPtr p); /* reads one byte, returns 0 in case of EOF or error */
};
#define IByteIn_Read(p) (p)->Read(p)
Z7_C_IFACE_DECL (IByteOut)
{
void (*Write)(IByteOutPtr p, Byte b);
};
#define IByteOut_Write(p, b) (p)->Write(p, b)
Z7_C_IFACE_DECL (ISeqInStream)
{
SRes (*Read)(ISeqInStreamPtr p, void *buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) < input(*size)) is allowed */
};
#define ISeqInStream_Read(p, buf, size) (p)->Read(p, buf, size)
/* try to read as much as avail in stream and limited by (*processedSize) */
SRes SeqInStream_ReadMax(ISeqInStreamPtr stream, void *buf, size_t *processedSize);
/* it can return SZ_ERROR_INPUT_EOF */
// SRes SeqInStream_Read(ISeqInStreamPtr stream, void *buf, size_t size);
// SRes SeqInStream_Read2(ISeqInStreamPtr stream, void *buf, size_t size, SRes errorType);
SRes SeqInStream_ReadByte(ISeqInStreamPtr stream, Byte *buf);
Z7_C_IFACE_DECL (ISeqOutStream)
{
size_t (*Write)(ISeqOutStreamPtr p, const void *buf, size_t size);
/* Returns: result - the number of actually written bytes.
(result < size) means error */
};
#define ISeqOutStream_Write(p, buf, size) (p)->Write(p, buf, size)
typedef enum
{
SZ_SEEK_SET = 0,
SZ_SEEK_CUR = 1,
SZ_SEEK_END = 2
} ESzSeek;
Z7_C_IFACE_DECL (ISeekInStream)
{
SRes (*Read)(ISeekInStreamPtr p, void *buf, size_t *size); /* same as ISeqInStream::Read */
SRes (*Seek)(ISeekInStreamPtr p, Int64 *pos, ESzSeek origin);
};
#define ISeekInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ISeekInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
Z7_C_IFACE_DECL (ILookInStream)
{
SRes (*Look)(ILookInStreamPtr p, const void **buf, size_t *size);
/* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
(output(*size) > input(*size)) is not allowed
(output(*size) < input(*size)) is allowed */
SRes (*Skip)(ILookInStreamPtr p, size_t offset);
/* offset must be <= output(*size) of Look */
SRes (*Read)(ILookInStreamPtr p, void *buf, size_t *size);
/* reads directly (without buffer). It's same as ISeqInStream::Read */
SRes (*Seek)(ILookInStreamPtr p, Int64 *pos, ESzSeek origin);
};
#define ILookInStream_Look(p, buf, size) (p)->Look(p, buf, size)
#define ILookInStream_Skip(p, offset) (p)->Skip(p, offset)
#define ILookInStream_Read(p, buf, size) (p)->Read(p, buf, size)
#define ILookInStream_Seek(p, pos, origin) (p)->Seek(p, pos, origin)
SRes LookInStream_LookRead(ILookInStreamPtr stream, void *buf, size_t *size);
SRes LookInStream_SeekTo(ILookInStreamPtr stream, UInt64 offset);
/* reads via ILookInStream::Read */
SRes LookInStream_Read2(ILookInStreamPtr stream, void *buf, size_t size, SRes errorType);
SRes LookInStream_Read(ILookInStreamPtr stream, void *buf, size_t size);
typedef struct
{
ILookInStream vt;
ISeekInStreamPtr realStream;
size_t pos;
size_t size; /* it's data size */
/* the following variables must be set outside */
Byte *buf;
size_t bufSize;
} CLookToRead2;
void LookToRead2_CreateVTable(CLookToRead2 *p, int lookahead);
#define LookToRead2_INIT(p) { (p)->pos = (p)->size = 0; }
typedef struct
{
ISeqInStream vt;
ILookInStreamPtr realStream;
} CSecToLook;
void SecToLook_CreateVTable(CSecToLook *p);
typedef struct
{
ISeqInStream vt;
ILookInStreamPtr realStream;
} CSecToRead;
void SecToRead_CreateVTable(CSecToRead *p);
Z7_C_IFACE_DECL (ICompressProgress)
{
SRes (*Progress)(ICompressProgressPtr p, UInt64 inSize, UInt64 outSize);
/* Returns: result. (result != SZ_OK) means break.
Value (UInt64)(Int64)-1 for size means unknown value. */
};
#define ICompressProgress_Progress(p, inSize, outSize) (p)->Progress(p, inSize, outSize)
typedef struct ISzAlloc ISzAlloc;
typedef const ISzAlloc * ISzAllocPtr;
struct ISzAlloc
{
void *(*Alloc)(ISzAllocPtr p, size_t size);
void (*Free)(ISzAllocPtr p, void *address); /* address can be 0 */
};
#define ISzAlloc_Alloc(p, size) (p)->Alloc(p, size)
#define ISzAlloc_Free(p, a) (p)->Free(p, a)
/* deprecated */
#define IAlloc_Alloc(p, size) ISzAlloc_Alloc(p, size)
#define IAlloc_Free(p, a) ISzAlloc_Free(p, a)
#ifndef MY_offsetof
#ifdef offsetof
#define MY_offsetof(type, m) offsetof(type, m)
/*
#define MY_offsetof(type, m) FIELD_OFFSET(type, m)
*/
#else
#define MY_offsetof(type, m) ((size_t)&(((type *)0)->m))
#endif
#endif
#ifndef Z7_container_of
/*
#define Z7_container_of(ptr, type, m) container_of(ptr, type, m)
#define Z7_container_of(ptr, type, m) CONTAINING_RECORD(ptr, type, m)
#define Z7_container_of(ptr, type, m) ((type *)((char *)(ptr) - offsetof(type, m)))
#define Z7_container_of(ptr, type, m) (&((type *)0)->m == (ptr), ((type *)(((char *)(ptr)) - MY_offsetof(type, m))))
*/
/*
GCC shows warning: "perhaps the 'offsetof' macro was used incorrectly"
GCC 3.4.4 : classes with constructor
GCC 4.8.1 : classes with non-public variable members"
*/
#define Z7_container_of(ptr, type, m) \
((type *)(void *)((char *)(void *) \
(1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m)))
#define Z7_container_of_CONST(ptr, type, m) \
((const type *)(const void *)((const char *)(const void *) \
(1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m)))
/*
#define Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m) \
((type *)(void *)(const void *)((const char *)(const void *) \
(1 ? (ptr) : &((type *)NULL)->m) - MY_offsetof(type, m)))
*/
#endif
#define Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m) ((type *)(void *)(ptr))
// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
#define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of(ptr, type, m)
// #define Z7_CONTAINER_FROM_VTBL(ptr, type, m) Z7_container_of_NON_CONST_FROM_CONST(ptr, type, m)
#define Z7_CONTAINER_FROM_VTBL_CONST(ptr, type, m) Z7_container_of_CONST(ptr, type, m)
#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL_SIMPLE(ptr, type, m)
/*
#define Z7_CONTAINER_FROM_VTBL_CLS(ptr, type, m) Z7_CONTAINER_FROM_VTBL(ptr, type, m)
*/
#if defined (__clang__) || defined(__GNUC__)
#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL \
_Pragma("GCC diagnostic pop")
#else
#define Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL
#define Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL
#endif
#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(ptr, type, m, p) \
Z7_DIAGNOSTIC_IGNORE_BEGIN_CAST_QUAL \
type *p = Z7_CONTAINER_FROM_VTBL(ptr, type, m); \
Z7_DIAGNOSTIC_IGNORE_END_CAST_QUAL
#define Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR_pp_vt_p(type) \
Z7_CONTAINER_FROM_VTBL_TO_DECL_VAR(pp, type, vt, p)
// #define ZIP7_DECLARE_HANDLE(name) typedef void *name;
#define Z7_DECLARE_HANDLE(name) struct name##_dummy{int unused;}; typedef struct name##_dummy *name;
#define Z7_memset_0_ARRAY(a) memset((a), 0, sizeof(a))
#ifndef Z7_ARRAY_SIZE
#define Z7_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif
#ifdef _WIN32
#define CHAR_PATH_SEPARATOR '\\'
#define WCHAR_PATH_SEPARATOR L'\\'
#define STRING_PATH_SEPARATOR "\\"
#define WSTRING_PATH_SEPARATOR L"\\"
#else
#define CHAR_PATH_SEPARATOR '/'
#define WCHAR_PATH_SEPARATOR L'/'
#define STRING_PATH_SEPARATOR "/"
#define WSTRING_PATH_SEPARATOR L"/"
#endif
#define k_PropVar_TimePrec_0 0
#define k_PropVar_TimePrec_Unix 1
#define k_PropVar_TimePrec_DOS 2
#define k_PropVar_TimePrec_HighPrec 3
#define k_PropVar_TimePrec_Base 16
#define k_PropVar_TimePrec_100ns (k_PropVar_TimePrec_Base + 7)
#define k_PropVar_TimePrec_1ns (k_PropVar_TimePrec_Base + 9)
EXTERN_C_END
#endif
/*
#ifndef Z7_ST
#ifdef _7ZIP_ST
#define Z7_ST
#endif
#endif
*/

View File

@@ -0,0 +1,27 @@
#define MY_VER_MAJOR 24
#define MY_VER_MINOR 9
#define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "24.09"
#define MY_VERSION MY_VERSION_NUMBERS
#ifdef MY_CPU_NAME
#define MY_VERSION_CPU MY_VERSION " (" MY_CPU_NAME ")"
#else
#define MY_VERSION_CPU MY_VERSION
#endif
#define MY_DATE "2024-11-29"
#undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2024 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR
#else
#define MY_COPYRIGHT MY_COPYRIGHT_PD
#endif
#define MY_COPYRIGHT_DATE MY_COPYRIGHT " : " MY_DATE
#define MY_VERSION_COPYRIGHT_DATE MY_VERSION_CPU " : " MY_COPYRIGHT " : " MY_DATE

View File

@@ -0,0 +1,101 @@
/* 7zWindows.h -- StdAfx
2023-04-02 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_7Z_WINDOWS_H
#define ZIP7_INC_7Z_WINDOWS_H
#ifdef _WIN32
#if defined(__clang__)
# pragma clang diagnostic push
#endif
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable : 4668) // '_WIN32_WINNT' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
#if _MSC_VER == 1900
// for old kit10 versions
// #pragma warning(disable : 4255) // winuser.h(13979): warning C4255: 'GetThreadDpiAwarenessContext':
#endif
// win10 Windows Kit:
#endif // _MSC_VER
#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64)
// for msvc6 without sdk2003
#define RPC_NO_WINDOWS_H
#endif
#if defined(__MINGW32__) || defined(__MINGW64__)
// #if defined(__GNUC__) && !defined(__clang__)
#include <windows.h>
#else
#include <Windows.h>
#endif
// #include <basetsd.h>
// #include <wtypes.h>
// but if precompiled with clang-cl then we need
// #include <windows.h>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#if defined(__clang__)
# pragma clang diagnostic pop
#endif
#if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_WIN64)
#ifndef _W64
typedef long LONG_PTR, *PLONG_PTR;
typedef unsigned long ULONG_PTR, *PULONG_PTR;
typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR;
#define Z7_OLD_WIN_SDK
#endif // _W64
#endif // _MSC_VER == 1200
#ifdef Z7_OLD_WIN_SDK
#ifndef INVALID_FILE_ATTRIBUTES
#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
#endif
#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER ((DWORD)-1)
#endif
#ifndef FILE_SPECIAL_ACCESS
#define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS)
#endif
// ShlObj.h:
// #define BIF_NEWDIALOGSTYLE 0x0040
#pragma warning(disable : 4201)
// #pragma warning(disable : 4115)
#undef VARIANT_TRUE
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
#endif
#endif // Z7_OLD_WIN_SDK
#ifdef UNDER_CE
#undef VARIANT_TRUE
#define VARIANT_TRUE ((VARIANT_BOOL)-1)
#endif
#if defined(_MSC_VER)
#if _MSC_VER >= 1400 && _MSC_VER <= 1600
// BaseTsd.h(148) : 'HandleToULong' : unreferenced inline function has been removed
// string.h
// #pragma warning(disable : 4514)
#endif
#endif
/* #include "7zTypes.h" */
#endif

View File

@@ -0,0 +1,60 @@
/* Aes.h -- AES encryption / decryption
2023-04-02 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_AES_H
#define ZIP7_INC_AES_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define AES_BLOCK_SIZE 16
/* Call AesGenTables one time before other AES functions */
void AesGenTables(void);
/* UInt32 pointers must be 16-byte aligned */
/* 16-byte (4 * 32-bit words) blocks: 1 (IV) + 1 (keyMode) + 15 (AES-256 roundKeys) */
#define AES_NUM_IVMRK_WORDS ((1 + 1 + 15) * 4)
/* aes - 16-byte aligned pointer to keyMode+roundKeys sequence */
/* keySize = 16 or 24 or 32 (bytes) */
typedef void (Z7_FASTCALL *AES_SET_KEY_FUNC)(UInt32 *aes, const Byte *key, unsigned keySize);
void Z7_FASTCALL Aes_SetKey_Enc(UInt32 *aes, const Byte *key, unsigned keySize);
void Z7_FASTCALL Aes_SetKey_Dec(UInt32 *aes, const Byte *key, unsigned keySize);
/* ivAes - 16-byte aligned pointer to iv+keyMode+roundKeys sequence: UInt32[AES_NUM_IVMRK_WORDS] */
void AesCbc_Init(UInt32 *ivAes, const Byte *iv); /* iv size is AES_BLOCK_SIZE */
/* data - 16-byte aligned pointer to data */
/* numBlocks - the number of 16-byte blocks in data array */
typedef void (Z7_FASTCALL *AES_CODE_FUNC)(UInt32 *ivAes, Byte *data, size_t numBlocks);
extern AES_CODE_FUNC g_AesCbc_Decode;
#ifndef Z7_SFX
extern AES_CODE_FUNC g_AesCbc_Encode;
extern AES_CODE_FUNC g_AesCtr_Code;
#define k_Aes_SupportedFunctions_HW (1 << 2)
#define k_Aes_SupportedFunctions_HW_256 (1 << 3)
extern UInt32 g_Aes_SupportedFunctions_Flags;
#endif
#define Z7_DECLARE_AES_CODE_FUNC(funcName) \
void Z7_FASTCALL funcName(UInt32 *ivAes, Byte *data, size_t numBlocks);
Z7_DECLARE_AES_CODE_FUNC (AesCbc_Encode)
Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode)
Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code)
Z7_DECLARE_AES_CODE_FUNC (AesCbc_Encode_HW)
Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode_HW)
Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code_HW)
Z7_DECLARE_AES_CODE_FUNC (AesCbc_Decode_HW_256)
Z7_DECLARE_AES_CODE_FUNC (AesCtr_Code_HW_256)
EXTERN_C_END
#endif

View File

@@ -0,0 +1,76 @@
/* Alloc.h -- Memory allocation functions
2024-01-22 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_ALLOC_H
#define ZIP7_INC_ALLOC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/*
MyFree(NULL) : is allowed, as free(NULL)
MyAlloc(0) : returns NULL : but malloc(0) is allowed to return NULL or non_NULL
MyRealloc(NULL, 0) : returns NULL : but realloc(NULL, 0) is allowed to return NULL or non_NULL
MyRealloc() is similar to realloc() for the following cases:
MyRealloc(non_NULL, 0) : returns NULL and always calls MyFree(ptr)
MyRealloc(NULL, non_ZERO) : returns NULL, if allocation failed
MyRealloc(non_NULL, non_ZERO) : returns NULL, if reallocation failed
*/
void *MyAlloc(size_t size);
void MyFree(void *address);
void *MyRealloc(void *address, size_t size);
void *z7_AlignedAlloc(size_t size);
void z7_AlignedFree(void *p);
#ifdef _WIN32
#ifdef Z7_LARGE_PAGES
void SetLargePageSize(void);
#endif
void *MidAlloc(size_t size);
void MidFree(void *address);
void *BigAlloc(size_t size);
void BigFree(void *address);
/* #define Z7_BIG_ALLOC_IS_ZERO_FILLED */
#else
#define MidAlloc(size) z7_AlignedAlloc(size)
#define MidFree(address) z7_AlignedFree(address)
#define BigAlloc(size) z7_AlignedAlloc(size)
#define BigFree(address) z7_AlignedFree(address)
#endif
extern const ISzAlloc g_Alloc;
#ifdef _WIN32
extern const ISzAlloc g_BigAlloc;
extern const ISzAlloc g_MidAlloc;
#else
#define g_BigAlloc g_AlignedAlloc
#define g_MidAlloc g_AlignedAlloc
#endif
extern const ISzAlloc g_AlignedAlloc;
typedef struct
{
ISzAlloc vt;
ISzAllocPtr baseAlloc;
unsigned numAlignBits; /* ((1 << numAlignBits) >= sizeof(void *)) */
size_t offset; /* (offset == (k * sizeof(void *)) && offset < (1 << numAlignBits) */
} CAlignOffsetAlloc;
void AlignOffsetAlloc_CreateVTable(CAlignOffsetAlloc *p);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,332 @@
/* Bcj2.h -- BCJ2 converter for x86 code (Branch CALL/JUMP variant2)
2023-03-02 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_BCJ2_H
#define ZIP7_INC_BCJ2_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define BCJ2_NUM_STREAMS 4
enum
{
BCJ2_STREAM_MAIN,
BCJ2_STREAM_CALL,
BCJ2_STREAM_JUMP,
BCJ2_STREAM_RC
};
enum
{
BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS,
BCJ2_DEC_STATE_ORIG_1,
BCJ2_DEC_STATE_ORIG_2,
BCJ2_DEC_STATE_ORIG_3,
BCJ2_DEC_STATE_ORIG,
BCJ2_DEC_STATE_ERROR /* after detected data error */
};
enum
{
BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS,
BCJ2_ENC_STATE_FINISHED /* it's state after fully encoded stream */
};
/* #define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP) */
#define BCJ2_IS_32BIT_STREAM(s) ((unsigned)((unsigned)(s) - (unsigned)BCJ2_STREAM_CALL) < 2)
/*
CBcj2Dec / CBcj2Enc
bufs sizes:
BUF_SIZE(n) = lims[n] - bufs[n]
bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be multiply of 4:
(BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
(BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
*/
// typedef UInt32 CBcj2Prob;
typedef UInt16 CBcj2Prob;
/*
BCJ2 encoder / decoder internal requirements:
- If last bytes of stream contain marker (e8/e8/0f8x), then
there is also encoded symbol (0 : no conversion) in RC stream.
- One case of overlapped instructions is supported,
if last byte of converted instruction is (0f) and next byte is (8x):
marker [xx xx xx 0f] 8x
then the pair (0f 8x) is treated as marker.
*/
/* ---------- BCJ2 Decoder ---------- */
/*
CBcj2Dec:
(dest) is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
bufs[BCJ2_STREAM_MAIN] >= dest &&
bufs[BCJ2_STREAM_MAIN] - dest >=
BUF_SIZE(BCJ2_STREAM_CALL) +
BUF_SIZE(BCJ2_STREAM_JUMP)
reserve = bufs[BCJ2_STREAM_MAIN] - dest -
( BUF_SIZE(BCJ2_STREAM_CALL) +
BUF_SIZE(BCJ2_STREAM_JUMP) )
and additional conditions:
if (it's first call of Bcj2Dec_Decode() after Bcj2Dec_Init())
{
(reserve != 1) : if (ver < v23.00)
}
else // if there are more than one calls of Bcj2Dec_Decode() after Bcj2Dec_Init())
{
(reserve >= 6) : if (ver < v23.00)
(reserve >= 4) : if (ver >= v23.00)
We need that (reserve) because after first call of Bcj2Dec_Decode(),
CBcj2Dec::temp can contain up to 4 bytes for writing to (dest).
}
(reserve == 0) is allowed, if we decode full stream via single call of Bcj2Dec_Decode().
(reserve == 0) also is allowed in case of multi-call, if we use fixed buffers,
and (reserve) is calculated from full (final) sizes of all streams before first call.
*/
typedef struct
{
const Byte *bufs[BCJ2_NUM_STREAMS];
const Byte *lims[BCJ2_NUM_STREAMS];
Byte *dest;
const Byte *destLim;
unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */
UInt32 ip; /* property of starting base for decoding */
UInt32 temp; /* Byte temp[4]; */
UInt32 range;
UInt32 code;
CBcj2Prob probs[2 + 256];
} CBcj2Dec;
/* Note:
Bcj2Dec_Init() sets (CBcj2Dec::ip = 0)
if (ip != 0) property is required, the caller must set CBcj2Dec::ip after Bcj2Dec_Init()
*/
void Bcj2Dec_Init(CBcj2Dec *p);
/* Bcj2Dec_Decode():
returns:
SZ_OK
SZ_ERROR_DATA : if data in 5 starting bytes of BCJ2_STREAM_RC stream are not correct
*/
SRes Bcj2Dec_Decode(CBcj2Dec *p);
/* To check that decoding was finished you can compare
sizes of processed streams with sizes known from another sources.
You must do at least one mandatory check from the two following options:
- the check for size of processed output (ORIG) stream.
- the check for size of processed input (MAIN) stream.
additional optional checks:
- the checks for processed sizes of all input streams (MAIN, CALL, JUMP, RC)
- the checks Bcj2Dec_IsMaybeFinished*()
also before actual decoding you can check that the
following condition is met for stream sizes:
( size(ORIG) == size(MAIN) + size(CALL) + size(JUMP) )
*/
/* (state == BCJ2_STREAM_MAIN) means that decoder is ready for
additional input data in BCJ2_STREAM_MAIN stream.
Note that (state == BCJ2_STREAM_MAIN) is allowed for non-finished decoding.
*/
#define Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) ((_p_)->state == BCJ2_STREAM_MAIN)
/* if the stream decoding was finished correctly, then range decoder
part of CBcj2Dec also was finished, and then (CBcj2Dec::code == 0).
Note that (CBcj2Dec::code == 0) is allowed for non-finished decoding.
*/
#define Bcj2Dec_IsMaybeFinished_code(_p_) ((_p_)->code == 0)
/* use Bcj2Dec_IsMaybeFinished() only as additional check
after at least one mandatory check from the two following options:
- the check for size of processed output (ORIG) stream.
- the check for size of processed input (MAIN) stream.
*/
#define Bcj2Dec_IsMaybeFinished(_p_) ( \
Bcj2Dec_IsMaybeFinished_state_MAIN(_p_) && \
Bcj2Dec_IsMaybeFinished_code(_p_))
/* ---------- BCJ2 Encoder ---------- */
typedef enum
{
BCJ2_ENC_FINISH_MODE_CONTINUE,
BCJ2_ENC_FINISH_MODE_END_BLOCK,
BCJ2_ENC_FINISH_MODE_END_STREAM
} EBcj2Enc_FinishMode;
/*
BCJ2_ENC_FINISH_MODE_CONTINUE:
process non finished encoding.
It notifies the encoder that additional further calls
can provide more input data (src) than provided by current call.
In that case the CBcj2Enc encoder still can move (src) pointer
up to (srcLim), but CBcj2Enc encoder can store some of the last
processed bytes (up to 4 bytes) from src to internal CBcj2Enc::temp[] buffer.
at return:
(CBcj2Enc::src will point to position that includes
processed data and data copied to (temp[]) buffer)
That data from (temp[]) buffer will be used in further calls.
BCJ2_ENC_FINISH_MODE_END_BLOCK:
finish encoding of current block (ended at srcLim) without RC flushing.
at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_ORIG) &&
CBcj2Enc::src == CBcj2Enc::srcLim)
: it shows that block encoding was finished. And the encoder is
ready for new (src) data or for stream finish operation.
finished block means
{
CBcj2Enc has completed block encoding up to (srcLim).
(1 + 4 bytes) or (2 + 4 bytes) CALL/JUMP cortages will
not cross block boundary at (srcLim).
temporary CBcj2Enc buffer for (ORIG) src data is empty.
3 output uncompressed streams (MAIN, CALL, JUMP) were flushed.
RC stream was not flushed. And RC stream will cross block boundary.
}
Note: some possible implementation of BCJ2 encoder could
write branch marker (e8/e8/0f8x) in one call of Bcj2Enc_Encode(),
and it could calculate symbol for RC in another call of Bcj2Enc_Encode().
BCJ2 encoder uses ip/fileIp/fileSize/relatLimit values to calculate RC symbol.
And these CBcj2Enc variables can have different values in different Bcj2Enc_Encode() calls.
So caller must finish each block with BCJ2_ENC_FINISH_MODE_END_BLOCK
to ensure that RC symbol is calculated and written in proper block.
BCJ2_ENC_FINISH_MODE_END_STREAM
finish encoding of stream (ended at srcLim) fully including RC flushing.
at return: if (CBcj2Enc::state == BCJ2_ENC_STATE_FINISHED)
: it shows that stream encoding was finished fully,
and all output streams were flushed fully.
also Bcj2Enc_IsFinished() can be called.
*/
/*
32-bit relative offset in JUMP/CALL commands is
- (mod 4 GiB) for 32-bit x86 code
- signed Int32 for 64-bit x86-64 code
BCJ2 encoder also does internal relative to absolute address conversions.
And there are 2 possible ways to do it:
before v23: we used 32-bit variables and (mod 4 GiB) conversion
since v23: we use 64-bit variables and (signed Int32 offset) conversion.
The absolute address condition for conversion in v23:
((UInt64)((Int64)ip64 - (Int64)fileIp64 + 5 + (Int32)offset) < (UInt64)fileSize64)
note that if (fileSize64 > 2 GiB). there is difference between
old (mod 4 GiB) way (v22) and new (signed Int32 offset) way (v23).
And new (v23) way is more suitable to encode 64-bit x86-64 code for (fileSize64 > 2 GiB) cases.
*/
/*
// for old (v22) way for conversion:
typedef UInt32 CBcj2Enc_ip_unsigned;
typedef Int32 CBcj2Enc_ip_signed;
#define BCJ2_ENC_FileSize_MAX ((UInt32)1 << 31)
*/
typedef UInt64 CBcj2Enc_ip_unsigned;
typedef Int64 CBcj2Enc_ip_signed;
/* maximum size of file that can be used for conversion condition */
#define BCJ2_ENC_FileSize_MAX ((CBcj2Enc_ip_unsigned)0 - 2)
/* default value of fileSize64_minus1 variable that means
that absolute address limitation will not be used */
#define BCJ2_ENC_FileSizeField_UNLIMITED ((CBcj2Enc_ip_unsigned)0 - 1)
/* calculate value that later can be set to CBcj2Enc::fileSize64_minus1 */
#define BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize) \
((CBcj2Enc_ip_unsigned)(fileSize) - 1)
/* set CBcj2Enc::fileSize64_minus1 variable from size of file */
#define Bcj2Enc_SET_FileSize(p, fileSize) \
(p)->fileSize64_minus1 = BCJ2_ENC_GET_FileSizeField_VAL_FROM_FileSize(fileSize);
typedef struct
{
Byte *bufs[BCJ2_NUM_STREAMS];
const Byte *lims[BCJ2_NUM_STREAMS];
const Byte *src;
const Byte *srcLim;
unsigned state;
EBcj2Enc_FinishMode finishMode;
Byte context;
Byte flushRem;
Byte isFlushState;
Byte cache;
UInt32 range;
UInt64 low;
UInt64 cacheSize;
// UInt32 context; // for marker version, it can include marker flag.
/* (ip64) and (fileIp64) correspond to virtual source stream position
that doesn't include data in temp[] */
CBcj2Enc_ip_unsigned ip64; /* current (ip) position */
CBcj2Enc_ip_unsigned fileIp64; /* start (ip) position of current file */
CBcj2Enc_ip_unsigned fileSize64_minus1; /* size of current file (for conversion limitation) */
UInt32 relatLimit; /* (relatLimit <= ((UInt32)1 << 31)) : 0 means disable_conversion */
// UInt32 relatExcludeBits;
UInt32 tempTarget;
unsigned tempPos; /* the number of bytes that were copied to temp[] buffer
(tempPos <= 4) outside of Bcj2Enc_Encode() */
// Byte temp[4]; // for marker version
Byte temp[8];
CBcj2Prob probs[2 + 256];
} CBcj2Enc;
void Bcj2Enc_Init(CBcj2Enc *p);
/*
Bcj2Enc_Encode(): at exit:
p->State < BCJ2_NUM_STREAMS : we need more buffer space for output stream
(bufs[p->State] == lims[p->State])
p->State == BCJ2_ENC_STATE_ORIG : we need more data in input src stream
(src == srcLim)
p->State == BCJ2_ENC_STATE_FINISHED : after fully encoded stream
*/
void Bcj2Enc_Encode(CBcj2Enc *p);
/* Bcj2Enc encoder can look ahead for up 4 bytes of source stream.
CBcj2Enc::tempPos : is the number of bytes that were copied from input stream to temp[] buffer.
(CBcj2Enc::src) after Bcj2Enc_Encode() is starting position after
fully processed data and after data copied to temp buffer.
So if the caller needs to get real number of fully processed input
bytes (without look ahead data in temp buffer),
the caller must subtruct (CBcj2Enc::tempPos) value from processed size
value that is calculated based on current (CBcj2Enc::src):
cur_processed_pos = Calc_Big_Processed_Pos(enc.src)) -
Bcj2Enc_Get_AvailInputSize_in_Temp(&enc);
*/
/* get the size of input data that was stored in temp[] buffer: */
#define Bcj2Enc_Get_AvailInputSize_in_Temp(p) ((p)->tempPos)
#define Bcj2Enc_IsFinished(p) ((p)->flushRem == 0)
/* Note : the decoder supports overlapping of marker (0f 80).
But we can eliminate such overlapping cases by setting
the limit for relative offset conversion as
CBcj2Enc::relatLimit <= (0x0f << 24) == (240 MiB)
*/
/* default value for CBcj2Enc::relatLimit */
#define BCJ2_ENC_RELAT_LIMIT_DEFAULT ((UInt32)0x0f << 24)
#define BCJ2_ENC_RELAT_LIMIT_MAX ((UInt32)1 << 31)
// #define BCJ2_RELAT_EXCLUDE_NUM_BITS 5
EXTERN_C_END
#endif

View File

@@ -0,0 +1,105 @@
/* Blake2.h -- BLAKE2sp Hash
2024-01-17 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_BLAKE2_H
#define ZIP7_INC_BLAKE2_H
#include "7zTypes.h"
#if 0
#include "Compiler.h"
#include "CpuArch.h"
#if defined(MY_CPU_X86_OR_AMD64)
#if defined(__SSE2__) \
|| defined(_MSC_VER) && _MSC_VER > 1200 \
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 30300) \
|| defined(__clang__) \
|| defined(__INTEL_COMPILER)
#include <emmintrin.h> // SSE2
#endif
#if defined(__AVX2__) \
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \
|| defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \
|| defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \
|| defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \
|| defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400)
#include <immintrin.h>
#if defined(__clang__)
#include <avxintrin.h>
#include <avx2intrin.h>
#endif
#endif // avx2
#endif // MY_CPU_X86_OR_AMD64
#endif // 0
EXTERN_C_BEGIN
#define Z7_BLAKE2S_BLOCK_SIZE 64
#define Z7_BLAKE2S_DIGEST_SIZE 32
#define Z7_BLAKE2SP_PARALLEL_DEGREE 8
#define Z7_BLAKE2SP_NUM_STRUCT_WORDS 16
#if 1 || defined(Z7_BLAKE2SP_USE_FUNCTIONS)
typedef void (Z7_FASTCALL *Z7_BLAKE2SP_FUNC_COMPRESS)(UInt32 *states, const Byte *data, const Byte *end);
typedef void (Z7_FASTCALL *Z7_BLAKE2SP_FUNC_INIT)(UInt32 *states);
#endif
// it's required that CBlake2sp is aligned for 32-bytes,
// because the code can use unaligned access with sse and avx256.
// but 64-bytes alignment can be better.
MY_ALIGN(64)
typedef struct
{
union
{
#if 0
#if defined(MY_CPU_X86_OR_AMD64)
#if defined(__SSE2__) \
|| defined(_MSC_VER) && _MSC_VER > 1200 \
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 30300) \
|| defined(__clang__) \
|| defined(__INTEL_COMPILER)
__m128i _pad_align_128bit[4];
#endif // sse2
#if defined(__AVX2__) \
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \
|| defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \
|| defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \
|| defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \
|| defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400)
__m256i _pad_align_256bit[2];
#endif // avx2
#endif // x86
#endif // 0
void * _pad_align_ptr[8];
UInt32 _pad_align_32bit[16];
struct
{
unsigned cycPos;
unsigned _pad_unused;
#if 1 || defined(Z7_BLAKE2SP_USE_FUNCTIONS)
Z7_BLAKE2SP_FUNC_COMPRESS func_Compress_Fast;
Z7_BLAKE2SP_FUNC_COMPRESS func_Compress_Single;
Z7_BLAKE2SP_FUNC_INIT func_Init;
Z7_BLAKE2SP_FUNC_INIT func_Final;
#endif
} header;
} u;
// MY_ALIGN(64)
UInt32 states[Z7_BLAKE2SP_PARALLEL_DEGREE * Z7_BLAKE2SP_NUM_STRUCT_WORDS];
// MY_ALIGN(64)
UInt32 buf32[Z7_BLAKE2SP_PARALLEL_DEGREE * Z7_BLAKE2SP_NUM_STRUCT_WORDS * 2];
} CBlake2sp;
BoolInt Blake2sp_SetFunction(CBlake2sp *p, unsigned algo);
void Blake2sp_Init(CBlake2sp *p);
void Blake2sp_InitState(CBlake2sp *p);
void Blake2sp_Update(CBlake2sp *p, const Byte *data, size_t size);
void Blake2sp_Final(CBlake2sp *p, Byte *digest);
void z7_Black2sp_Prepare(void);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,105 @@
/* Bra.h -- Branch converters for executables
2024-01-20 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_BRA_H
#define ZIP7_INC_BRA_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/* #define PPC BAD_PPC_11 // for debug */
#define Z7_BRANCH_CONV_DEC_2(name) z7_ ## name ## _Dec
#define Z7_BRANCH_CONV_ENC_2(name) z7_ ## name ## _Enc
#define Z7_BRANCH_CONV_DEC(name) Z7_BRANCH_CONV_DEC_2(BranchConv_ ## name)
#define Z7_BRANCH_CONV_ENC(name) Z7_BRANCH_CONV_ENC_2(BranchConv_ ## name)
#define Z7_BRANCH_CONV_ST_DEC(name) z7_BranchConvSt_ ## name ## _Dec
#define Z7_BRANCH_CONV_ST_ENC(name) z7_BranchConvSt_ ## name ## _Enc
#define Z7_BRANCH_CONV_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc)
#define Z7_BRANCH_CONV_ST_DECL(name) Byte * name(Byte *data, SizeT size, UInt32 pc, UInt32 *state)
typedef Z7_BRANCH_CONV_DECL( (*z7_Func_BranchConv));
typedef Z7_BRANCH_CONV_ST_DECL((*z7_Func_BranchConvSt));
#define Z7_BRANCH_CONV_ST_X86_STATE_INIT_VAL 0
Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_DEC(X86));
Z7_BRANCH_CONV_ST_DECL (Z7_BRANCH_CONV_ST_ENC(X86));
#define Z7_BRANCH_FUNCS_DECL(name) \
Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_DEC_2(name)); \
Z7_BRANCH_CONV_DECL (Z7_BRANCH_CONV_ENC_2(name));
Z7_BRANCH_FUNCS_DECL (BranchConv_ARM64)
Z7_BRANCH_FUNCS_DECL (BranchConv_ARM)
Z7_BRANCH_FUNCS_DECL (BranchConv_ARMT)
Z7_BRANCH_FUNCS_DECL (BranchConv_PPC)
Z7_BRANCH_FUNCS_DECL (BranchConv_SPARC)
Z7_BRANCH_FUNCS_DECL (BranchConv_IA64)
Z7_BRANCH_FUNCS_DECL (BranchConv_RISCV)
/*
These functions convert data that contain CPU instructions.
Each such function converts relative addresses to absolute addresses in some
branch instructions: CALL (in all converters) and JUMP (X86 converter only).
Such conversion allows to increase compression ratio, if we compress that data.
There are 2 types of converters:
Byte * Conv_RISC (Byte *data, SizeT size, UInt32 pc);
Byte * ConvSt_X86(Byte *data, SizeT size, UInt32 pc, UInt32 *state);
Each Converter supports 2 versions: one for encoding
and one for decoding (_Enc/_Dec postfixes in function name).
In params:
data : data buffer
size : size of data
pc : current virtual Program Counter (Instruction Pointer) value
In/Out param:
state : pointer to state variable (for X86 converter only)
Return:
The pointer to position in (data) buffer after last byte that was processed.
If the caller calls converter again, it must call it starting with that position.
But the caller is allowed to move data in buffer. So pointer to
current processed position also will be changed for next call.
Also the caller must increase internal (pc) value for next call.
Each converter has some characteristics: Endian, Alignment, LookAhead.
Type Endian Alignment LookAhead
X86 little 1 4
ARMT little 2 2
RISCV little 2 6
ARM little 4 0
ARM64 little 4 0
PPC big 4 0
SPARC big 4 0
IA64 little 16 0
(data) must be aligned for (Alignment).
processed size can be calculated as:
SizeT processed = Conv(data, size, pc) - data;
if (processed == 0)
it means that converter needs more data for processing.
If (size < Alignment + LookAhead)
then (processed == 0) is allowed.
Example code for conversion in loop:
UInt32 pc = 0;
size = 0;
for (;;)
{
size += Load_more_input_data(data + size);
SizeT processed = Conv(data, size, pc) - data;
if (processed == 0 && no_more_input_data_after_size)
break; // we stop convert loop
data += processed;
size -= processed;
pc += processed;
}
*/
EXTERN_C_END
#endif

View File

@@ -0,0 +1,26 @@
/* BwtSort.h -- BWT block sorting
2023-03-03 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_BWT_SORT_H
#define ZIP7_INC_BWT_SORT_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/* use BLOCK_SORT_EXTERNAL_FLAGS if blockSize can be > 1M */
/* #define BLOCK_SORT_EXTERNAL_FLAGS */
#ifdef BLOCK_SORT_EXTERNAL_FLAGS
#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) ((((blockSize) + 31) >> 5))
#else
#define BLOCK_SORT_EXTERNAL_SIZE(blockSize) 0
#endif
#define BLOCK_SORT_BUF_SIZE(blockSize) ((blockSize) * 2 + BLOCK_SORT_EXTERNAL_SIZE(blockSize) + (1 << 16))
UInt32 BlockSort(UInt32 *indices, const Byte *data, UInt32 blockSize);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,236 @@
/* Compiler.h : Compiler specific defines and pragmas
2024-01-22 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_COMPILER_H
#define ZIP7_INC_COMPILER_H
#if defined(__clang__)
# define Z7_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
#endif
#if defined(__clang__) && defined(__apple_build_version__)
# define Z7_APPLE_CLANG_VERSION Z7_CLANG_VERSION
#elif defined(__clang__)
# define Z7_LLVM_CLANG_VERSION Z7_CLANG_VERSION
#elif defined(__GNUC__)
# define Z7_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#ifdef _MSC_VER
#if !defined(__clang__) && !defined(__GNUC__)
#define Z7_MSC_VER_ORIGINAL _MSC_VER
#endif
#endif
#if defined(__MINGW32__) || defined(__MINGW64__)
#define Z7_MINGW
#endif
#if defined(__LCC__) && (defined(__MCST__) || defined(__e2k__))
#define Z7_MCST_LCC
#define Z7_MCST_LCC_VERSION (__LCC__ * 100 + __LCC_MINOR__)
#endif
/*
#if defined(__AVX2__) \
|| defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900) \
|| defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 40600) \
|| defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30100) \
|| defined(Z7_MSC_VER_ORIGINAL) && (Z7_MSC_VER_ORIGINAL >= 1800) \
|| defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1400)
#define Z7_COMPILER_AVX2_SUPPORTED
#endif
#endif
*/
// #pragma GCC diagnostic ignored "-Wunknown-pragmas"
#ifdef __clang__
// padding size of '' with 4 bytes to alignment boundary
#pragma GCC diagnostic ignored "-Wpadded"
#if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) \
&& defined(__FreeBSD__)
// freebsd:
#pragma GCC diagnostic ignored "-Wexcess-padding"
#endif
#if __clang_major__ >= 16
#pragma GCC diagnostic ignored "-Wunsafe-buffer-usage"
#endif
#if __clang_major__ == 13
#if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16)
// cheri
#pragma GCC diagnostic ignored "-Wcapability-to-integer-cast"
#endif
#endif
#if __clang_major__ == 13
// for <arm_neon.h>
#pragma GCC diagnostic ignored "-Wreserved-identifier"
#endif
#endif // __clang__
#if defined(_WIN32) && defined(__clang__) && __clang_major__ >= 16
// #pragma GCC diagnostic ignored "-Wcast-function-type-strict"
#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION \
_Pragma("GCC diagnostic ignored \"-Wcast-function-type-strict\"")
#else
#define Z7_DIAGNOSTIC_IGNORE_CAST_FUNCTION
#endif
typedef void (*Z7_void_Function)(void);
#if defined(__clang__) || defined(__GNUC__)
#define Z7_CAST_FUNC_C (Z7_void_Function)
#elif defined(_MSC_VER) && _MSC_VER > 1920
#define Z7_CAST_FUNC_C (void *)
// #pragma warning(disable : 4191) // 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)()'
#else
#define Z7_CAST_FUNC_C
#endif
/*
#if (defined(__GNUC__) && (__GNUC__ >= 8)) || defined(__clang__)
// #pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
*/
#ifdef __GNUC__
#if defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40000) && (Z7_GCC_VERSION < 70000)
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
#endif
#ifdef _MSC_VER
#ifdef UNDER_CE
#define RPC_NO_WINDOWS_H
/* #pragma warning(disable : 4115) // '_RPC_ASYNC_STATE' : named type definition in parentheses */
#pragma warning(disable : 4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable : 4214) // nonstandard extension used : bit field types other than int
#endif
#if defined(_MSC_VER) && _MSC_VER >= 1800
#pragma warning(disable : 4464) // relative include path contains '..'
#endif
// == 1200 : -O1 : for __forceinline
// >= 1900 : -O1 : for printf
#pragma warning(disable : 4710) // function not inlined
#if _MSC_VER < 1900
// winnt.h: 'Int64ShllMod32'
#pragma warning(disable : 4514) // unreferenced inline function has been removed
#endif
#if _MSC_VER < 1300
// #pragma warning(disable : 4702) // unreachable code
// Bra.c : -O1:
#pragma warning(disable : 4714) // function marked as __forceinline not inlined
#endif
/*
#if _MSC_VER > 1400 && _MSC_VER <= 1900
// strcat: This function or variable may be unsafe
// sysinfoapi.h: kit10: GetVersion was declared deprecated
#pragma warning(disable : 4996)
#endif
*/
#if _MSC_VER > 1200
// -Wall warnings
#pragma warning(disable : 4711) // function selected for automatic inline expansion
#pragma warning(disable : 4820) // '2' bytes padding added after data member
#if _MSC_VER >= 1400 && _MSC_VER < 1920
// 1400: string.h: _DBG_MEMCPY_INLINE_
// 1600 - 191x : smmintrin.h __cplusplus'
// is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
#pragma warning(disable : 4668)
// 1400 - 1600 : WinDef.h : 'FARPROC' :
// 1900 - 191x : immintrin.h: _readfsbase_u32
// no function prototype given : converting '()' to '(void)'
#pragma warning(disable : 4255)
#endif
#if _MSC_VER >= 1914
// Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
#pragma warning(disable : 5045)
#endif
#endif // _MSC_VER > 1200
#endif // _MSC_VER
#if defined(__clang__) && (__clang_major__ >= 4)
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \
_Pragma("clang loop unroll(disable)") \
_Pragma("clang loop vectorize(disable)")
#define Z7_ATTRIB_NO_VECTORIZE
#elif defined(__GNUC__) && (__GNUC__ >= 5) \
&& (!defined(Z7_MCST_LCC_VERSION) || (Z7_MCST_LCC_VERSION >= 12610))
#define Z7_ATTRIB_NO_VECTORIZE __attribute__((optimize("no-tree-vectorize")))
// __attribute__((optimize("no-unroll-loops")));
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE
#elif defined(_MSC_VER) && (_MSC_VER >= 1920)
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE \
_Pragma("loop( no_vector )")
#define Z7_ATTRIB_NO_VECTORIZE
#else
#define Z7_PRAGMA_OPT_DISABLE_LOOP_UNROLL_VECTORIZE
#define Z7_ATTRIB_NO_VECTORIZE
#endif
#if defined(MY_CPU_X86_OR_AMD64) && ( \
defined(__clang__) && (__clang_major__ >= 4) \
|| defined(__GNUC__) && (__GNUC__ >= 5))
#define Z7_ATTRIB_NO_SSE __attribute__((__target__("no-sse")))
#else
#define Z7_ATTRIB_NO_SSE
#endif
#define Z7_ATTRIB_NO_VECTOR \
Z7_ATTRIB_NO_VECTORIZE \
Z7_ATTRIB_NO_SSE
#if defined(__clang__) && (__clang_major__ >= 8) \
|| defined(__GNUC__) && (__GNUC__ >= 1000) \
/* || defined(_MSC_VER) && (_MSC_VER >= 1920) */
// GCC is not good for __builtin_expect()
#define Z7_LIKELY(x) (__builtin_expect((x), 1))
#define Z7_UNLIKELY(x) (__builtin_expect((x), 0))
// #define Z7_unlikely [[unlikely]]
// #define Z7_likely [[likely]]
#else
#define Z7_LIKELY(x) (x)
#define Z7_UNLIKELY(x) (x)
// #define Z7_likely
#endif
#if (defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30600))
#if (Z7_CLANG_VERSION < 130000)
#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wreserved-id-macro\"")
#else
#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wreserved-macro-identifier\"")
#endif
#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER \
_Pragma("GCC diagnostic pop")
#else
#define Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
#define Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
#endif
#define UNUSED_VAR(x) (void)x;
/* #define UNUSED_VAR(x) x=x; */
#endif

View File

@@ -0,0 +1,678 @@
/* CpuArch.h -- CPU specific code
Igor Pavlov : Public domain */
#ifndef ZIP7_INC_CPU_ARCH_H
#define ZIP7_INC_CPU_ARCH_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/*
MY_CPU_LE means that CPU is LITTLE ENDIAN.
MY_CPU_BE means that CPU is BIG ENDIAN.
If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
MY_CPU_64BIT means that processor can work with 64-bit registers.
MY_CPU_64BIT can be used to select fast code branch
MY_CPU_64BIT doesn't mean that (sizeof(void *) == 8)
*/
#if !defined(_M_ARM64EC)
#if defined(_M_X64) \
|| defined(_M_AMD64) \
|| defined(__x86_64__) \
|| defined(__AMD64__) \
|| defined(__amd64__)
#define MY_CPU_AMD64
#ifdef __ILP32__
#define MY_CPU_NAME "x32"
#define MY_CPU_SIZEOF_POINTER 4
#else
#define MY_CPU_NAME "x64"
#define MY_CPU_SIZEOF_POINTER 8
#endif
#define MY_CPU_64BIT
#endif
#endif
#if defined(_M_IX86) \
|| defined(__i386__)
#define MY_CPU_X86
#define MY_CPU_NAME "x86"
/* #define MY_CPU_32BIT */
#define MY_CPU_SIZEOF_POINTER 4
#endif
#if defined(_M_ARM64) \
|| defined(_M_ARM64EC) \
|| defined(__AARCH64EL__) \
|| defined(__AARCH64EB__) \
|| defined(__aarch64__)
#define MY_CPU_ARM64
#if defined(__ILP32__) \
|| defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)
#define MY_CPU_NAME "arm64-32"
#define MY_CPU_SIZEOF_POINTER 4
#elif defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 16)
#define MY_CPU_NAME "arm64-128"
#define MY_CPU_SIZEOF_POINTER 16
#else
#if defined(_M_ARM64EC)
#define MY_CPU_NAME "arm64ec"
#else
#define MY_CPU_NAME "arm64"
#endif
#define MY_CPU_SIZEOF_POINTER 8
#endif
#define MY_CPU_64BIT
#endif
#if defined(_M_ARM) \
|| defined(_M_ARM_NT) \
|| defined(_M_ARMT) \
|| defined(__arm__) \
|| defined(__thumb__) \
|| defined(__ARMEL__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEL__) \
|| defined(__THUMBEB__)
#define MY_CPU_ARM
#if defined(__thumb__) || defined(__THUMBEL__) || defined(_M_ARMT)
#define MY_CPU_ARMT
#define MY_CPU_NAME "armt"
#else
#define MY_CPU_ARM32
#define MY_CPU_NAME "arm"
#endif
/* #define MY_CPU_32BIT */
#define MY_CPU_SIZEOF_POINTER 4
#endif
#if defined(_M_IA64) \
|| defined(__ia64__)
#define MY_CPU_IA64
#define MY_CPU_NAME "ia64"
#define MY_CPU_64BIT
#endif
#if defined(__mips64) \
|| defined(__mips64__) \
|| (defined(__mips) && (__mips == 64 || __mips == 4 || __mips == 3))
#define MY_CPU_NAME "mips64"
#define MY_CPU_64BIT
#elif defined(__mips__)
#define MY_CPU_NAME "mips"
/* #define MY_CPU_32BIT */
#endif
#if defined(__ppc64__) \
|| defined(__powerpc64__) \
|| defined(__ppc__) \
|| defined(__powerpc__) \
|| defined(__PPC__) \
|| defined(_POWER)
#define MY_CPU_PPC_OR_PPC64
#if defined(__ppc64__) \
|| defined(__powerpc64__) \
|| defined(_LP64) \
|| defined(__64BIT__)
#ifdef __ILP32__
#define MY_CPU_NAME "ppc64-32"
#define MY_CPU_SIZEOF_POINTER 4
#else
#define MY_CPU_NAME "ppc64"
#define MY_CPU_SIZEOF_POINTER 8
#endif
#define MY_CPU_64BIT
#else
#define MY_CPU_NAME "ppc"
#define MY_CPU_SIZEOF_POINTER 4
/* #define MY_CPU_32BIT */
#endif
#endif
#if defined(__sparc__) \
|| defined(__sparc)
#define MY_CPU_SPARC
#if defined(__LP64__) \
|| defined(_LP64) \
|| defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8)
#define MY_CPU_NAME "sparcv9"
#define MY_CPU_SIZEOF_POINTER 8
#define MY_CPU_64BIT
#elif defined(__sparc_v9__) \
|| defined(__sparcv9)
#define MY_CPU_64BIT
#if defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)
#define MY_CPU_NAME "sparcv9-32"
#else
#define MY_CPU_NAME "sparcv9m"
#endif
#elif defined(__sparc_v8__) \
|| defined(__sparcv8)
#define MY_CPU_NAME "sparcv8"
#define MY_CPU_SIZEOF_POINTER 4
#else
#define MY_CPU_NAME "sparc"
#endif
#endif
#if defined(__riscv) \
|| defined(__riscv__)
#define MY_CPU_RISCV
#if __riscv_xlen == 32
#define MY_CPU_NAME "riscv32"
#elif __riscv_xlen == 64
#define MY_CPU_NAME "riscv64"
#else
#define MY_CPU_NAME "riscv"
#endif
#endif
#if defined(__loongarch__)
#define MY_CPU_LOONGARCH
#if defined(__loongarch64) || defined(__loongarch_grlen) && (__loongarch_grlen == 64)
#define MY_CPU_64BIT
#endif
#if defined(__loongarch64)
#define MY_CPU_NAME "loongarch64"
#define MY_CPU_LOONGARCH64
#else
#define MY_CPU_NAME "loongarch"
#endif
#endif
// #undef MY_CPU_NAME
// #undef MY_CPU_SIZEOF_POINTER
// #define __e2k__
// #define __SIZEOF_POINTER__ 4
#if defined(__e2k__)
#define MY_CPU_E2K
#if defined(__ILP32__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 4)
#define MY_CPU_NAME "e2k-32"
#define MY_CPU_SIZEOF_POINTER 4
#else
#define MY_CPU_NAME "e2k"
#if defined(__LP64__) || defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8)
#define MY_CPU_SIZEOF_POINTER 8
#endif
#endif
#define MY_CPU_64BIT
#endif
#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
#define MY_CPU_X86_OR_AMD64
#endif
#if defined(MY_CPU_ARM) || defined(MY_CPU_ARM64)
#define MY_CPU_ARM_OR_ARM64
#endif
#ifdef _WIN32
#ifdef MY_CPU_ARM
#define MY_CPU_ARM_LE
#endif
#ifdef MY_CPU_ARM64
#define MY_CPU_ARM64_LE
#endif
#ifdef _M_IA64
#define MY_CPU_IA64_LE
#endif
#endif
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_LE) \
|| defined(MY_CPU_ARM64_LE) \
|| defined(MY_CPU_IA64_LE) \
|| defined(_LITTLE_ENDIAN) \
|| defined(__LITTLE_ENDIAN__) \
|| defined(__ARMEL__) \
|| defined(__THUMBEL__) \
|| defined(__AARCH64EL__) \
|| defined(__MIPSEL__) \
|| defined(__MIPSEL) \
|| defined(_MIPSEL) \
|| defined(__BFIN__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
#define MY_CPU_LE
#endif
#if defined(__BIG_ENDIAN__) \
|| defined(__ARMEB__) \
|| defined(__THUMBEB__) \
|| defined(__AARCH64EB__) \
|| defined(__MIPSEB__) \
|| defined(__MIPSEB) \
|| defined(_MIPSEB) \
|| defined(__m68k__) \
|| defined(__s390__) \
|| defined(__s390x__) \
|| defined(__zarch__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE
#endif
#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
#error Stop_Compiling_Bad_Endian
#endif
#if !defined(MY_CPU_LE) && !defined(MY_CPU_BE)
#error Stop_Compiling_CPU_ENDIAN_must_be_detected_at_compile_time
#endif
#if defined(MY_CPU_32BIT) && defined(MY_CPU_64BIT)
#error Stop_Compiling_Bad_32_64_BIT
#endif
#ifdef __SIZEOF_POINTER__
#ifdef MY_CPU_SIZEOF_POINTER
#if MY_CPU_SIZEOF_POINTER != __SIZEOF_POINTER__
#error Stop_Compiling_Bad_MY_CPU_PTR_SIZE
#endif
#else
#define MY_CPU_SIZEOF_POINTER __SIZEOF_POINTER__
#endif
#endif
#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
#if defined (_LP64)
#error Stop_Compiling_Bad_MY_CPU_PTR_SIZE
#endif
#endif
#ifdef _MSC_VER
#if _MSC_VER >= 1300
#define MY_CPU_pragma_pack_push_1 __pragma(pack(push, 1))
#define MY_CPU_pragma_pop __pragma(pack(pop))
#else
#define MY_CPU_pragma_pack_push_1
#define MY_CPU_pragma_pop
#endif
#else
#ifdef __xlC__
#define MY_CPU_pragma_pack_push_1 _Pragma("pack(1)")
#define MY_CPU_pragma_pop _Pragma("pack()")
#else
#define MY_CPU_pragma_pack_push_1 _Pragma("pack(push, 1)")
#define MY_CPU_pragma_pop _Pragma("pack(pop)")
#endif
#endif
#ifndef MY_CPU_NAME
// #define MY_CPU_IS_UNKNOWN
#ifdef MY_CPU_LE
#define MY_CPU_NAME "LE"
#elif defined(MY_CPU_BE)
#define MY_CPU_NAME "BE"
#else
/*
#define MY_CPU_NAME ""
*/
#endif
#endif
#ifdef __has_builtin
#define Z7_has_builtin(x) __has_builtin(x)
#else
#define Z7_has_builtin(x) 0
#endif
#define Z7_BSWAP32_CONST(v) \
( (((UInt32)(v) << 24) ) \
| (((UInt32)(v) << 8) & (UInt32)0xff0000) \
| (((UInt32)(v) >> 8) & (UInt32)0xff00 ) \
| (((UInt32)(v) >> 24) ))
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
#include <stdlib.h>
/* Note: these macros will use bswap instruction (486), that is unsupported in 386 cpu */
#pragma intrinsic(_byteswap_ushort)
#pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64)
#define Z7_BSWAP16(v) _byteswap_ushort(v)
#define Z7_BSWAP32(v) _byteswap_ulong (v)
#define Z7_BSWAP64(v) _byteswap_uint64(v)
#define Z7_CPU_FAST_BSWAP_SUPPORTED
/* GCC can generate slow code that calls function for __builtin_bswap32() for:
- GCC for RISCV, if Zbb/XTHeadBb extension is not used.
- GCC for SPARC.
The code from CLANG for SPARC also is not fastest.
So we don't define Z7_CPU_FAST_BSWAP_SUPPORTED in some cases.
*/
#elif (!defined(MY_CPU_RISCV) || defined (__riscv_zbb) || defined(__riscv_xtheadbb)) \
&& !defined(MY_CPU_SPARC) \
&& ( \
(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) \
|| (defined(__clang__) && Z7_has_builtin(__builtin_bswap16)) \
)
#define Z7_BSWAP16(v) __builtin_bswap16(v)
#define Z7_BSWAP32(v) __builtin_bswap32(v)
#define Z7_BSWAP64(v) __builtin_bswap64(v)
#define Z7_CPU_FAST_BSWAP_SUPPORTED
#else
#define Z7_BSWAP16(v) ((UInt16) \
( ((UInt32)(v) << 8) \
| ((UInt32)(v) >> 8) \
))
#define Z7_BSWAP32(v) Z7_BSWAP32_CONST(v)
#define Z7_BSWAP64(v) \
( ( ( (UInt64)(v) ) << 8 * 7 ) \
| ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 1) ) << 8 * 5 ) \
| ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 2) ) << 8 * 3 ) \
| ( ( (UInt64)(v) & ((UInt32)0xff << 8 * 3) ) << 8 * 1 ) \
| ( ( (UInt64)(v) >> 8 * 1 ) & ((UInt32)0xff << 8 * 3) ) \
| ( ( (UInt64)(v) >> 8 * 3 ) & ((UInt32)0xff << 8 * 2) ) \
| ( ( (UInt64)(v) >> 8 * 5 ) & ((UInt32)0xff << 8 * 1) ) \
| ( ( (UInt64)(v) >> 8 * 7 ) ) \
)
#endif
#ifdef MY_CPU_LE
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM64) \
|| defined(MY_CPU_RISCV) && defined(__riscv_misaligned_fast) \
|| defined(MY_CPU_E2K) && defined(__iset__) && (__iset__ >= 6)
#define MY_CPU_LE_UNALIGN
#define MY_CPU_LE_UNALIGN_64
#elif defined(__ARM_FEATURE_UNALIGNED)
/* === ALIGNMENT on 32-bit arm and LDRD/STRD/LDM/STM instructions.
Description of problems:
problem-1 : 32-bit ARM architecture:
multi-access (pair of 32-bit accesses) instructions (LDRD/STRD/LDM/STM)
require 32-bit (WORD) alignment (by 32-bit ARM architecture).
So there is "Alignment fault exception", if data is not aligned for 32-bit.
problem-2 : 32-bit kernels and arm64 kernels:
32-bit linux kernels provide fixup for these "paired" instruction "Alignment fault exception".
So unaligned paired-access instructions work via exception handler in kernel in 32-bit linux.
But some arm64 kernels do not handle these faults in 32-bit programs.
So we have unhandled exception for such instructions.
Probably some new arm64 kernels have fixed it, and unaligned
paired-access instructions work in new kernels?
problem-3 : compiler for 32-bit arm:
Compilers use LDRD/STRD/LDM/STM for UInt64 accesses
and for another cases where two 32-bit accesses are fused
to one multi-access instruction.
So UInt64 variables must be aligned for 32-bit, and each
32-bit access must be aligned for 32-bit, if we want to
avoid "Alignment fault" exception (handled or unhandled).
problem-4 : performace:
Even if unaligned access is handled by kernel, it will be slow.
So if we allow unaligned access, we can get fast unaligned
single-access, and slow unaligned paired-access.
We don't allow unaligned access on 32-bit arm, because compiler
genarates paired-access instructions that require 32-bit alignment,
and some arm64 kernels have no handler for these instructions.
Also unaligned paired-access instructions will be slow, if kernel handles them.
*/
// it must be disabled:
// #define MY_CPU_LE_UNALIGN
#endif
#endif
#ifdef MY_CPU_LE_UNALIGN
#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
#ifdef MY_CPU_LE_UNALIGN_64
#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
#define SetUi64(p, v) { *(UInt64 *)(void *)(p) = (v); }
#endif
#define SetUi16(p, v) { *(UInt16 *)(void *)(p) = (v); }
#define SetUi32(p, v) { *(UInt32 *)(void *)(p) = (v); }
#else
#define GetUi16(p) ( (UInt16) ( \
((const Byte *)(p))[0] | \
((UInt16)((const Byte *)(p))[1] << 8) ))
#define GetUi32(p) ( \
((const Byte *)(p))[0] | \
((UInt32)((const Byte *)(p))[1] << 8) | \
((UInt32)((const Byte *)(p))[2] << 16) | \
((UInt32)((const Byte *)(p))[3] << 24))
#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); }
#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)_vvv_; \
_ppp_[1] = (Byte)(_vvv_ >> 8); \
_ppp_[2] = (Byte)(_vvv_ >> 16); \
_ppp_[3] = (Byte)(_vvv_ >> 24); }
#endif
#ifndef GetUi64
#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
#endif
#ifndef SetUi64
#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
SetUi32(_ppp2_ , (UInt32)_vvv2_) \
SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)) }
#endif
#if defined(MY_CPU_LE_UNALIGN) && defined(Z7_CPU_FAST_BSWAP_SUPPORTED)
#if 0
// Z7_BSWAP16 can be slow for x86-msvc
#define GetBe16_to32(p) (Z7_BSWAP16 (*(const UInt16 *)(const void *)(p)))
#else
#define GetBe16_to32(p) (Z7_BSWAP32 (*(const UInt16 *)(const void *)(p)) >> 16)
#endif
#define GetBe32(p) Z7_BSWAP32 (*(const UInt32 *)(const void *)(p))
#define SetBe32(p, v) { (*(UInt32 *)(void *)(p)) = Z7_BSWAP32(v); }
#if defined(MY_CPU_LE_UNALIGN_64)
#define GetBe64(p) Z7_BSWAP64 (*(const UInt64 *)(const void *)(p))
#define SetBe64(p, v) { (*(UInt64 *)(void *)(p)) = Z7_BSWAP64(v); }
#endif
#else
#define GetBe32(p) ( \
((UInt32)((const Byte *)(p))[0] << 24) | \
((UInt32)((const Byte *)(p))[1] << 16) | \
((UInt32)((const Byte *)(p))[2] << 8) | \
((const Byte *)(p))[3] )
#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
_ppp_[0] = (Byte)(_vvv_ >> 24); \
_ppp_[1] = (Byte)(_vvv_ >> 16); \
_ppp_[2] = (Byte)(_vvv_ >> 8); \
_ppp_[3] = (Byte)_vvv_; }
#endif
#ifndef GetBe64
#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
#endif
#ifndef SetBe64
#define SetBe64(p, v) { Byte *_ppp_ = (Byte *)(p); UInt64 _vvv_ = (v); \
_ppp_[0] = (Byte)(_vvv_ >> 56); \
_ppp_[1] = (Byte)(_vvv_ >> 48); \
_ppp_[2] = (Byte)(_vvv_ >> 40); \
_ppp_[3] = (Byte)(_vvv_ >> 32); \
_ppp_[4] = (Byte)(_vvv_ >> 24); \
_ppp_[5] = (Byte)(_vvv_ >> 16); \
_ppp_[6] = (Byte)(_vvv_ >> 8); \
_ppp_[7] = (Byte)_vvv_; }
#endif
#ifndef GetBe16
#ifdef GetBe16_to32
#define GetBe16(p) ( (UInt16) GetBe16_to32(p))
#else
#define GetBe16(p) ( (UInt16) ( \
((UInt16)((const Byte *)(p))[0] << 8) | \
((const Byte *)(p))[1] ))
#endif
#endif
#if defined(MY_CPU_BE)
#define Z7_CONV_BE_TO_NATIVE_CONST32(v) (v)
#define Z7_CONV_LE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v)
#define Z7_CONV_NATIVE_TO_BE_32(v) (v)
#elif defined(MY_CPU_LE)
#define Z7_CONV_BE_TO_NATIVE_CONST32(v) Z7_BSWAP32_CONST(v)
#define Z7_CONV_LE_TO_NATIVE_CONST32(v) (v)
#define Z7_CONV_NATIVE_TO_BE_32(v) Z7_BSWAP32(v)
#else
#error Stop_Compiling_Unknown_Endian_CONV
#endif
#if defined(MY_CPU_BE)
#define GetBe64a(p) (*(const UInt64 *)(const void *)(p))
#define GetBe32a(p) (*(const UInt32 *)(const void *)(p))
#define GetBe16a(p) (*(const UInt16 *)(const void *)(p))
#define SetBe32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
#define SetBe16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
#define GetUi64a(p) GetUi64(p)
#define GetUi32a(p) GetUi32(p)
#define GetUi16a(p) GetUi16(p)
#define SetUi32a(p, v) SetUi32(p, v)
#define SetUi16a(p, v) SetUi16(p, v)
#elif defined(MY_CPU_LE)
#define GetUi64a(p) (*(const UInt64 *)(const void *)(p))
#define GetUi32a(p) (*(const UInt32 *)(const void *)(p))
#define GetUi16a(p) (*(const UInt16 *)(const void *)(p))
#define SetUi32a(p, v) { *(UInt32 *)(void *)(p) = (v); }
#define SetUi16a(p, v) { *(UInt16 *)(void *)(p) = (v); }
#define GetBe64a(p) GetBe64(p)
#define GetBe32a(p) GetBe32(p)
#define GetBe16a(p) GetBe16(p)
#define SetBe32a(p, v) SetBe32(p, v)
#define SetBe16a(p, v) SetBe16(p, v)
#else
#error Stop_Compiling_Unknown_Endian_CPU_a
#endif
#ifndef GetBe16_to32
#define GetBe16_to32(p) GetBe16(p)
#endif
#if defined(MY_CPU_X86_OR_AMD64) \
|| defined(MY_CPU_ARM_OR_ARM64) \
|| defined(MY_CPU_PPC_OR_PPC64)
#define Z7_CPU_FAST_ROTATE_SUPPORTED
#endif
#ifdef MY_CPU_X86_OR_AMD64
void Z7_FASTCALL z7_x86_cpuid(UInt32 a[4], UInt32 function);
UInt32 Z7_FASTCALL z7_x86_cpuid_GetMaxFunc(void);
#if defined(MY_CPU_AMD64)
#define Z7_IF_X86_CPUID_SUPPORTED
#else
#define Z7_IF_X86_CPUID_SUPPORTED if (z7_x86_cpuid_GetMaxFunc())
#endif
BoolInt CPU_IsSupported_AES(void);
BoolInt CPU_IsSupported_AVX(void);
BoolInt CPU_IsSupported_AVX2(void);
BoolInt CPU_IsSupported_AVX512F_AVX512VL(void);
BoolInt CPU_IsSupported_VAES_AVX2(void);
BoolInt CPU_IsSupported_CMOV(void);
BoolInt CPU_IsSupported_SSE(void);
BoolInt CPU_IsSupported_SSE2(void);
BoolInt CPU_IsSupported_SSSE3(void);
BoolInt CPU_IsSupported_SSE41(void);
BoolInt CPU_IsSupported_SHA(void);
BoolInt CPU_IsSupported_SHA512(void);
BoolInt CPU_IsSupported_PageGB(void);
#elif defined(MY_CPU_ARM_OR_ARM64)
BoolInt CPU_IsSupported_CRC32(void);
BoolInt CPU_IsSupported_NEON(void);
#if defined(_WIN32)
BoolInt CPU_IsSupported_CRYPTO(void);
#define CPU_IsSupported_SHA1 CPU_IsSupported_CRYPTO
#define CPU_IsSupported_SHA2 CPU_IsSupported_CRYPTO
#define CPU_IsSupported_AES CPU_IsSupported_CRYPTO
#else
BoolInt CPU_IsSupported_SHA1(void);
BoolInt CPU_IsSupported_SHA2(void);
BoolInt CPU_IsSupported_AES(void);
#endif
BoolInt CPU_IsSupported_SHA512(void);
#endif
#if defined(__APPLE__)
int z7_sysctlbyname_Get(const char *name, void *buf, size_t *bufSize);
int z7_sysctlbyname_Get_UInt32(const char *name, UInt32 *val);
#endif
EXTERN_C_END
#endif

View File

@@ -0,0 +1,19 @@
/* Delta.h -- Delta converter
2023-03-03 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_DELTA_H
#define ZIP7_INC_DELTA_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define DELTA_STATE_SIZE 256
void Delta_Init(Byte *state);
void Delta_Encode(Byte *state, unsigned delta, Byte *data, SizeT size);
void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,20 @@
/* DllSecur.h -- DLL loading for security
2023-03-03 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_DLL_SECUR_H
#define ZIP7_INC_DLL_SECUR_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#ifdef _WIN32
void My_SetDefaultDllDirectories(void);
void LoadSecurityDlls(void);
#endif
EXTERN_C_END
#endif

View File

@@ -0,0 +1,23 @@
/* HuffEnc.h -- Huffman encoding
2023-03-05 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_HUFF_ENC_H
#define ZIP7_INC_HUFF_ENC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/*
Conditions:
num <= 1024 = 2 ^ NUM_BITS
Sum(freqs) < 4M = 2 ^ (32 - NUM_BITS)
maxLen <= 16 = kMaxLen
Num_Items(p) >= HUFFMAN_TEMP_SIZE(num)
*/
void Huffman_Generate(const UInt32 *freqs, UInt32 *p, Byte *lens, UInt32 num, UInt32 maxLen);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,160 @@
/* LzFind.h -- Match finder for LZ algorithms
2024-01-22 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZ_FIND_H
#define ZIP7_INC_LZ_FIND_H
#include "7zTypes.h"
EXTERN_C_BEGIN
typedef UInt32 CLzRef;
typedef struct
{
const Byte *buffer;
UInt32 pos;
UInt32 posLimit;
UInt32 streamPos; /* wrap over Zero is allowed (streamPos < pos). Use (UInt32)(streamPos - pos) */
UInt32 lenLimit;
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
Byte streamEndWasReached;
Byte btMode;
Byte bigHash;
Byte directInput;
UInt32 matchMaxLen;
CLzRef *hash;
CLzRef *son;
UInt32 hashMask;
UInt32 cutValue;
Byte *bufBase;
ISeqInStreamPtr stream;
UInt32 blockSize;
UInt32 keepSizeBefore;
UInt32 keepSizeAfter;
UInt32 numHashBytes;
size_t directInputRem;
UInt32 historySize;
UInt32 fixedHashSize;
Byte numHashBytes_Min;
Byte numHashOutBits;
Byte _pad2_[2];
SRes result;
UInt32 crc[256];
size_t numRefs;
UInt64 expectedDataSize;
} CMatchFinder;
#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((const Byte *)(p)->buffer)
#define Inline_MatchFinder_GetNumAvailableBytes(p) ((UInt32)((p)->streamPos - (p)->pos))
/*
#define Inline_MatchFinder_IsFinishedOK(p) \
((p)->streamEndWasReached \
&& (p)->streamPos == (p)->pos \
&& (!(p)->directInput || (p)->directInputRem == 0))
*/
int MatchFinder_NeedMove(CMatchFinder *p);
/* Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); */
void MatchFinder_MoveBlock(CMatchFinder *p);
void MatchFinder_ReadIfRequired(CMatchFinder *p);
void MatchFinder_Construct(CMatchFinder *p);
/* (directInput = 0) is default value.
It's required to provide correct (directInput) value
before calling MatchFinder_Create().
You can set (directInput) by any of the following calls:
- MatchFinder_SET_DIRECT_INPUT_BUF()
- MatchFinder_SET_STREAM()
- MatchFinder_SET_STREAM_MODE()
*/
#define MatchFinder_SET_DIRECT_INPUT_BUF(p, _src_, _srcLen_) { \
(p)->stream = NULL; \
(p)->directInput = 1; \
(p)->buffer = (_src_); \
(p)->directInputRem = (_srcLen_); }
/*
#define MatchFinder_SET_STREAM_MODE(p) { \
(p)->directInput = 0; }
*/
#define MatchFinder_SET_STREAM(p, _stream_) { \
(p)->stream = _stream_; \
(p)->directInput = 0; }
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
ISzAllocPtr alloc);
void MatchFinder_Free(CMatchFinder *p, ISzAllocPtr alloc);
void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, size_t numItems);
/*
#define MatchFinder_INIT_POS(p, val) \
(p)->pos = (val); \
(p)->streamPos = (val);
*/
// void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
#define MatchFinder_REDUCE_OFFSETS(p, subValue) \
(p)->pos -= (subValue); \
(p)->streamPos -= (subValue);
UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
size_t _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
UInt32 *distances, UInt32 maxLen);
/*
Conditions:
Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
*/
typedef void (*Mf_Init_Func)(void *object);
typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
typedef UInt32 * (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
typedef void (*Mf_Skip_Func)(void *object, UInt32);
typedef struct
{
Mf_Init_Func Init;
Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
Mf_GetMatches_Func GetMatches;
Mf_Skip_Func Skip;
} IMatchFinder2;
void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder2 *vTable);
void MatchFinder_Init_LowHash(CMatchFinder *p);
void MatchFinder_Init_HighHash(CMatchFinder *p);
void MatchFinder_Init_4(CMatchFinder *p);
// void MatchFinder_Init(CMatchFinder *p);
void MatchFinder_Init(void *p);
UInt32* Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
UInt32* Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
void LzFindPrepare(void);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,112 @@
/* LzFindMt.h -- multithreaded Match finder for LZ algorithms
2024-01-22 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZ_FIND_MT_H
#define ZIP7_INC_LZ_FIND_MT_H
#include "LzFind.h"
#include "Threads.h"
EXTERN_C_BEGIN
typedef struct
{
UInt32 numProcessedBlocks;
CThread thread;
UInt64 affinity;
BoolInt wasCreated;
BoolInt needStart;
BoolInt csWasInitialized;
BoolInt csWasEntered;
BoolInt exit;
BoolInt stopWriting;
CAutoResetEvent canStart;
CAutoResetEvent wasStopped;
CSemaphore freeSemaphore;
CSemaphore filledSemaphore;
CCriticalSection cs;
// UInt32 numBlocks_Sent;
} CMtSync;
struct CMatchFinderMt_;
typedef UInt32 * (*Mf_Mix_Matches)(struct CMatchFinderMt_ *p, UInt32 matchMinPos, UInt32 *distances);
/* kMtCacheLineDummy must be >= size_of_CPU_cache_line */
#define kMtCacheLineDummy 128
typedef void (*Mf_GetHeads)(const Byte *buffer, UInt32 pos,
UInt32 *hash, UInt32 hashMask, UInt32 *heads, UInt32 numHeads, const UInt32 *crc);
typedef struct CMatchFinderMt_
{
/* LZ */
const Byte *pointerToCurPos;
UInt32 *btBuf;
const UInt32 *btBufPos;
const UInt32 *btBufPosLimit;
UInt32 lzPos;
UInt32 btNumAvailBytes;
UInt32 *hash;
UInt32 fixedHashSize;
// UInt32 hash4Mask;
UInt32 historySize;
const UInt32 *crc;
Mf_Mix_Matches MixMatchesFunc;
UInt32 failure_LZ_BT; // failure in BT transfered to LZ
// UInt32 failure_LZ_LZ; // failure in LZ tables
UInt32 failureBuf[1];
// UInt32 crc[256];
/* LZ + BT */
CMtSync btSync;
Byte btDummy[kMtCacheLineDummy];
/* BT */
UInt32 *hashBuf;
UInt32 hashBufPos;
UInt32 hashBufPosLimit;
UInt32 hashNumAvail;
UInt32 failure_BT;
CLzRef *son;
UInt32 matchMaxLen;
UInt32 numHashBytes;
UInt32 pos;
const Byte *buffer;
UInt32 cyclicBufferPos;
UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
UInt32 cutValue;
/* BT + Hash */
CMtSync hashSync;
/* Byte hashDummy[kMtCacheLineDummy]; */
/* Hash */
Mf_GetHeads GetHeadsFunc;
CMatchFinder *MatchFinder;
// CMatchFinder MatchFinder;
} CMatchFinderMt;
// only for Mt part
void MatchFinderMt_Construct(CMatchFinderMt *p);
void MatchFinderMt_Destruct(CMatchFinderMt *p, ISzAllocPtr alloc);
SRes MatchFinderMt_Create(CMatchFinderMt *p, UInt32 historySize, UInt32 keepAddBufferBefore,
UInt32 matchMaxLen, UInt32 keepAddBufferAfter, ISzAllocPtr alloc);
void MatchFinderMt_CreateVTable(CMatchFinderMt *p, IMatchFinder2 *vTable);
/* call MatchFinderMt_InitMt() before IMatchFinder::Init() */
SRes MatchFinderMt_InitMt(CMatchFinderMt *p);
void MatchFinderMt_ReleaseStream(CMatchFinderMt *p);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,34 @@
/* LzHash.h -- HASH constants for LZ algorithms
2023-03-05 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZ_HASH_H
#define ZIP7_INC_LZ_HASH_H
/*
(kHash2Size >= (1 << 8)) : Required
(kHash3Size >= (1 << 16)) : Required
*/
#define kHash2Size (1 << 10)
#define kHash3Size (1 << 16)
// #define kHash4Size (1 << 20)
#define kFix3HashSize (kHash2Size)
#define kFix4HashSize (kHash2Size + kHash3Size)
// #define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
/*
We use up to 3 crc values for hash:
crc0
crc1 << Shift_1
crc2 << Shift_2
(Shift_1 = 5) and (Shift_2 = 10) is good tradeoff.
Small values for Shift are not good for collision rate.
Big value for Shift_2 increases the minimum size
of hash table, that will be slow for small files.
*/
#define kLzHash_CrcShift_1 5
#define kLzHash_CrcShift_2 10
#endif

View File

@@ -0,0 +1,121 @@
/* Lzma2Dec.h -- LZMA2 Decoder
2023-03-03 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZMA2_DEC_H
#define ZIP7_INC_LZMA2_DEC_H
#include "LzmaDec.h"
EXTERN_C_BEGIN
/* ---------- State Interface ---------- */
typedef struct
{
unsigned state;
Byte control;
Byte needInitLevel;
Byte isExtraMode;
Byte _pad_;
UInt32 packSize;
UInt32 unpackSize;
CLzmaDec decoder;
} CLzma2Dec;
#define Lzma2Dec_CONSTRUCT(p) LzmaDec_CONSTRUCT(&(p)->decoder)
#define Lzma2Dec_Construct(p) Lzma2Dec_CONSTRUCT(p)
#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc)
#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc)
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc);
void Lzma2Dec_Init(CLzma2Dec *p);
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
LZMA_FINISH_ANY - use smallest number of input bytes
LZMA_FINISH_END - read EndOfStream marker after decoding
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
SZ_ERROR_DATA - Data error
*/
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- LZMA2 block and chunk parsing ---------- */
/*
Lzma2Dec_Parse() parses compressed data stream up to next independent block or next chunk data.
It can return LZMA_STATUS_* code or LZMA2_PARSE_STATUS_* code:
- LZMA2_PARSE_STATUS_NEW_BLOCK - there is new block, and 1 additional byte (control byte of next block header) was read from input.
- LZMA2_PARSE_STATUS_NEW_CHUNK - there is new chunk, and only lzma2 header of new chunk was read.
CLzma2Dec::unpackSize contains unpack size of that chunk
*/
typedef enum
{
/*
LZMA_STATUS_NOT_SPECIFIED // data error
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED //
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK // unused
*/
LZMA2_PARSE_STATUS_NEW_BLOCK = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK + 1,
LZMA2_PARSE_STATUS_NEW_CHUNK
} ELzma2ParseStatus;
ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
SizeT outSize, // output size
const Byte *src, SizeT *srcLen,
int checkFinishBlock // set (checkFinishBlock = 1), if it must read full input data, if decoder.dicPos reaches blockMax position.
);
/*
LZMA2 parser doesn't decode LZMA chunks, so we must read
full input LZMA chunk to decode some part of LZMA chunk.
Lzma2Dec_GetUnpackExtra() returns the value that shows
max possible number of output bytes that can be output by decoder
at current input positon.
*/
#define Lzma2Dec_GetUnpackExtra(p) ((p)->isExtraMode ? (p)->unpackSize : 0)
/* ---------- One Call Interface ---------- */
/*
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - use smallest number of input bytes
LZMA_FINISH_END - read EndOfStream marker after decoding
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
*/
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,81 @@
/* Lzma2DecMt.h -- LZMA2 Decoder Multi-thread
2023-04-13 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZMA2_DEC_MT_H
#define ZIP7_INC_LZMA2_DEC_MT_H
#include "7zTypes.h"
EXTERN_C_BEGIN
typedef struct
{
size_t inBufSize_ST;
size_t outStep_ST;
#ifndef Z7_ST
unsigned numThreads;
size_t inBufSize_MT;
size_t outBlockMax;
size_t inBlockMax;
#endif
} CLzma2DecMtProps;
/* init to single-thread mode */
void Lzma2DecMtProps_Init(CLzma2DecMtProps *p);
/* ---------- CLzma2DecMtHandle Interface ---------- */
/* Lzma2DecMt_ * functions can return the following exit codes:
SRes:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - ISeqOutStream write callback error
// SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/
typedef struct CLzma2DecMt CLzma2DecMt;
typedef CLzma2DecMt * CLzma2DecMtHandle;
// Z7_DECLARE_HANDLE(CLzma2DecMtHandle)
CLzma2DecMtHandle Lzma2DecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid);
void Lzma2DecMt_Destroy(CLzma2DecMtHandle p);
SRes Lzma2DecMt_Decode(CLzma2DecMtHandle p,
Byte prop,
const CLzma2DecMtProps *props,
ISeqOutStreamPtr outStream,
const UInt64 *outDataSize, // NULL means undefined
int finishMode, // 0 - partial unpacking is allowed, 1 - if lzma2 stream must be finished
// Byte *outBuf, size_t *outBufSize,
ISeqInStreamPtr inStream,
// const Byte *inData, size_t inDataSize,
// out variables:
UInt64 *inProcessed,
int *isMT, /* out: (*isMT == 0), if single thread decoding was used */
// UInt64 *outProcessed,
ICompressProgressPtr progress);
/* ---------- Read from CLzma2DecMtHandle Interface ---------- */
SRes Lzma2DecMt_Init(CLzma2DecMtHandle pp,
Byte prop,
const CLzma2DecMtProps *props,
const UInt64 *outDataSize, int finishMode,
ISeqInStreamPtr inStream);
SRes Lzma2DecMt_Read(CLzma2DecMtHandle pp,
Byte *data, size_t *outSize,
UInt64 *inStreamProcessed);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,57 @@
/* Lzma2Enc.h -- LZMA2 Encoder
2023-04-13 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZMA2_ENC_H
#define ZIP7_INC_LZMA2_ENC_H
#include "LzmaEnc.h"
EXTERN_C_BEGIN
#define LZMA2_ENC_PROPS_BLOCK_SIZE_AUTO 0
#define LZMA2_ENC_PROPS_BLOCK_SIZE_SOLID ((UInt64)(Int64)-1)
typedef struct
{
CLzmaEncProps lzmaProps;
UInt64 blockSize;
int numBlockThreads_Reduced;
int numBlockThreads_Max;
int numTotalThreads;
} CLzma2EncProps;
void Lzma2EncProps_Init(CLzma2EncProps *p);
void Lzma2EncProps_Normalize(CLzma2EncProps *p);
/* ---------- CLzmaEnc2Handle Interface ---------- */
/* Lzma2Enc_* functions can return the following exit codes:
SRes:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - ISeqOutStream write callback error
SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/
typedef struct CLzma2Enc CLzma2Enc;
typedef CLzma2Enc * CLzma2EncHandle;
// Z7_DECLARE_HANDLE(CLzma2EncHandle)
CLzma2EncHandle Lzma2Enc_Create(ISzAllocPtr alloc, ISzAllocPtr allocBig);
void Lzma2Enc_Destroy(CLzma2EncHandle p);
SRes Lzma2Enc_SetProps(CLzma2EncHandle p, const CLzma2EncProps *props);
void Lzma2Enc_SetDataSize(CLzma2EncHandle p, UInt64 expectedDataSiize);
Byte Lzma2Enc_WriteProperties(CLzma2EncHandle p);
SRes Lzma2Enc_Encode2(CLzma2EncHandle p,
ISeqOutStreamPtr outStream,
Byte *outBuf, size_t *outBufSize,
ISeqInStreamPtr inStream,
const Byte *inData, size_t inDataSize,
ICompressProgressPtr progress);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,111 @@
/* Lzma86.h -- LZMA + x86 (BCJ) Filter
2023-03-03 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZMA86_H
#define ZIP7_INC_LZMA86_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define LZMA86_SIZE_OFFSET (1 + 5)
#define LZMA86_HEADER_SIZE (LZMA86_SIZE_OFFSET + 8)
/*
It's an example for LZMA + x86 Filter use.
You can use .lzma86 extension, if you write that stream to file.
.lzma86 header adds one additional byte to standard .lzma header.
.lzma86 header (14 bytes):
Offset Size Description
0 1 = 0 - no filter, pure LZMA
= 1 - x86 filter + LZMA
1 1 lc, lp and pb in encoded form
2 4 dictSize (little endian)
6 8 uncompressed size (little endian)
Lzma86_Encode
-------------
level - compression level: 0 <= level <= 9, the default value for "level" is 5.
dictSize - The dictionary size in bytes. The maximum value is
128 MB = (1 << 27) bytes for 32-bit version
1 GB = (1 << 30) bytes for 64-bit version
The default value is 16 MB = (1 << 24) bytes, for level = 5.
It's recommended to use the dictionary that is larger than 4 KB and
that can be calculated as (1 << N) or (3 << N) sizes.
For better compression ratio dictSize must be >= inSize.
filterMode:
SZ_FILTER_NO - no Filter
SZ_FILTER_YES - x86 Filter
SZ_FILTER_AUTO - it tries both alternatives to select best.
Encoder will use 2 or 3 passes:
2 passes when FILTER_NO provides better compression.
3 passes when FILTER_YES provides better compression.
Lzma86Encode allocates Data with MyAlloc functions.
RAM Requirements for compressing:
RamSize = dictionarySize * 11.5 + 6MB + FilterBlockSize
filterMode FilterBlockSize
SZ_FILTER_NO 0
SZ_FILTER_YES inSize
SZ_FILTER_AUTO inSize
Return code:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/
enum ESzFilterMode
{
SZ_FILTER_NO,
SZ_FILTER_YES,
SZ_FILTER_AUTO
};
SRes Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
int level, UInt32 dictSize, int filterMode);
/*
Lzma86_GetUnpackSize:
In:
src - input data
srcLen - input data size
Out:
unpackSize - size of uncompressed stream
Return code:
SZ_OK - OK
SZ_ERROR_INPUT_EOF - Error in headers
*/
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize);
/*
Lzma86_Decode:
In:
dest - output data
destLen - output data size
src - input data
srcLen - input data size
Out:
destLen - processed output size
srcLen - processed input size
Return code:
SZ_OK - OK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - unsupported file
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer
*/
SRes Lzma86_Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,237 @@
/* LzmaDec.h -- LZMA Decoder
2023-04-02 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZMA_DEC_H
#define ZIP7_INC_LZMA_DEC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
/* #define Z7_LZMA_PROB32 */
/* Z7_LZMA_PROB32 can increase the speed on some CPUs,
but memory usage for CLzmaDec::probs will be doubled in that case */
typedef
#ifdef Z7_LZMA_PROB32
UInt32
#else
UInt16
#endif
CLzmaProb;
/* ---------- LZMA Properties ---------- */
#define LZMA_PROPS_SIZE 5
typedef struct
{
Byte lc;
Byte lp;
Byte pb;
Byte _pad_;
UInt32 dicSize;
} CLzmaProps;
/* LzmaProps_Decode - decodes properties
Returns:
SZ_OK
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
/* ---------- LZMA Decoder state ---------- */
/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
#define LZMA_REQUIRED_INPUT_MAX 20
typedef struct
{
/* Don't change this structure. ASM code can use it. */
CLzmaProps prop;
CLzmaProb *probs;
CLzmaProb *probs_1664;
Byte *dic;
SizeT dicBufSize;
SizeT dicPos;
const Byte *buf;
UInt32 range;
UInt32 code;
UInt32 processedPos;
UInt32 checkDicSize;
UInt32 reps[4];
UInt32 state;
UInt32 remainLen;
UInt32 numProbs;
unsigned tempBufSize;
Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
} CLzmaDec;
#define LzmaDec_CONSTRUCT(p) { (p)->dic = NULL; (p)->probs = NULL; }
#define LzmaDec_Construct(p) LzmaDec_CONSTRUCT(p)
void LzmaDec_Init(CLzmaDec *p);
/* There are two types of LZMA streams:
- Stream with end mark. That end mark adds about 6 bytes to compressed size.
- Stream without end mark. You must know exact uncompressed size to decompress such stream. */
typedef enum
{
LZMA_FINISH_ANY, /* finish at any point */
LZMA_FINISH_END /* block must be finished at the end */
} ELzmaFinishMode;
/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
You must use LZMA_FINISH_END, when you know that current output buffer
covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
and output value of destLen will be less than output buffer size limit.
You can check status result also.
You can use multiple checks to test data integrity after full decompression:
1) Check Result and "status" variable.
2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
You must use correct finish mode in that case. */
typedef enum
{
LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
} ELzmaStatus;
/* ELzmaStatus is used only as output value for function call */
/* ---------- Interfaces ---------- */
/* There are 3 levels of interfaces:
1) Dictionary Interface
2) Buffer Interface
3) One Call Interface
You can select any of these interfaces, but don't mix functions from different
groups for same object. */
/* There are two variants to allocate state for Dictionary Interface:
1) LzmaDec_Allocate / LzmaDec_Free
2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
You can use variant 2, if you set dictionary buffer manually.
For Buffer Interface you must always use variant 1.
LzmaDec_Allocate* can return:
SZ_OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
*/
SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_FreeProbs(CLzmaDec *p, ISzAllocPtr alloc);
SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAllocPtr alloc);
void LzmaDec_Free(CLzmaDec *p, ISzAllocPtr alloc);
/* ---------- Dictionary Interface ---------- */
/* You can use it, if you want to eliminate the overhead for data copying from
dictionary to some other external buffer.
You must work with CLzmaDec variables directly in this interface.
STEPS:
LzmaDec_Construct()
LzmaDec_Allocate()
for (each new stream)
{
LzmaDec_Init()
while (it needs more decompression)
{
LzmaDec_DecodeToDic()
use data from CLzmaDec::dic and update CLzmaDec::dicPos
}
}
LzmaDec_Free()
*/
/* LzmaDec_DecodeToDic
The decoding to internal dictionary buffer (CLzmaDec::dic).
You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
finishMode:
It has meaning only if the decoding reaches output limit (dicLimit).
LZMA_FINISH_ANY - Decode just dicLimit bytes.
LZMA_FINISH_END - Stream must be finished after dicLimit.
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_NEEDS_MORE_INPUT
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_FAIL - Some unexpected error: internal error of code, memory corruption or hardware failure
*/
SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- Buffer Interface ---------- */
/* It's zlib-like interface.
See LzmaDec_DecodeToDic description for information about STEPS and return results,
but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
to work with CLzmaDec variables manually.
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
*/
SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
/* ---------- One Call Interface ---------- */
/* LzmaDecode
finishMode:
It has meaning only if the decoding reaches output limit (*destLen).
LZMA_FINISH_ANY - Decode just destLen bytes.
LZMA_FINISH_END - Stream must be finished after (*destLen).
Returns:
SZ_OK
status:
LZMA_STATUS_FINISHED_WITH_MARK
LZMA_STATUS_NOT_FINISHED
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
SZ_ERROR_FAIL - Some unexpected error: internal error of code, memory corruption or hardware failure
*/
SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
ELzmaStatus *status, ISzAllocPtr alloc);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,83 @@
/* LzmaEnc.h -- LZMA Encoder
2023-04-13 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZMA_ENC_H
#define ZIP7_INC_LZMA_ENC_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define LZMA_PROPS_SIZE 5
typedef struct
{
int level; /* 0 <= level <= 9 */
UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
(1 << 12) <= dictSize <= (3 << 29) for 64-bit version
default = (1 << 24) */
int lc; /* 0 <= lc <= 8, default = 3 */
int lp; /* 0 <= lp <= 4, default = 0 */
int pb; /* 0 <= pb <= 4, default = 2 */
int algo; /* 0 - fast, 1 - normal, default = 1 */
int fb; /* 5 <= fb <= 273, default = 32 */
int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
int numHashBytes; /* 2, 3 or 4, default = 4 */
unsigned numHashOutBits; /* default = ? */
UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
int numThreads; /* 1 or 2, default = 2 */
// int _pad;
UInt64 reduceSize; /* estimated size of data that will be compressed. default = (UInt64)(Int64)-1.
Encoder uses this value to reduce dictionary size */
UInt64 affinity;
} CLzmaEncProps;
void LzmaEncProps_Init(CLzmaEncProps *p);
void LzmaEncProps_Normalize(CLzmaEncProps *p);
UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
/* ---------- CLzmaEncHandle Interface ---------- */
/* LzmaEnc* functions can return the following exit codes:
SRes:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater in props
SZ_ERROR_WRITE - ISeqOutStream write callback error
SZ_ERROR_OUTPUT_EOF - output buffer overflow - version with (Byte *) output
SZ_ERROR_PROGRESS - some break from progress callback
SZ_ERROR_THREAD - error in multithreading functions (only for Mt version)
*/
typedef struct CLzmaEnc CLzmaEnc;
typedef CLzmaEnc * CLzmaEncHandle;
// Z7_DECLARE_HANDLE(CLzmaEncHandle)
CLzmaEncHandle LzmaEnc_Create(ISzAllocPtr alloc);
void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
void LzmaEnc_SetDataSize(CLzmaEncHandle p, UInt64 expectedDataSiize);
SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
unsigned LzmaEnc_IsWriteEndMark(CLzmaEncHandle p);
SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStreamPtr outStream, ISeqInStreamPtr inStream,
ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
int writeEndMark, ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
/* ---------- One Call Interface ---------- */
SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
ICompressProgressPtr progress, ISzAllocPtr alloc, ISzAllocPtr allocBig);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,138 @@
/* LzmaLib.h -- LZMA library interface
2023-04-02 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_LZMA_LIB_H
#define ZIP7_INC_LZMA_LIB_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define Z7_STDAPI int Z7_STDCALL
#define LZMA_PROPS_SIZE 5
/*
RAM requirements for LZMA:
for compression: (dictSize * 11.5 + 6 MB) + state_size
for decompression: dictSize + state_size
state_size = (4 + (1.5 << (lc + lp))) KB
by default (lc=3, lp=0), state_size = 16 KB.
LZMA properties (5 bytes) format
Offset Size Description
0 1 lc, lp and pb in encoded form.
1 4 dictSize (little endian).
*/
/*
LzmaCompress
------------
outPropsSize -
In: the pointer to the size of outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
Out: the pointer to the size of written properties in outProps buffer; *outPropsSize = LZMA_PROPS_SIZE = 5.
LZMA Encoder will use defult values for any parameter, if it is
-1 for any from: level, loc, lp, pb, fb, numThreads
0 for dictSize
level - compression level: 0 <= level <= 9;
level dictSize algo fb
0: 64 KB 0 32
1: 256 KB 0 32
2: 1 MB 0 32
3: 4 MB 0 32
4: 16 MB 0 32
5: 16 MB 1 32
6: 32 MB 1 32
7: 32 MB 1 64
8: 64 MB 1 64
9: 64 MB 1 64
The default value for "level" is 5.
algo = 0 means fast method
algo = 1 means normal method
dictSize - The dictionary size in bytes. The maximum value is
128 MB = (1 << 27) bytes for 32-bit version
1 GB = (1 << 30) bytes for 64-bit version
The default value is 16 MB = (1 << 24) bytes.
It's recommended to use the dictionary that is larger than 4 KB and
that can be calculated as (1 << N) or (3 << N) sizes.
lc - The number of literal context bits (high bits of previous literal).
It can be in the range from 0 to 8. The default value is 3.
Sometimes lc=4 gives the gain for big files.
lp - The number of literal pos bits (low bits of current position for literals).
It can be in the range from 0 to 4. The default value is 0.
The lp switch is intended for periodical data when the period is equal to 2^lp.
For example, for 32-bit (4 bytes) periodical data you can use lp=2. Often it's
better to set lc=0, if you change lp switch.
pb - The number of pos bits (low bits of current position).
It can be in the range from 0 to 4. The default value is 2.
The pb switch is intended for periodical data when the period is equal 2^pb.
fb - Word size (the number of fast bytes).
It can be in the range from 5 to 273. The default value is 32.
Usually, a big number gives a little bit better compression ratio and
slower compression process.
numThreads - The number of thereads. 1 or 2. The default value is 2.
Fast mode (algo = 0) can use only 1 thread.
In:
dest - output data buffer
destLen - output data buffer size
src - input data
srcLen - input data size
Out:
destLen - processed output size
Returns:
SZ_OK - OK
SZ_ERROR_MEM - Memory allocation error
SZ_ERROR_PARAM - Incorrect paramater
SZ_ERROR_OUTPUT_EOF - output buffer overflow
SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
*/
Z7_STDAPI LzmaCompress(unsigned char *dest, size_t *destLen, const unsigned char *src, size_t srcLen,
unsigned char *outProps, size_t *outPropsSize, /* *outPropsSize must be = 5 */
int level, /* 0 <= level <= 9, default = 5 */
unsigned dictSize, /* default = (1 << 24) */
int lc, /* 0 <= lc <= 8, default = 3 */
int lp, /* 0 <= lp <= 4, default = 0 */
int pb, /* 0 <= pb <= 4, default = 2 */
int fb, /* 5 <= fb <= 273, default = 32 */
int numThreads /* 1 or 2, default = 2 */
);
/*
LzmaUncompress
--------------
In:
dest - output data buffer
destLen - output data buffer size
src - input data
srcLen - input data size
Out:
destLen - processed output size
srcLen - processed input size
Returns:
SZ_OK - OK
SZ_ERROR_DATA - Data error
SZ_ERROR_MEM - Memory allocation arror
SZ_ERROR_UNSUPPORTED - Unsupported properties
SZ_ERROR_INPUT_EOF - it needs more bytes in input buffer (src)
*/
Z7_STDAPI LzmaUncompress(unsigned char *dest, size_t *destLen, const unsigned char *src, SizeT *srcLen,
const unsigned char *props, size_t propsSize);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,34 @@
/* Md5.h -- MD5 Hash
: Igor Pavlov : Public domain */
#ifndef ZIP7_INC_MD5_H
#define ZIP7_INC_MD5_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define MD5_NUM_BLOCK_WORDS 16
#define MD5_NUM_DIGEST_WORDS 4
#define MD5_BLOCK_SIZE (MD5_NUM_BLOCK_WORDS * 4)
#define MD5_DIGEST_SIZE (MD5_NUM_DIGEST_WORDS * 4)
typedef struct
{
UInt64 count;
UInt64 _pad_1;
// we want 16-bytes alignment here
UInt32 state[MD5_NUM_DIGEST_WORDS];
UInt64 _pad_2[4];
// we want 64-bytes alignment here
Byte buffer[MD5_BLOCK_SIZE];
} CMd5;
void Md5_Init(CMd5 *p);
void Md5_Update(CMd5 *p, const Byte *data, size_t size);
void Md5_Final(CMd5 *p, Byte *digest);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,141 @@
/* MtCoder.h -- Multi-thread Coder
2023-04-13 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_MT_CODER_H
#define ZIP7_INC_MT_CODER_H
#include "MtDec.h"
EXTERN_C_BEGIN
/*
if ( defined MTCODER_USE_WRITE_THREAD) : main thread writes all data blocks to output stream
if (not defined MTCODER_USE_WRITE_THREAD) : any coder thread can write data blocks to output stream
*/
/* #define MTCODER_USE_WRITE_THREAD */
#ifndef Z7_ST
#define MTCODER_GET_NUM_BLOCKS_FROM_THREADS(numThreads) ((numThreads) + (numThreads) / 8 + 1)
#define MTCODER_THREADS_MAX 64
#define MTCODER_BLOCKS_MAX (MTCODER_GET_NUM_BLOCKS_FROM_THREADS(MTCODER_THREADS_MAX) + 3)
#else
#define MTCODER_THREADS_MAX 1
#define MTCODER_BLOCKS_MAX 1
#endif
#ifndef Z7_ST
typedef struct
{
ICompressProgress vt;
CMtProgress *mtProgress;
UInt64 inSize;
UInt64 outSize;
} CMtProgressThunk;
void MtProgressThunk_CreateVTable(CMtProgressThunk *p);
#define MtProgressThunk_INIT(p) { (p)->inSize = 0; (p)->outSize = 0; }
struct CMtCoder_;
typedef struct
{
struct CMtCoder_ *mtCoder;
unsigned index;
int stop;
Byte *inBuf;
CAutoResetEvent startEvent;
CThread thread;
} CMtCoderThread;
typedef struct
{
SRes (*Code)(void *p, unsigned coderIndex, unsigned outBufIndex,
const Byte *src, size_t srcSize, int finished);
SRes (*Write)(void *p, unsigned outBufIndex);
} IMtCoderCallback2;
typedef struct
{
SRes res;
unsigned bufIndex;
BoolInt finished;
} CMtCoderBlock;
typedef struct CMtCoder_
{
/* input variables */
size_t blockSize; /* size of input block */
unsigned numThreadsMax;
UInt64 expectedDataSize;
ISeqInStreamPtr inStream;
const Byte *inData;
size_t inDataSize;
ICompressProgressPtr progress;
ISzAllocPtr allocBig;
IMtCoderCallback2 *mtCallback;
void *mtCallbackObject;
/* internal variables */
size_t allocatedBufsSize;
CAutoResetEvent readEvent;
CSemaphore blocksSemaphore;
BoolInt stopReading;
SRes readRes;
#ifdef MTCODER_USE_WRITE_THREAD
CAutoResetEvent writeEvents[MTCODER_BLOCKS_MAX];
#else
CAutoResetEvent finishedEvent;
SRes writeRes;
unsigned writeIndex;
Byte ReadyBlocks[MTCODER_BLOCKS_MAX];
LONG numFinishedThreads;
#endif
unsigned numStartedThreadsLimit;
unsigned numStartedThreads;
unsigned numBlocksMax;
unsigned blockIndex;
UInt64 readProcessed;
CCriticalSection cs;
unsigned freeBlockHead;
unsigned freeBlockList[MTCODER_BLOCKS_MAX];
CMtProgress mtProgress;
CMtCoderBlock blocks[MTCODER_BLOCKS_MAX];
CMtCoderThread threads[MTCODER_THREADS_MAX];
} CMtCoder;
void MtCoder_Construct(CMtCoder *p);
void MtCoder_Destruct(CMtCoder *p);
SRes MtCoder_Code(CMtCoder *p);
#endif
EXTERN_C_END
#endif

View File

@@ -0,0 +1,202 @@
/* MtDec.h -- Multi-thread Decoder
2023-04-02 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_MT_DEC_H
#define ZIP7_INC_MT_DEC_H
#include "7zTypes.h"
#ifndef Z7_ST
#include "Threads.h"
#endif
EXTERN_C_BEGIN
#ifndef Z7_ST
#ifndef Z7_ST
#define MTDEC_THREADS_MAX 32
#else
#define MTDEC_THREADS_MAX 1
#endif
typedef struct
{
ICompressProgressPtr progress;
SRes res;
UInt64 totalInSize;
UInt64 totalOutSize;
CCriticalSection cs;
} CMtProgress;
void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress);
SRes MtProgress_Progress_ST(CMtProgress *p);
SRes MtProgress_ProgressAdd(CMtProgress *p, UInt64 inSize, UInt64 outSize);
SRes MtProgress_GetError(CMtProgress *p);
void MtProgress_SetError(CMtProgress *p, SRes res);
struct CMtDec;
typedef struct
{
struct CMtDec_ *mtDec;
unsigned index;
void *inBuf;
size_t inDataSize_Start; // size of input data in start block
UInt64 inDataSize; // total size of input data in all blocks
CThread thread;
CAutoResetEvent canRead;
CAutoResetEvent canWrite;
void *allocaPtr;
} CMtDecThread;
void MtDecThread_FreeInBufs(CMtDecThread *t);
typedef enum
{
MTDEC_PARSE_CONTINUE, // continue this block with more input data
MTDEC_PARSE_OVERFLOW, // MT buffers overflow, need switch to single-thread
MTDEC_PARSE_NEW, // new block
MTDEC_PARSE_END // end of block threading. But we still can return to threading after Write(&needContinue)
} EMtDecParseState;
typedef struct
{
// in
int startCall;
const Byte *src;
size_t srcSize;
// in : (srcSize == 0) is allowed
// out : it's allowed to return less that actually was used ?
int srcFinished;
// out
EMtDecParseState state;
BoolInt canCreateNewThread;
UInt64 outPos; // check it (size_t)
} CMtDecCallbackInfo;
typedef struct
{
void (*Parse)(void *p, unsigned coderIndex, CMtDecCallbackInfo *ci);
// PreCode() and Code():
// (SRes_return_result != SZ_OK) means stop decoding, no need another blocks
SRes (*PreCode)(void *p, unsigned coderIndex);
SRes (*Code)(void *p, unsigned coderIndex,
const Byte *src, size_t srcSize, int srcFinished,
UInt64 *inCodePos, UInt64 *outCodePos, int *stop);
// stop - means stop another Code calls
/* Write() must be called, if Parse() was called
set (needWrite) if
{
&& (was not interrupted by progress)
&& (was not interrupted in previous block)
}
out:
if (*needContinue), decoder still need to continue decoding with new iteration,
even after MTDEC_PARSE_END
if (*canRecode), we didn't flush current block data, so we still can decode current block later.
*/
SRes (*Write)(void *p, unsigned coderIndex,
BoolInt needWriteToStream,
const Byte *src, size_t srcSize, BoolInt isCross,
// int srcFinished,
BoolInt *needContinue,
BoolInt *canRecode);
} IMtDecCallback2;
typedef struct CMtDec_
{
/* input variables */
size_t inBufSize; /* size of input block */
unsigned numThreadsMax;
// size_t inBlockMax;
unsigned numThreadsMax_2;
ISeqInStreamPtr inStream;
// const Byte *inData;
// size_t inDataSize;
ICompressProgressPtr progress;
ISzAllocPtr alloc;
IMtDecCallback2 *mtCallback;
void *mtCallbackObject;
/* internal variables */
size_t allocatedBufsSize;
BoolInt exitThread;
WRes exitThreadWRes;
UInt64 blockIndex;
BoolInt isAllocError;
BoolInt overflow;
SRes threadingErrorSRes;
BoolInt needContinue;
// CAutoResetEvent finishedEvent;
SRes readRes;
SRes codeRes;
BoolInt wasInterrupted;
unsigned numStartedThreads_Limit;
unsigned numStartedThreads;
Byte *crossBlock;
size_t crossStart;
size_t crossEnd;
UInt64 readProcessed;
BoolInt readWasFinished;
UInt64 inProcessed;
unsigned filledThreadStart;
unsigned numFilledThreads;
#ifndef Z7_ST
BoolInt needInterrupt;
UInt64 interruptIndex;
CMtProgress mtProgress;
CMtDecThread threads[MTDEC_THREADS_MAX];
#endif
} CMtDec;
void MtDec_Construct(CMtDec *p);
void MtDec_Destruct(CMtDec *p);
/*
MtDec_Code() returns:
SZ_OK - in most cases
MY_SRes_HRESULT_FROM_WRes(WRes_error) - in case of unexpected error in threading function
*/
SRes MtDec_Code(CMtDec *p);
Byte *MtDec_GetCrossBuff(CMtDec *p);
int MtDec_PrepareRead(CMtDec *p);
const Byte *MtDec_Read(CMtDec *p, size_t *inLim);
#endif
EXTERN_C_END
#endif

View File

@@ -0,0 +1,169 @@
/* Ppmd.h -- PPMD codec common code
2023-03-05 : Igor Pavlov : Public domain
This code is based on PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef ZIP7_INC_PPMD_H
#define ZIP7_INC_PPMD_H
#include "CpuArch.h"
EXTERN_C_BEGIN
#if defined(MY_CPU_SIZEOF_POINTER) && (MY_CPU_SIZEOF_POINTER == 4)
/*
PPMD code always uses 32-bit internal fields in PPMD structures to store internal references in main block.
if (PPMD_32BIT is defined), the PPMD code stores internal pointers to 32-bit reference fields.
if (PPMD_32BIT is NOT defined), the PPMD code stores internal UInt32 offsets to reference fields.
if (pointer size is 64-bit), then (PPMD_32BIT) mode is not allowed,
if (pointer size is 32-bit), then (PPMD_32BIT) mode is optional,
and it's allowed to disable PPMD_32BIT mode even if pointer is 32-bit.
PPMD code works slightly faster in (PPMD_32BIT) mode.
*/
#define PPMD_32BIT
#endif
#define PPMD_INT_BITS 7
#define PPMD_PERIOD_BITS 7
#define PPMD_BIN_SCALE (1 << (PPMD_INT_BITS + PPMD_PERIOD_BITS))
#define PPMD_GET_MEAN_SPEC(summ, shift, round) (((summ) + (1 << ((shift) - (round)))) >> (shift))
#define PPMD_GET_MEAN(summ) PPMD_GET_MEAN_SPEC((summ), PPMD_PERIOD_BITS, 2)
#define PPMD_UPDATE_PROB_0(prob) ((prob) + (1 << PPMD_INT_BITS) - PPMD_GET_MEAN(prob))
#define PPMD_UPDATE_PROB_1(prob) ((prob) - PPMD_GET_MEAN(prob))
#define PPMD_N1 4
#define PPMD_N2 4
#define PPMD_N3 4
#define PPMD_N4 ((128 + 3 - 1 * PPMD_N1 - 2 * PPMD_N2 - 3 * PPMD_N3) / 4)
#define PPMD_NUM_INDEXES (PPMD_N1 + PPMD_N2 + PPMD_N3 + PPMD_N4)
MY_CPU_pragma_pack_push_1
/* Most compilers works OK here even without #pragma pack(push, 1), but some GCC compilers need it. */
/* SEE-contexts for PPM-contexts with masked symbols */
typedef struct
{
UInt16 Summ; /* Freq */
Byte Shift; /* Speed of Freq change; low Shift is for fast change */
Byte Count; /* Count to next change of Shift */
} CPpmd_See;
#define Ppmd_See_UPDATE(p) \
{ if ((p)->Shift < PPMD_PERIOD_BITS && --(p)->Count == 0) \
{ (p)->Summ = (UInt16)((p)->Summ << 1); \
(p)->Count = (Byte)(3 << (p)->Shift++); }}
typedef struct
{
Byte Symbol;
Byte Freq;
UInt16 Successor_0;
UInt16 Successor_1;
} CPpmd_State;
typedef struct CPpmd_State2_
{
Byte Symbol;
Byte Freq;
} CPpmd_State2;
typedef struct CPpmd_State4_
{
UInt16 Successor_0;
UInt16 Successor_1;
} CPpmd_State4;
MY_CPU_pragma_pop
/*
PPMD code can write full CPpmd_State structure data to CPpmd*_Context
at (byte offset = 2) instead of some fields of original CPpmd*_Context structure.
If we use pointers to different types, but that point to shared
memory space, we can have aliasing problem (strict aliasing).
XLC compiler in -O2 mode can change the order of memory write instructions
in relation to read instructions, if we have use pointers to different types.
To solve that aliasing problem we use combined CPpmd*_Context structure
with unions that contain the fields from both structures:
the original CPpmd*_Context and CPpmd_State.
So we can access the fields from both structures via one pointer,
and the compiler doesn't change the order of write instructions
in relation to read instructions.
If we don't use memory write instructions to shared memory in
some local code, and we use only reading instructions (read only),
then probably it's safe to use pointers to different types for reading.
*/
#ifdef PPMD_32BIT
#define Ppmd_Ref_Type(type) type *
#define Ppmd_GetRef(p, ptr) (ptr)
#define Ppmd_GetPtr(p, ptr) (ptr)
#define Ppmd_GetPtr_Type(p, ptr, note_type) (ptr)
#else
#define Ppmd_Ref_Type(type) UInt32
#define Ppmd_GetRef(p, ptr) ((UInt32)((Byte *)(ptr) - (p)->Base))
#define Ppmd_GetPtr(p, offs) ((void *)((p)->Base + (offs)))
#define Ppmd_GetPtr_Type(p, offs, type) ((type *)Ppmd_GetPtr(p, offs))
#endif // PPMD_32BIT
typedef Ppmd_Ref_Type(CPpmd_State) CPpmd_State_Ref;
typedef Ppmd_Ref_Type(void) CPpmd_Void_Ref;
typedef Ppmd_Ref_Type(Byte) CPpmd_Byte_Ref;
/*
#ifdef MY_CPU_LE_UNALIGN
// the unaligned 32-bit access latency can be too large, if the data is not in L1 cache.
#define Ppmd_GET_SUCCESSOR(p) ((CPpmd_Void_Ref)*(const UInt32 *)(const void *)&(p)->Successor_0)
#define Ppmd_SET_SUCCESSOR(p, v) *(UInt32 *)(void *)(void *)&(p)->Successor_0 = (UInt32)(v)
#else
*/
/*
We can write 16-bit halves to 32-bit (Successor) field in any selected order.
But the native order is more consistent way.
So we use the native order, if LE/BE order can be detected here at compile time.
*/
#ifdef MY_CPU_BE
#define Ppmd_GET_SUCCESSOR(p) \
( (CPpmd_Void_Ref) (((UInt32)(p)->Successor_0 << 16) | (p)->Successor_1) )
#define Ppmd_SET_SUCCESSOR(p, v) { \
(p)->Successor_0 = (UInt16)(((UInt32)(v) >> 16) /* & 0xFFFF */); \
(p)->Successor_1 = (UInt16)((UInt32)(v) /* & 0xFFFF */); }
#else
#define Ppmd_GET_SUCCESSOR(p) \
( (CPpmd_Void_Ref) ((p)->Successor_0 | ((UInt32)(p)->Successor_1 << 16)) )
#define Ppmd_SET_SUCCESSOR(p, v) { \
(p)->Successor_0 = (UInt16)((UInt32)(v) /* & 0xFFFF */); \
(p)->Successor_1 = (UInt16)(((UInt32)(v) >> 16) /* & 0xFFFF */); }
#endif
// #endif
#define PPMD_SetAllBitsIn256Bytes(p) \
{ size_t z; for (z = 0; z < 256 / sizeof(p[0]); z += 8) { \
p[z+7] = p[z+6] = p[z+5] = p[z+4] = p[z+3] = p[z+2] = p[z+1] = p[z+0] = ~(size_t)0; }}
EXTERN_C_END
#endif

View File

@@ -0,0 +1,181 @@
/* Ppmd7.h -- Ppmd7 (PPMdH) compression codec
2023-04-02 : Igor Pavlov : Public domain
This code is based on:
PPMd var.H (2001): Dmitry Shkarin : Public domain */
#ifndef ZIP7_INC_PPMD7_H
#define ZIP7_INC_PPMD7_H
#include "Ppmd.h"
EXTERN_C_BEGIN
#define PPMD7_MIN_ORDER 2
#define PPMD7_MAX_ORDER 64
#define PPMD7_MIN_MEM_SIZE (1 << 11)
#define PPMD7_MAX_MEM_SIZE (0xFFFFFFFF - 12 * 3)
struct CPpmd7_Context_;
typedef Ppmd_Ref_Type(struct CPpmd7_Context_) CPpmd7_Context_Ref;
// MY_CPU_pragma_pack_push_1
typedef struct CPpmd7_Context_
{
UInt16 NumStats;
union
{
UInt16 SummFreq;
CPpmd_State2 State2;
} Union2;
union
{
CPpmd_State_Ref Stats;
CPpmd_State4 State4;
} Union4;
CPpmd7_Context_Ref Suffix;
} CPpmd7_Context;
// MY_CPU_pragma_pop
#define Ppmd7Context_OneState(p) ((CPpmd_State *)&(p)->Union2)
typedef struct
{
UInt32 Range;
UInt32 Code;
UInt32 Low;
IByteInPtr Stream;
} CPpmd7_RangeDec;
typedef struct
{
UInt32 Range;
Byte Cache;
// Byte _dummy_[3];
UInt64 Low;
UInt64 CacheSize;
IByteOutPtr Stream;
} CPpmd7z_RangeEnc;
typedef struct
{
CPpmd7_Context *MinContext, *MaxContext;
CPpmd_State *FoundState;
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, HiBitsFlag;
Int32 RunLength, InitRL; /* must be 32-bit at least */
UInt32 Size;
UInt32 GlueCount;
UInt32 AlignOffset;
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
union
{
CPpmd7_RangeDec dec;
CPpmd7z_RangeEnc enc;
} rc;
Byte Indx2Units[PPMD_NUM_INDEXES + 2]; // +2 for alignment
Byte Units2Indx[128];
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
Byte NS2BSIndx[256], NS2Indx[256];
Byte ExpEscape[16];
CPpmd_See DummySee, See[25][16];
UInt16 BinSumm[128][64];
// int LastSymbol;
} CPpmd7;
void Ppmd7_Construct(CPpmd7 *p);
BoolInt Ppmd7_Alloc(CPpmd7 *p, UInt32 size, ISzAllocPtr alloc);
void Ppmd7_Free(CPpmd7 *p, ISzAllocPtr alloc);
void Ppmd7_Init(CPpmd7 *p, unsigned maxOrder);
#define Ppmd7_WasAllocated(p) ((p)->Base != NULL)
/* ---------- Internal Functions ---------- */
#define Ppmd7_GetPtr(p, ptr) Ppmd_GetPtr(p, ptr)
#define Ppmd7_GetContext(p, ptr) Ppmd_GetPtr_Type(p, ptr, CPpmd7_Context)
#define Ppmd7_GetStats(p, ctx) Ppmd_GetPtr_Type(p, (ctx)->Union4.Stats, CPpmd_State)
void Ppmd7_Update1(CPpmd7 *p);
void Ppmd7_Update1_0(CPpmd7 *p);
void Ppmd7_Update2(CPpmd7 *p);
#define PPMD7_HiBitsFlag_3(sym) ((((unsigned)sym + 0xC0) >> (8 - 3)) & (1 << 3))
#define PPMD7_HiBitsFlag_4(sym) ((((unsigned)sym + 0xC0) >> (8 - 4)) & (1 << 4))
// #define PPMD7_HiBitsFlag_3(sym) ((sym) < 0x40 ? 0 : (1 << 3))
// #define PPMD7_HiBitsFlag_4(sym) ((sym) < 0x40 ? 0 : (1 << 4))
#define Ppmd7_GetBinSumm(p) \
&p->BinSumm[(size_t)(unsigned)Ppmd7Context_OneState(p->MinContext)->Freq - 1] \
[ p->PrevSuccess + ((p->RunLength >> 26) & 0x20) \
+ p->NS2BSIndx[(size_t)Ppmd7_GetContext(p, p->MinContext->Suffix)->NumStats - 1] \
+ PPMD7_HiBitsFlag_4(Ppmd7Context_OneState(p->MinContext)->Symbol) \
+ (p->HiBitsFlag = PPMD7_HiBitsFlag_3(p->FoundState->Symbol)) ]
CPpmd_See *Ppmd7_MakeEscFreq(CPpmd7 *p, unsigned numMasked, UInt32 *scale);
/*
We support two versions of Ppmd7 (PPMdH) methods that use same CPpmd7 structure:
1) Ppmd7a_*: original PPMdH
2) Ppmd7z_*: modified PPMdH with 7z Range Coder
Ppmd7_*: the structures and functions that are common for both versions of PPMd7 (PPMdH)
*/
/* ---------- Decode ---------- */
#define PPMD7_SYM_END (-1)
#define PPMD7_SYM_ERROR (-2)
/*
You must set (CPpmd7::rc.dec.Stream) before Ppmd7*_RangeDec_Init()
Ppmd7*_DecodeSymbol()
out:
>= 0 : decoded byte
-1 : PPMD7_SYM_END : End of payload marker
-2 : PPMD7_SYM_ERROR : Data error
*/
/* Ppmd7a_* : original PPMdH */
BoolInt Ppmd7a_RangeDec_Init(CPpmd7_RangeDec *p);
#define Ppmd7a_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd7a_DecodeSymbol(CPpmd7 *p);
/* Ppmd7z_* : modified PPMdH with 7z Range Coder */
BoolInt Ppmd7z_RangeDec_Init(CPpmd7_RangeDec *p);
#define Ppmd7z_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd7z_DecodeSymbol(CPpmd7 *p);
// Byte *Ppmd7z_DecodeSymbols(CPpmd7 *p, Byte *buf, const Byte *lim);
/* ---------- Encode ---------- */
void Ppmd7z_Init_RangeEnc(CPpmd7 *p);
void Ppmd7z_Flush_RangeEnc(CPpmd7 *p);
// void Ppmd7z_EncodeSymbol(CPpmd7 *p, int symbol);
void Ppmd7z_EncodeSymbols(CPpmd7 *p, const Byte *buf, const Byte *lim);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,181 @@
/* Ppmd8.h -- Ppmd8 (PPMdI) compression codec
2023-04-02 : Igor Pavlov : Public domain
This code is based on:
PPMd var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
#ifndef ZIP7_INC_PPMD8_H
#define ZIP7_INC_PPMD8_H
#include "Ppmd.h"
EXTERN_C_BEGIN
#define PPMD8_MIN_ORDER 2
#define PPMD8_MAX_ORDER 16
struct CPpmd8_Context_;
typedef Ppmd_Ref_Type(struct CPpmd8_Context_) CPpmd8_Context_Ref;
// MY_CPU_pragma_pack_push_1
typedef struct CPpmd8_Context_
{
Byte NumStats;
Byte Flags;
union
{
UInt16 SummFreq;
CPpmd_State2 State2;
} Union2;
union
{
CPpmd_State_Ref Stats;
CPpmd_State4 State4;
} Union4;
CPpmd8_Context_Ref Suffix;
} CPpmd8_Context;
// MY_CPU_pragma_pop
#define Ppmd8Context_OneState(p) ((CPpmd_State *)&(p)->Union2)
/* PPMdI code rev.2 contains the fix over PPMdI code rev.1.
But the code PPMdI.2 is not compatible with PPMdI.1 for some files compressed
in FREEZE mode. So we disable FREEZE mode support. */
// #define PPMD8_FREEZE_SUPPORT
enum
{
PPMD8_RESTORE_METHOD_RESTART,
PPMD8_RESTORE_METHOD_CUT_OFF
#ifdef PPMD8_FREEZE_SUPPORT
, PPMD8_RESTORE_METHOD_FREEZE
#endif
, PPMD8_RESTORE_METHOD_UNSUPPPORTED
};
typedef struct
{
CPpmd8_Context *MinContext, *MaxContext;
CPpmd_State *FoundState;
unsigned OrderFall, InitEsc, PrevSuccess, MaxOrder, RestoreMethod;
Int32 RunLength, InitRL; /* must be 32-bit at least */
UInt32 Size;
UInt32 GlueCount;
UInt32 AlignOffset;
Byte *Base, *LoUnit, *HiUnit, *Text, *UnitsStart;
UInt32 Range;
UInt32 Code;
UInt32 Low;
union
{
IByteInPtr In;
IByteOutPtr Out;
} Stream;
Byte Indx2Units[PPMD_NUM_INDEXES + 2]; // +2 for alignment
Byte Units2Indx[128];
CPpmd_Void_Ref FreeList[PPMD_NUM_INDEXES];
UInt32 Stamps[PPMD_NUM_INDEXES];
Byte NS2BSIndx[256], NS2Indx[260];
Byte ExpEscape[16];
CPpmd_See DummySee, See[24][32];
UInt16 BinSumm[25][64];
} CPpmd8;
void Ppmd8_Construct(CPpmd8 *p);
BoolInt Ppmd8_Alloc(CPpmd8 *p, UInt32 size, ISzAllocPtr alloc);
void Ppmd8_Free(CPpmd8 *p, ISzAllocPtr alloc);
void Ppmd8_Init(CPpmd8 *p, unsigned maxOrder, unsigned restoreMethod);
#define Ppmd8_WasAllocated(p) ((p)->Base != NULL)
/* ---------- Internal Functions ---------- */
#define Ppmd8_GetPtr(p, ptr) Ppmd_GetPtr(p, ptr)
#define Ppmd8_GetContext(p, ptr) Ppmd_GetPtr_Type(p, ptr, CPpmd8_Context)
#define Ppmd8_GetStats(p, ctx) Ppmd_GetPtr_Type(p, (ctx)->Union4.Stats, CPpmd_State)
void Ppmd8_Update1(CPpmd8 *p);
void Ppmd8_Update1_0(CPpmd8 *p);
void Ppmd8_Update2(CPpmd8 *p);
#define Ppmd8_GetBinSumm(p) \
&p->BinSumm[p->NS2Indx[(size_t)Ppmd8Context_OneState(p->MinContext)->Freq - 1]] \
[ p->PrevSuccess + ((p->RunLength >> 26) & 0x20) \
+ p->NS2BSIndx[Ppmd8_GetContext(p, p->MinContext->Suffix)->NumStats] + \
+ p->MinContext->Flags ]
CPpmd_See *Ppmd8_MakeEscFreq(CPpmd8 *p, unsigned numMasked, UInt32 *scale);
/* 20.01: the original PPMdI encoder and decoder probably could work incorrectly in some rare cases,
where the original PPMdI code can give "Divide by Zero" operation.
We use the following fix to allow correct working of encoder and decoder in any cases.
We correct (Escape_Freq) and (_sum_), if (_sum_) is larger than p->Range) */
#define PPMD8_CORRECT_SUM_RANGE(p, _sum_) if (_sum_ > p->Range /* /1 */) _sum_ = p->Range;
/* ---------- Decode ---------- */
#define PPMD8_SYM_END (-1)
#define PPMD8_SYM_ERROR (-2)
/*
You must set (CPpmd8::Stream.In) before Ppmd8_RangeDec_Init()
Ppmd8_DecodeSymbol()
out:
>= 0 : decoded byte
-1 : PPMD8_SYM_END : End of payload marker
-2 : PPMD8_SYM_ERROR : Data error
*/
BoolInt Ppmd8_Init_RangeDec(CPpmd8 *p);
#define Ppmd8_RangeDec_IsFinishedOK(p) ((p)->Code == 0)
int Ppmd8_DecodeSymbol(CPpmd8 *p);
/* ---------- Encode ---------- */
#define Ppmd8_Init_RangeEnc(p) { (p)->Low = 0; (p)->Range = 0xFFFFFFFF; }
void Ppmd8_Flush_RangeEnc(CPpmd8 *p);
void Ppmd8_EncodeSymbol(CPpmd8 *p, int symbol);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,127 @@
/* Precomp.h -- precompilation file
2024-01-25 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_PRECOMP_H
#define ZIP7_INC_PRECOMP_H
/*
this file must be included before another *.h files and before <windows.h>.
this file is included from the following files:
C\*.c
C\Util\*\Precomp.h <- C\Util\*\*.c
CPP\Common\Common.h <- *\StdAfx.h <- *\*.cpp
this file can set the following macros:
Z7_LARGE_PAGES 1
Z7_LONG_PATH 1
Z7_WIN32_WINNT_MIN 0x0500 (or higher) : we require at least win2000+ for 7-Zip
_WIN32_WINNT 0x0500 (or higher)
WINVER _WIN32_WINNT
UNICODE 1
_UNICODE 1
*/
#include "Compiler.h"
#ifdef _MSC_VER
// #pragma warning(disable : 4206) // nonstandard extension used : translation unit is empty
#if _MSC_VER >= 1912
// #pragma warning(disable : 5039) // pointer or reference to potentially throwing function passed to 'extern "C"' function under - EHc.Undefined behavior may occur if this function throws an exception.
#endif
#endif
/*
// for debug:
#define UNICODE 1
#define _UNICODE 1
#define _WIN32_WINNT 0x0500 // win2000
#ifndef WINVER
#define WINVER _WIN32_WINNT
#endif
*/
#ifdef _WIN32
/*
this "Precomp.h" file must be included before <windows.h>,
if we want to define _WIN32_WINNT before <windows.h>.
*/
#ifndef Z7_LARGE_PAGES
#ifndef Z7_NO_LARGE_PAGES
#define Z7_LARGE_PAGES 1
#endif
#endif
#ifndef Z7_LONG_PATH
#ifndef Z7_NO_LONG_PATH
#define Z7_LONG_PATH 1
#endif
#endif
#ifndef Z7_DEVICE_FILE
#ifndef Z7_NO_DEVICE_FILE
// #define Z7_DEVICE_FILE 1
#endif
#endif
// we don't change macros if included after <windows.h>
#ifndef _WINDOWS_
#ifndef Z7_WIN32_WINNT_MIN
#if defined(_M_ARM64) || defined(__aarch64__)
// #define Z7_WIN32_WINNT_MIN 0x0a00 // win10
#define Z7_WIN32_WINNT_MIN 0x0600 // vista
#elif defined(_M_ARM) && defined(_M_ARMT) && defined(_M_ARM_NT)
// #define Z7_WIN32_WINNT_MIN 0x0602 // win8
#define Z7_WIN32_WINNT_MIN 0x0600 // vista
#elif defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) || defined(_M_IA64)
#define Z7_WIN32_WINNT_MIN 0x0503 // win2003
// #elif defined(_M_IX86) || defined(__i386__)
// #define Z7_WIN32_WINNT_MIN 0x0500 // win2000
#else // x86 and another(old) systems
#define Z7_WIN32_WINNT_MIN 0x0500 // win2000
// #define Z7_WIN32_WINNT_MIN 0x0502 // win2003 // for debug
#endif
#endif // Z7_WIN32_WINNT_MIN
#ifndef Z7_DO_NOT_DEFINE_WIN32_WINNT
#ifdef _WIN32_WINNT
// #error Stop_Compiling_Bad_WIN32_WINNT
#else
#ifndef Z7_NO_DEFINE_WIN32_WINNT
Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
#define _WIN32_WINNT Z7_WIN32_WINNT_MIN
Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
#endif
#endif // _WIN32_WINNT
#ifndef WINVER
#define WINVER _WIN32_WINNT
#endif
#endif // Z7_DO_NOT_DEFINE_WIN32_WINNT
#ifndef _MBCS
#ifndef Z7_NO_UNICODE
// UNICODE and _UNICODE are used by <windows.h> and by 7-zip code.
#ifndef UNICODE
#define UNICODE 1
#endif
#ifndef _UNICODE
Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
#define _UNICODE 1
Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
#endif
#endif // Z7_NO_UNICODE
#endif // _MBCS
#endif // _WINDOWS_
// #include "7zWindows.h"
#endif // _WIN32
#endif

View File

@@ -0,0 +1,50 @@
/* RotateDefs.h -- Rotate functions
2023-06-18 : Igor Pavlov : Public domain */
#ifndef ZIP7_INC_ROTATE_DEFS_H
#define ZIP7_INC_ROTATE_DEFS_H
#ifdef _MSC_VER
#include <stdlib.h>
/* don't use _rotl with old MINGW. It can insert slow call to function. */
/* #if (_MSC_VER >= 1200) */
#pragma intrinsic(_rotl)
#pragma intrinsic(_rotr)
/* #endif */
#define rotlFixed(x, n) _rotl((x), (n))
#define rotrFixed(x, n) _rotr((x), (n))
#if (_MSC_VER >= 1300)
#define Z7_ROTL64(x, n) _rotl64((x), (n))
#define Z7_ROTR64(x, n) _rotr64((x), (n))
#else
#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
#endif
#else
/* new compilers can translate these macros to fast commands. */
#if defined(__clang__) && (__clang_major__ >= 4) \
|| defined(__GNUC__) && (__GNUC__ >= 5)
/* GCC 4.9.0 and clang 3.5 can recognize more correct version: */
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (-(n) & 31)))
#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (-(n) & 31)))
#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (-(n) & 63)))
#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (-(n) & 63)))
#else
/* for old GCC / clang: */
#define rotlFixed(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
#define rotrFixed(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
#define Z7_ROTL64(x, n) (((x) << (n)) | ((x) >> (64 - (n))))
#define Z7_ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
#endif
#endif
#endif

View File

@@ -0,0 +1,86 @@
/* Sha1.h -- SHA-1 Hash
: Igor Pavlov : Public domain */
#ifndef ZIP7_INC_SHA1_H
#define ZIP7_INC_SHA1_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define SHA1_NUM_BLOCK_WORDS 16
#define SHA1_NUM_DIGEST_WORDS 5
#define SHA1_BLOCK_SIZE (SHA1_NUM_BLOCK_WORDS * 4)
#define SHA1_DIGEST_SIZE (SHA1_NUM_DIGEST_WORDS * 4)
typedef void (Z7_FASTCALL *SHA1_FUNC_UPDATE_BLOCKS)(UInt32 state[5], const Byte *data, size_t numBlocks);
/*
if (the system supports different SHA1 code implementations)
{
(CSha1::func_UpdateBlocks) will be used
(CSha1::func_UpdateBlocks) can be set by
Sha1_Init() - to default (fastest)
Sha1_SetFunction() - to any algo
}
else
{
(CSha1::func_UpdateBlocks) is ignored.
}
*/
typedef struct
{
union
{
struct
{
SHA1_FUNC_UPDATE_BLOCKS func_UpdateBlocks;
UInt64 count;
} vars;
UInt64 _pad_64bit[4];
void *_pad_align_ptr[2];
} v;
UInt32 state[SHA1_NUM_DIGEST_WORDS];
UInt32 _pad_3[3];
Byte buffer[SHA1_BLOCK_SIZE];
} CSha1;
#define SHA1_ALGO_DEFAULT 0
#define SHA1_ALGO_SW 1
#define SHA1_ALGO_HW 2
/*
Sha1_SetFunction()
return:
0 - (algo) value is not supported, and func_UpdateBlocks was not changed
1 - func_UpdateBlocks was set according (algo) value.
*/
BoolInt Sha1_SetFunction(CSha1 *p, unsigned algo);
void Sha1_InitState(CSha1 *p);
void Sha1_Init(CSha1 *p);
void Sha1_Update(CSha1 *p, const Byte *data, size_t size);
void Sha1_Final(CSha1 *p, Byte *digest);
void Sha1_PrepareBlock(const CSha1 *p, Byte *block, unsigned size);
void Sha1_GetBlockDigest(const CSha1 *p, const Byte *data, Byte *destDigest);
// void Z7_FASTCALL Sha1_UpdateBlocks(UInt32 state[5], const Byte *data, size_t numBlocks);
/*
call Sha1Prepare() once at program start.
It prepares all supported implementations, and detects the fastest implementation.
*/
void Sha1Prepare(void);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,86 @@
/* Sha256.h -- SHA-256 Hash
: Igor Pavlov : Public domain */
#ifndef ZIP7_INC_SHA256_H
#define ZIP7_INC_SHA256_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define SHA256_NUM_BLOCK_WORDS 16
#define SHA256_NUM_DIGEST_WORDS 8
#define SHA256_BLOCK_SIZE (SHA256_NUM_BLOCK_WORDS * 4)
#define SHA256_DIGEST_SIZE (SHA256_NUM_DIGEST_WORDS * 4)
typedef void (Z7_FASTCALL *SHA256_FUNC_UPDATE_BLOCKS)(UInt32 state[8], const Byte *data, size_t numBlocks);
/*
if (the system supports different SHA256 code implementations)
{
(CSha256::func_UpdateBlocks) will be used
(CSha256::func_UpdateBlocks) can be set by
Sha256_Init() - to default (fastest)
Sha256_SetFunction() - to any algo
}
else
{
(CSha256::func_UpdateBlocks) is ignored.
}
*/
typedef struct
{
union
{
struct
{
SHA256_FUNC_UPDATE_BLOCKS func_UpdateBlocks;
UInt64 count;
} vars;
UInt64 _pad_64bit[4];
void *_pad_align_ptr[2];
} v;
UInt32 state[SHA256_NUM_DIGEST_WORDS];
Byte buffer[SHA256_BLOCK_SIZE];
} CSha256;
#define SHA256_ALGO_DEFAULT 0
#define SHA256_ALGO_SW 1
#define SHA256_ALGO_HW 2
/*
Sha256_SetFunction()
return:
0 - (algo) value is not supported, and func_UpdateBlocks was not changed
1 - func_UpdateBlocks was set according (algo) value.
*/
BoolInt Sha256_SetFunction(CSha256 *p, unsigned algo);
void Sha256_InitState(CSha256 *p);
void Sha256_Init(CSha256 *p);
void Sha256_Update(CSha256 *p, const Byte *data, size_t size);
void Sha256_Final(CSha256 *p, Byte *digest);
// void Z7_FASTCALL Sha256_UpdateBlocks(UInt32 state[8], const Byte *data, size_t numBlocks);
/*
call Sha256Prepare() once at program start.
It prepares all supported implementations, and detects the fastest implementation.
*/
void Sha256Prepare(void);
EXTERN_C_END
#endif

View File

@@ -0,0 +1,36 @@
/* Sha3.h -- SHA-3 Hash
: Igor Pavlov : Public domain */
#ifndef ZIP7_INC_MD5_H
#define ZIP7_INC_MD5_H
#include "7zTypes.h"
EXTERN_C_BEGIN
#define SHA3_NUM_STATE_WORDS 25
#define SHA3_BLOCK_SIZE_FROM_DIGEST_SIZE(digestSize) \
(SHA3_NUM_STATE_WORDS * 8 - (digestSize) * 2)
typedef struct
{
UInt32 count; // < blockSize
UInt32 blockSize; // <= SHA3_NUM_STATE_WORDS * 8
UInt64 _pad1[3];
// we want 32-bytes alignment here
UInt64 state[SHA3_NUM_STATE_WORDS];
UInt64 _pad2[3];
// we want 64-bytes alignment here
Byte buffer[SHA3_NUM_STATE_WORDS * 8]; // last bytes will be unused with predefined blockSize values
} CSha3;
#define Sha3_SET_blockSize(p, blockSize) { (p)->blockSize = (blockSize); }
void Sha3_Init(CSha3 *p);
void Sha3_Update(CSha3 *p, const Byte *data, size_t size);
void Sha3_Final(CSha3 *p, Byte *digest, unsigned digestSize, unsigned shake);
EXTERN_C_END
#endif

Some files were not shown because too many files have changed in this diff Show More