提交 0d6a4c19 编写于 作者: V vit9696

Bootstrap: Initial commit

上级
.DS_Store
UDK
Binaries
build
DerivedData
xcshareddata
xcuserdata
project.xcworkspace
*.dSYM
DICT
fuzz-*.log
crash-*
oom-*
slow-unit-*
/** @file
Bootstrap OpenCore driver.
Copyright (c) 2018, vit9696. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Uefi.h>
#include <Protocol/DevicePath.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/OcBootstrap.h>
#include <Library/UefiLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/OcDevicePathLib.h>
#include <Library/OcFileLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/UefiApplicationEntryPoint.h>
STATIC
EFI_STATUS
LoadOpenCore (
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem,
IN EFI_HANDLE ParentImageHandle,
OUT EFI_HANDLE *ImageHandle
)
{
EFI_STATUS Status;
VOID *Buffer;
UINTN BufferSize;
ASSERT (FileSystem != NULL);
ASSERT (ParentImageHandle != NULL);
ASSERT (ImageHandle != NULL);
BufferSize = 0;
Buffer = ReadFile (FileSystem, L"EFI\\OC\\OpenCore.efi", &BufferSize);
if (Buffer == NULL) {
DEBUG ((DEBUG_ERROR, "BS: Failed to locate valid OpenCore image - %p!\n", Buffer));
return EFI_NOT_FOUND;
}
DEBUG ((DEBUG_INFO, "BS: Read OpenCore image of %Lu bytes\n", (UINT64) BufferSize));
//
// Run OpenCore image
//
*ImageHandle = NULL;
Status = gBS->LoadImage (
FALSE,
ParentImageHandle,
NULL,
Buffer,
BufferSize,
ImageHandle
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "BS: Failed to load OpenCore image - %r\n", Status));
FreePool (Buffer);
return Status;
}
DEBUG ((DEBUG_INFO, "BS: Loaded OpenCore image at %p handle\n", *ImageHandle));
Status = gBS->StartImage (
*ImageHandle,
NULL,
NULL
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "BS: Failed to start OpenCore image - %r\n", Status));
gBS->UnloadImage (*ImageHandle);
}
FreePool (Buffer);
return Status;
}
STATIC
VOID
StartOpenCore (
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem
)
{
EFI_STATUS Status;
OC_BOOTSTRAP_PROTOCOL *Bootstrap;
Bootstrap = NULL;
Status = gBS->LocateProtocol (
&gOcBootstrapProtocolGuid,
NULL,
(VOID **) &Bootstrap
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_WARN, "BS: Failed to locate bootstrap protocol - %r\n", Status));
return;
}
Bootstrap->ReRun (Bootstrap, FileSystem);
}
EFI_STATUS
EFIAPI
UefiMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
EFI_HANDLE OcImageHandle;
DEBUG ((DEBUG_INFO, "BS: Starting OpenCore...\n"));
//
// We have just started at EFI/BOOT/BOOTx64.efi.
// We need to run OpenCore on this partition as it failed automatically.
// The image is optionally located at EFI/OC/OpenCore.efi file.
//
LoadedImage = NULL;
Status = gBS->HandleProtocol (
ImageHandle,
&gEfiLoadedImageProtocolGuid,
(VOID **) &LoadedImage
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "BS: Failed to locate loaded image - %r\n", Status));
return EFI_NOT_FOUND;
}
DebugPrintDevicePath (DEBUG_INFO, "BS: Booter path", LoadedImage->FilePath);
//
// Obtain the file system device path
//
FileSystem = LocateFileSystem (
LoadedImage->DeviceHandle,
LoadedImage->FilePath
);
if (FileSystem == NULL) {
DEBUG ((DEBUG_ERROR, "BS: Failed to obtain own file system\n"));
return EFI_NOT_FOUND;
}
//
// Try to start previously loaded OpenCore
//
DEBUG ((DEBUG_INFO, "BS: Trying to start loaded OpenCore image...\n"));
StartOpenCore (FileSystem);
DEBUG ((DEBUG_INFO, "BS: Trying to load OpenCore image...\n"));
Status = LoadOpenCore (FileSystem, ImageHandle, &OcImageHandle);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "BS: Failed to load OpenCore from disk - %r\n", Status));
return EFI_NOT_FOUND;
}
StartOpenCore (FileSystem);
DEBUG ((DEBUG_ERROR, "BS: Failed to start OpenCore image...\n"));
return EFI_NOT_FOUND;
}
## @file
# OpenCore bootstrap image.
#
# Copyright (c) 2018, vit9696. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = BOOTx64
FILE_GUID = 1E55CC26-6036-43AB-867C-213FFB426812
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 1.0
ENTRY_POINT = UefiMain
#
# This flag specifies whether HII resource section is generated into PE image.
#
UEFI_HII_RESOURCE_SECTION = TRUE
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
Bootstrap.c
[Packages]
OpenCorePkg/OpenCorePkg.dec
OcSupportPkg/OcSupportPkg.dec
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[Protocols]
gEfiDevicePathProtocolGuid ## CONSUMES
gEfiLoadedImageProtocolGuid ## CONSUMES
gEfiSimpleFileSystemProtocolGuid ## CONSUMES
gOcBootstrapProtocolGuid ## CONSUMES
[LibraryClasses]
UefiApplicationEntryPoint
UefiLib
PrintLib
DebugLib
DevicePathLib
MemoryAllocationLib
OcDevicePathLib
OcFileLib
/** @file
Copyright (C) 2018, vit9696. All rights reserved.
All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef OC_BOOTSTRAP_PROTOCOL_H
#define OC_BOOTSTRAP_PROTOCOL_H
#include <Protocol/SimpleFileSystem.h>
///
/// BA1EB455-B182-4F14-8521-E422C325DEF6
///
#define OC_BOOTSTRAP_PROTOCOL_GUID \
{ \
0xBA1EB455, 0xB182, 0x4F14, { 0x85, 0x21, 0xE4, 0x22, 0xC3, 0x25, 0xDE, 0xF6 } \
}
///
/// Forward declaration of OC_BOOTSTRAP_PROTOCOL structure.
///
typedef struct OC_BOOTSTRAP_PROTOCOL_ OC_BOOTSTRAP_PROTOCOL;
/**
Restart OpenCore at specified file system, does not return.
@param[in] This This protocol.
@param[in] FileSystem File system to bootstrap in.
**/
typedef
VOID
(EFIAPI *OC_BOOTSTRAP_RERUN) (
IN OC_BOOTSTRAP_PROTOCOL *This,
IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem
);
///
/// The structure exposed by the OC_BOOTSTRAP_PROTOCOL.
///
struct OC_BOOTSTRAP_PROTOCOL_ {
UINTN Revision;
OC_BOOTSTRAP_RERUN ReRun;
};
extern EFI_GUID gOcBootstrapProtocolGuid;
#endif // OC_BOOTSTRAP_PROTOCOL_H
Copyright (c) 2016-2017, The HermitCrabs Lab
Copyright (c) 2016-2019, Download-Fritz
Copyright (c) 2017-2019, savvas
Copyright (c) 2016-2019, vit9696
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
## @file
# Copyright (C) 2018, vit9696. All rights reserved.<BR>
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##
[Defines]
PACKAGE_NAME = OpenCorePkg
PACKAGE_GUID = 6B1D3AB4-5C85-462D-9DC5-480F8B17D5CB
PACKAGE_VERSION = 1.0
DEC_SPECIFICATION = 0x00010005
[Includes]
Include
[Protocols]
gOcBootstrapProtocolGuid = { 0xBA1EB455, 0xB182, 0x4F14, { 0x85, 0x21, 0xE4, 0x22, 0xC3, 0x25, 0xDE, 0xF6 }}
## @file
# Copyright (C) 2018, vit9696. All rights reserved.<BR>
# Copyright (C) 2018, Download-Fritz. All rights reserved.<BR>
#
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
##
[Defines]
PLATFORM_NAME = OpenCorePkg
PLATFORM_GUID = 6B1D3AB4-5C85-462D-9DC5-480F8B17D5CB
PLATFORM_VERSION = 1.0
SUPPORTED_ARCHITECTURES = X64
BUILD_TARGETS = RELEASE|DEBUG|NOOPT
SKUID_IDENTIFIER = DEFAULT
DSC_SPECIFICATION = 0x00010006
[LibraryClasses]
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseRngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
DebugLib|OcSupportPkg/Library/OcDebugLogLib/OcDebugLogLib.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
OcAcpiLib|OcSupportPkg/Library/OcAcpiLib/OcAcpiLib.inf
OcAppleBootPolicyLib|OcSupportPkg/Library/OcAppleBootPolicyLib/OcAppleBootPolicyLib.inf
OcAppleChunklistLib|OcSupportPkg/Library/OcAppleChunklistLib/OcAppleChunklistLib.inf
OcAppleDiskImageLib|OcSupportPkg/Library/OcAppleDiskImageLib/OcAppleDiskImageLib.inf
OcAppleImageVerificationLib|OcSupportPkg/Library/OcAppleImageVerificationLib/OcAppleImageVerificationLib.inf
OcAppleKernelLib|OcSupportPkg/Library/OcAppleKernelLib/OcAppleKernelLib.inf
OcBootManagementLib|OcSupportPkg/Library/OcBootManagementLib/OcBootManagementLib.inf
OcCpuLib|OcSupportPkg/Library/OcCpuLib/OcCpuLib.inf
OcCryptoLib|OcSupportPkg/Library/OcCryptoLib/OcCryptoLib.inf
OcCompressionLib|OcSupportPkg/Library/OcCompressionLib/OcCompressionLib.inf
OcDataHubLib|OcSupportPkg/Library/OcDataHubLib/OcDataHubLib.inf
OcDebugLogLib|OcSupportPkg/Library/OcDebugLogLib/OcDebugLogLib.inf
OcDevicePathLib|OcSupportPkg/Library/OcDevicePathLib/OcDevicePathLib.inf
OcDevicePropertyLib|OcSupportPkg/Library/OcDevicePropertyLib/OcDevicePropertyLib.inf
OcFileLib|OcSupportPkg/Library/OcFileLib/OcFileLib.inf
OcFirmwarePasswordLib|OcSupportPkg/Library/OcFirmwarePasswordLib/OcFirmwarePasswordLib.inf
OcGuardLib|OcSupportPkg/Library/OcGuardLib/OcGuardLib.inf
OcMachoLib|OcSupportPkg/Library/OcMachoLib/OcMachoLib.inf
OcMiscLib|OcSupportPkg/Library/OcMiscLib/OcMiscLib.inf
OcPngLib|OcSupportPkg/Library/OcPngLib/OcPngLib.inf
OcProtocolLib|OcSupportPkg/Library/OcProtocolLib/OcProtocolLib.inf
OcSerializeLib|OcSupportPkg/Library/OcSerializeLib/OcSerializeLib.inf
OcSmbiosLib|OcSupportPkg/Library/OcSmbiosLib/OcSmbiosLib.inf
OcStringLib|OcSupportPkg/Library/OcStringLib/OcStringLib.inf
OcTemplateLib|OcSupportPkg/Library/OcTemplateLib/OcTemplateLib.inf
OcTimerLib|OcSupportPkg/Library/OcTimerLib/OcTimerLib.inf
OcVirtualFsLib|OcSupportPkg/Library/OcVirtualFsLib/OcVirtualFsLib.inf
OcXmlLib|OcSupportPkg/Library/OcXmlLib/OcXmlLib.inf
[Components]
OpenCorePkg/Application/Bootstrap/Bootstrap.inf
[PcdsFixedAtBuild]
gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|0
!if $(TARGET) == RELEASE
# DEBUG_PRINT_ENABLED
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|2
# DEBUG_ERROR | DEBUG_WARN
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000002
gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel|0x80000002
!else
# DEBUG_ASSERT_ENABLED | DEBUG_PRINT_ENABLED | DEBUG_CODE_ENABLED | CLEAR_MEMORY_ENABLED | ASSERT_DEADLOOP_ENABLED
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
# DEBUG_ERROR | DEBUG_WARN | DEBUG_INFO
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000042
gEfiMdePkgTokenSpaceGuid.PcdFixedDebugPrintErrorLevel|0x80000042
!endif
[BuildOptions]
# While there are no PCDs as of now, there at least are some custom macros.
DEFINE OCPKG_BUILD_OPTIONS_GEN = -D DISABLE_NEW_DEPRECATED_INTERFACES $(OCPKG_BUILD_OPTIONS)
GCC:DEBUG_*_*_CC_FLAGS = $(OCPKG_BUILD_OPTIONS_GEN)
GCC:NOOPT_*_*_CC_FLAGS = $(OCPKG_BUILD_OPTIONS_GEN)
GCC:RELEASE_*_*_CC_FLAGS = $(OCPKG_BUILD_OPTIONS_GEN)
MSFT:DEBUG_*_*_CC_FLAGS = $(OCPKG_BUILD_OPTIONS_GEN)
MSFT:NOOPT_*_*_CC_FLAGS = $(OCPKG_BUILD_OPTIONS_GEN)
MSFT:RELEASE_*_*_CC_FLAGS = $(OCPKG_BUILD_OPTIONS_GEN)
XCODE:DEBUG_*_*_CC_FLAGS = $(OCPKG_BUILD_OPTIONS_GEN)
XCODE:NOOPT_*_*_CC_FLAGS = $(OCPKG_BUILD_OPTIONS_GEN)
XCODE:RELEASE_*_*_CC_FLAGS = -Wno-error -flto $(OCPKG_BUILD_OPTIONS_GEN)
OpenCorePkg
===========
OpenCore bootloader front end.
## Credits
- The HermitCrabs Lab
- All projects providing third-party code (refer to file headers)
- [Download-Fritz](https://github.com/Download-Fritz)
- [savvamitrofanov](https://github.com/savvamitrofanov)
- [vit9696](https://github.com/vit9696)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册