├── P2KConsole ├── Version.h ├── include │ ├── PantherVersion.h │ ├── PantherConsole.h │ ├── P2KWin32Console.h │ ├── PantherLogger.h │ ├── P2KBaseConsole.h │ └── P2KCustomConsole.h ├── Logger.cpp ├── framework.h ├── pch.cpp ├── pch.h ├── Win32Console.h ├── Logger.h ├── Console.h ├── CustomConsole.h ├── P2KConsole.vcxproj.filters ├── Win32Console.cpp └── P2KConsole.vcxproj ├── Panther2K ├── Panther2K.h ├── small.ico ├── Panther2K.rc ├── Panther2K.ico ├── QuitingPage.cpp ├── WelcomePage.cpp ├── Bm437_IBM_VGA_8x16.FON ├── BootMethodSelectionPage.cpp ├── QuitingPage.h ├── FinalPage.h ├── WelcomePage.h ├── targetver.h ├── BootPreparationPage.h ├── BootMethodSelectionPage.h ├── framework.h ├── ImageSelectionPage.h ├── MessageBoxPage.h ├── WimApplyPage.h ├── PopupPage.h ├── DiskSelectionPage.h ├── WinPartedDll.h ├── Panther2K.cpp ├── Page.h ├── PartitionSelectionPage.h ├── resource.h ├── FinalPage.cpp ├── wdkpartial.h ├── MessageBoxPage.cpp ├── PopupPage.cpp ├── iatpatch.h ├── WindowsSetup.h ├── WinPartedDll.cpp ├── ImageSelectionPage.cpp ├── Page.cpp ├── Panther2K.vcxproj.filters ├── PartitionSelectionPage.cpp ├── DiskSelectionPage.cpp └── WimApplyPage.cpp ├── .gitmodules ├── Wimgapi └── Lib │ └── amd64 │ └── wimgapi.lib ├── WinParted ├── Bm437_IBM_VGA_8x16.FON ├── DllExports.def ├── Partition │ ├── PartitionInformationPage.h │ ├── PartitionGuidSelectionPage.h │ ├── PartitionFormatPage.h │ ├── PartitionTypeSelectionPage.h │ ├── PartitionCreationPage.h │ ├── PartitionTable.h │ ├── PartitionGuidSelectionPage.cpp │ ├── PartitionInformationPage.cpp │ ├── PartitionFormatPage.cpp │ └── PartitionTypeSelectionPage.cpp ├── DiskPartitioningPage.h ├── DiskSelectionPage.h ├── resource.h ├── Page.h ├── WinParted.rc ├── MessagePage.h ├── Page.cpp ├── WinParted.vcxproj.filters ├── DiskSelectionPage.cpp ├── CoreFunctions │ ├── PartitionManager.h │ └── DllExports.cpp ├── MessagePage.cpp ├── WinParted.cpp └── DiskPartitioningPage.cpp ├── Create empty BCD and load as hive.txt ├── README.md ├── .gitattributes ├── Panther2K.sln └── .gitignore /P2KConsole/Version.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define PANTHER_VERSION "1.3.1" -------------------------------------------------------------------------------- /Panther2K/Panther2K.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "resource.h" 4 | -------------------------------------------------------------------------------- /P2KConsole/include/PantherVersion.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define PANTHER_VERSION "1.3.1" -------------------------------------------------------------------------------- /Panther2K/small.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leetftw/Panther2K/HEAD/Panther2K/small.ico -------------------------------------------------------------------------------- /P2KConsole/Logger.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leetftw/Panther2K/HEAD/P2KConsole/Logger.cpp -------------------------------------------------------------------------------- /Panther2K/Panther2K.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leetftw/Panther2K/HEAD/Panther2K/Panther2K.rc -------------------------------------------------------------------------------- /Panther2K/Panther2K.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leetftw/Panther2K/HEAD/Panther2K/Panther2K.ico -------------------------------------------------------------------------------- /Panther2K/QuitingPage.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leetftw/Panther2K/HEAD/Panther2K/QuitingPage.cpp -------------------------------------------------------------------------------- /Panther2K/WelcomePage.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leetftw/Panther2K/HEAD/Panther2K/WelcomePage.cpp -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "RapidXML"] 2 | path = RapidXML 3 | url = https://github.com/Fe-Bell/RapidXML.git 4 | -------------------------------------------------------------------------------- /Wimgapi/Lib/amd64/wimgapi.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leetftw/Panther2K/HEAD/Wimgapi/Lib/amd64/wimgapi.lib -------------------------------------------------------------------------------- /Panther2K/Bm437_IBM_VGA_8x16.FON: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leetftw/Panther2K/HEAD/Panther2K/Bm437_IBM_VGA_8x16.FON -------------------------------------------------------------------------------- /WinParted/Bm437_IBM_VGA_8x16.FON: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leetftw/Panther2K/HEAD/WinParted/Bm437_IBM_VGA_8x16.FON -------------------------------------------------------------------------------- /Panther2K/BootMethodSelectionPage.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leetftw/Panther2K/HEAD/Panther2K/BootMethodSelectionPage.cpp -------------------------------------------------------------------------------- /P2KConsole/framework.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 4 | -------------------------------------------------------------------------------- /P2KConsole/include/PantherConsole.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PantherVersion.h" 4 | #include "P2KBaseConsole.h" 5 | #include "P2KCustomConsole.h" 6 | #include "P2KWin32Console.h" 7 | -------------------------------------------------------------------------------- /WinParted/DllExports.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | InitializeCRT @1 3 | RunWinParted @2 4 | ApplyP2KLayoutToDiskGPT @3 5 | ApplyP2KLayoutToDiskMBR @4 6 | SetPartType @5 7 | MountPartition @6 -------------------------------------------------------------------------------- /P2KConsole/pch.cpp: -------------------------------------------------------------------------------- 1 | // pch.cpp: source file corresponding to the pre-compiled header 2 | 3 | #include "pch.h" 4 | 5 | // When you are using pre-compiled headers, this source file is necessary for compilation to succeed. 6 | -------------------------------------------------------------------------------- /WinParted/Partition/PartitionInformationPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "..\Page.h" 3 | 4 | class PartitionInformationPage : public Page 5 | { 6 | protected: 7 | void InitPage(); 8 | void DrawPage(); 9 | void UpdatePage(); 10 | void RunPage(); 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /Panther2K/QuitingPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PopupPage.h" 4 | 5 | class QuitingPage : public PopupPage 6 | { 7 | private: 8 | virtual void Init() override; 9 | virtual void Drawer() override; 10 | virtual bool KeyHandler(WPARAM wParam) override; 11 | }; 12 | 13 | -------------------------------------------------------------------------------- /Panther2K/FinalPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Page.h" 3 | class FinalPage : public Page 4 | { 5 | protected: 6 | virtual void Init() override; 7 | virtual void Drawer() override; 8 | virtual void Redrawer() override; 9 | virtual bool KeyHandler(WPARAM wParam) override; 10 | }; 11 | 12 | -------------------------------------------------------------------------------- /Panther2K/WelcomePage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Page.h" 4 | 5 | class WelcomePage : public Page 6 | { 7 | private: 8 | virtual void Init() override; 9 | virtual void Drawer() override; 10 | virtual void Redrawer() override; 11 | virtual bool KeyHandler(WPARAM wParam) override; 12 | }; 13 | 14 | -------------------------------------------------------------------------------- /WinParted/DiskPartitioningPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Page.h" 3 | 4 | class DiskPartitioningPage : public Page 5 | { 6 | protected: 7 | void InitPage(); 8 | void DrawPage(); 9 | void UpdatePage(); 10 | void RunPage(); 11 | private: 12 | int scrollIndex; 13 | int selectionIndex; 14 | int maxItems; 15 | }; 16 | 17 | -------------------------------------------------------------------------------- /Panther2K/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // // Including SDKDDKVer.h defines the highest available Windows platform. 4 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 5 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 6 | #include 7 | -------------------------------------------------------------------------------- /WinParted/DiskSelectionPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Page.h" 3 | 4 | class DiskSelectionPage : public Page 5 | { 6 | protected: 7 | void InitPage(); 8 | void DrawPage(); 9 | void UpdatePage(); 10 | void RunPage(); 11 | private: 12 | int scrollIndex; 13 | int selectionIndex; 14 | int maxItems; 15 | int boxY; 16 | }; 17 | 18 | -------------------------------------------------------------------------------- /WinParted/Partition/PartitionGuidSelectionPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "..\Page.h" 3 | class PartitionGuidSelectionPage : public Page 4 | { 5 | protected: 6 | void InitPage(); 7 | void DrawPage(); 8 | void UpdatePage(); 9 | void RunPage(); 10 | private: 11 | wchar_t enteredChars[37]; 12 | POINT textLocation; 13 | int inputIndex; 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /Panther2K/BootPreparationPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Page.h" 3 | class BootPreparationPage : public Page 4 | { 5 | public: 6 | ~BootPreparationPage(); 7 | void PrepareBootFiles(); 8 | void PrepareBootFilesNew(); 9 | protected: 10 | virtual void Init() override; 11 | virtual void Drawer() override; 12 | virtual void Redrawer() override; 13 | virtual bool KeyHandler(WPARAM wParam) override; 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /Panther2K/BootMethodSelectionPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Page.h" 4 | 5 | class BootMethodSelectionPage : public Page 6 | { 7 | public: 8 | ~BootMethodSelectionPage(); 9 | private: 10 | bool legacy = false; 11 | int y = 0; 12 | protected: 13 | virtual void Init() override; 14 | virtual void Drawer() override; 15 | virtual void Redrawer() override; 16 | virtual bool KeyHandler(WPARAM wParam) override; 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /Panther2K/framework.h: -------------------------------------------------------------------------------- 1 | // header.h : include file for standard system include files, 2 | // or project specific include files 3 | // 4 | 5 | #pragma once 6 | 7 | #include "targetver.h" 8 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 9 | // Windows Header Files 10 | #include 11 | // C RunTime Header Files 12 | #include 13 | #include 14 | #include 15 | #include 16 | -------------------------------------------------------------------------------- /Panther2K/ImageSelectionPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Page.h" 3 | #include 4 | #include 5 | 6 | class ImageSelectionPage : public Page 7 | { 8 | private: 9 | ::std::vector<::std::array> FormattedStrings; 10 | int scrollIndex; 11 | int selectionIndex; 12 | int boxY; 13 | 14 | virtual void Init() override; 15 | virtual void Drawer() override; 16 | virtual void Redrawer() override; 17 | virtual bool KeyHandler(WPARAM wParam) override; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /Panther2K/MessageBoxPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "PopupPage.h" 3 | class MessageBoxPage : public PopupPage 4 | { 5 | public: 6 | MessageBoxPage(const wchar_t* text, bool isError, Page* par); 7 | void ShowDialog(); 8 | private: 9 | const wchar_t* fullText; 10 | int lineCount; 11 | wchar_t** lines; 12 | bool error; 13 | bool shown; 14 | 15 | virtual void Init() override; 16 | virtual void Drawer() override; 17 | virtual bool KeyHandler(WPARAM wParam) override; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /Panther2K/WimApplyPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Page.h" 3 | class WimApplyPage : public Page 4 | { 5 | public: 6 | ~WimApplyPage(); 7 | int progress = 0; 8 | const wchar_t* filename = 0; 9 | void WimMessageLoop(); 10 | void Update(int prog); 11 | void Update(wchar_t* filename); 12 | void ApplyImage(); 13 | protected: 14 | virtual void Init() override; 15 | virtual void Drawer() override; 16 | virtual void Redrawer() override; 17 | virtual bool KeyHandler(WPARAM wParam) override; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /WinParted/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by WinParted.rc 4 | #define IDR_FONT_IBM 3 5 | 6 | // Next default values for new objects 7 | // 8 | #ifdef APSTUDIO_INVOKED 9 | #ifndef APSTUDIO_READONLY_SYMBOLS 10 | #define _APS_NEXT_RESOURCE_VALUE 101 11 | #define _APS_NEXT_COMMAND_VALUE 40001 12 | #define _APS_NEXT_CONTROL_VALUE 1001 13 | #define _APS_NEXT_SYMED_VALUE 101 14 | #endif 15 | #endif 16 | -------------------------------------------------------------------------------- /Panther2K/PopupPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class Page; 6 | 7 | class PopupPage 8 | { 9 | public: 10 | void Initialize(Console* con, Page* par); 11 | void Draw(); 12 | bool HandleKey(WPARAM wParam); 13 | Page* parent; 14 | private: 15 | virtual void Init(); 16 | virtual void Drawer(); 17 | virtual bool KeyHandler(WPARAM wParam); 18 | protected: 19 | bool customColor = false; 20 | int fore, back; 21 | int width, height; 22 | const wchar_t* statusText; 23 | Console* console; 24 | }; 25 | 26 | #include "Page.h" 27 | 28 | -------------------------------------------------------------------------------- /WinParted/Partition/PartitionFormatPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "..\Page.h" 3 | 4 | class PartitionFormatPage : public Page 5 | { 6 | public: 7 | void InitPage(); 8 | void DrawPage(); 9 | void UpdatePage(); 10 | void RunPage(); 11 | private: 12 | int selectionIndex = 0; 13 | int scrollIndex = 0; 14 | int maxItems; 15 | 16 | bool enteringName = false; 17 | wchar_t nameString[64]; 18 | 19 | wchar_t* supportedFileSystems[5]; /* at most 5 filesystems for now */ 20 | int supportedFsCount = 0; 21 | int biggestFsName = 0; 22 | int drawY = 0; 23 | }; 24 | 25 | -------------------------------------------------------------------------------- /P2KConsole/pch.h: -------------------------------------------------------------------------------- 1 | // pch.h: This is a precompiled header file. 2 | // Files listed below are compiled only once, improving build performance for future builds. 3 | // This also affects IntelliSense performance, including code completion and many code browsing features. 4 | // However, files listed here are ALL re-compiled if any one of them is updated between builds. 5 | // Do not add files here that you will be updating frequently as this negates the performance advantage. 6 | 7 | #ifndef PCH_H 8 | #define PCH_H 9 | 10 | // add headers that you want to pre-compile here 11 | #include "framework.h" 12 | 13 | #endif //PCH_H 14 | -------------------------------------------------------------------------------- /Panther2K/DiskSelectionPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Page.h" 3 | 4 | typedef struct DISK_INFO 5 | { 6 | int diskNumber; 7 | wchar_t name[MAX_PATH]; 8 | MEDIA_TYPE mediaType; 9 | unsigned long long size; 10 | } *PDISK_INFO; 11 | 12 | class DiskSelectionPage : 13 | public Page 14 | { 15 | protected: 16 | virtual void Init() override; 17 | virtual void Drawer() override; 18 | virtual void Redrawer() override; 19 | virtual bool KeyHandler(WPARAM wParam) override; 20 | private: 21 | int boxY = 0; 22 | int selectionIndex = 0; 23 | int scrollIndex = 0; 24 | int diskCount = 0; 25 | DISK_INFO* diskInfo = 0; 26 | 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /WinParted/Partition/PartitionTypeSelectionPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "..\Page.h" 3 | #include "..\CoreFunctions\PartitionManager.h" 4 | 5 | class PartitionTypeSelectionPage : public Page 6 | { 7 | protected: 8 | void InitPage(); 9 | void DrawPage(); 10 | void UpdatePage(); 11 | void RunPage(); 12 | private: 13 | void LoadItems(bool showAll); 14 | int scrollIndex; 15 | int selectionIndex; 16 | int maxItems; 17 | int totalItems; 18 | int boxY; 19 | PartitionType items[PartitionTypeCount]; 20 | wchar_t enteredChars[5]; 21 | POINT textLocation; 22 | int inputIndex; 23 | bool inputSelected; 24 | bool allItemsShown; 25 | }; 26 | 27 | -------------------------------------------------------------------------------- /P2KConsole/Win32Console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Console.h" 3 | 4 | class Win32Console : public Console 5 | { 6 | public: 7 | bool Init(); 8 | void Init(bool createNewConsole); 9 | 10 | void SetPosition(long x, long y); 11 | POINT GetPosition(); 12 | void SetSize(long columns, long rows); 13 | SIZE GetSize(); 14 | 15 | void SetCursor(bool enabled, bool blinking); 16 | 17 | void Write(const wchar_t* string); 18 | void WriteLine(const wchar_t* string); 19 | KEY_EVENT_RECORD* Read(int count = 1); 20 | KEY_EVENT_RECORD* ReadLine(); 21 | void Update(); 22 | void Clear(); 23 | protected: 24 | void UpdateColorTable(); 25 | private: 26 | HANDLE hScreenBuffer; 27 | HANDLE hInputBuffer; 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /P2KConsole/include/P2KWin32Console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "P2KBaseConsole.h" 3 | 4 | class Win32Console : public Console 5 | { 6 | public: 7 | bool Init(); 8 | void Init(bool createNewConsole); 9 | 10 | void SetPosition(long x, long y); 11 | POINT GetPosition(); 12 | void SetSize(long columns, long rows); 13 | SIZE GetSize(); 14 | 15 | void SetCursor(bool enabled, bool blinking); 16 | 17 | void Write(const wchar_t* string); 18 | void WriteLine(const wchar_t* string); 19 | KEY_EVENT_RECORD* Read(int count = 1); 20 | KEY_EVENT_RECORD* ReadLine(); 21 | void Update(); 22 | void Clear(); 23 | protected: 24 | void UpdateColorTable(); 25 | private: 26 | HANDLE hScreenBuffer; 27 | HANDLE hInputBuffer; 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /WinParted/Page.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class Page 5 | { 6 | public: 7 | Page(); 8 | void Initialize(Console* con); 9 | void Draw(); 10 | void Update(); 11 | void Run(); 12 | void SetStatusText(const wchar_t* txt); 13 | private: 14 | const wchar_t* text; 15 | const wchar_t* statusText; 16 | Console* console; 17 | bool drawHeader; 18 | bool drawStatus; 19 | bool drawClear; 20 | 21 | friend class PartitionManager; 22 | protected: 23 | void SetDecorations(bool header, bool status, bool clear); 24 | void SetText(const wchar_t* txt); 25 | virtual void InitPage(); 26 | virtual void DrawPage(); 27 | virtual void UpdatePage(); 28 | virtual void RunPage(); 29 | Console* GetConsole(); 30 | }; 31 | 32 | -------------------------------------------------------------------------------- /Panther2K/WinPartedDll.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class WinPartedDll 6 | { 7 | public: 8 | static int RunWinParted(Console*, LibPanther::Logger*); 9 | static HRESULT ApplyP2KLayoutToDiskGPT(Console*, LibPanther::Logger*, int, bool, wchar_t***, wchar_t***); 10 | static HRESULT ApplyP2KLayoutToDiskMBR(Console*, LibPanther::Logger*, int, bool, wchar_t***, wchar_t***); 11 | static HRESULT SetPartType(Console*, LibPanther::Logger*, int, unsigned long long, short); 12 | static HRESULT MountPartition(Console*, LibPanther::Logger*, int, unsigned long long, const wchar_t*); 13 | private: 14 | static HMODULE hWinParted; 15 | static HRESULT InitParted(); 16 | static bool partedInitialized; 17 | }; -------------------------------------------------------------------------------- /Create empty BCD and load as hive.txt: -------------------------------------------------------------------------------- 1 | Create empty BCD and load as hive 2 | Load template BCD as hive as well 3 | 4 | Copy {dbgsettings} to new BCD 5 | Copy {emssettings} to new BCD 6 | Copy {badmemory} to new BCD 7 | Copy {globalsettings} to new BCD 8 | Copy {resumeloadersettings} to new BCD 9 | Copy {hypervisorsettings} to new BCD 10 | Copy {bootloadersettings} to new BCD 11 | 12 | Copy OS loader template and Bootmgr template and resume loader template without disrupting GUID structure, also add appropriate information 13 | 14 | 15 | Template GUIDs: 16 | OS Loader UEFI: {b012b84d-c47c-4ed5-b722-c0c42163e569} (GUID_WINDOWS_OS_TARGET_TEMPLATE_EFI) 17 | OS Loader PCAT: {a1943bbc-ea85-487c-97c7-c9ede908a38a} (GUID_WINDOWS_OS_TARGET_TEMPLATE_PCAT) 18 | Global settings: {7ea2e1ac-2e61-4728-aaa3-896d9d0a9f0e} -------------------------------------------------------------------------------- /Panther2K/Panther2K.cpp: -------------------------------------------------------------------------------- 1 | // Panther2K.cpp : Defines the entry point for the application. 2 | // 3 | 4 | #include "framework.h" 5 | #include "Panther2K.h" 6 | #include "WindowsSetup.h" 7 | 8 | // Command line builds (for testing and debugging) 9 | int wmain(int argc, wchar_t** argv) 10 | { 11 | if (__argc == 2 && lstrcmpiW(__wargv[1], L"--pe") == 0) 12 | { 13 | WindowsSetup::IsWinPE = true; 14 | } 15 | 16 | return WindowsSetup::RunSetup(); 17 | } 18 | 19 | // Headless builds (for releases) 20 | int APIENTRY wWinMain(_In_ HINSTANCE hInstance, 21 | _In_opt_ HINSTANCE hPrevInstance, 22 | _In_ LPWSTR lpCmdLine, 23 | _In_ int nCmdShow) 24 | { 25 | UNREFERENCED_PARAMETER(hPrevInstance); 26 | UNREFERENCED_PARAMETER(lpCmdLine); 27 | 28 | return wmain(0, nullptr); 29 | } 30 | -------------------------------------------------------------------------------- /Panther2K/Page.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "PopupPage.h" 5 | 6 | class Page 7 | { 8 | public: 9 | Page(); 10 | void Initialize(Console* con); 11 | void Draw(); 12 | void Redraw(bool redraw = true); 13 | bool HandleKey(WPARAM wParam); 14 | void AddPopup(PopupPage* popup); 15 | void RemovePopup(); 16 | 17 | void DrawBox(int x, int y, int cx, int cy, bool useDouble); 18 | void DrawTextLeft(const wchar_t* string, int cx, int y); 19 | void DrawTextRight(const wchar_t* string, int cx, int y); 20 | void DrawTextCenter(const wchar_t* string, int cx, int y); 21 | 22 | const wchar_t* text; 23 | const wchar_t* statusText; 24 | Console* console; 25 | private: 26 | virtual void Init(); 27 | virtual void Drawer(); 28 | virtual void Redrawer(); 29 | virtual bool KeyHandler(WPARAM wParam); 30 | protected: 31 | PopupPage* page; 32 | }; 33 | 34 | -------------------------------------------------------------------------------- /WinParted/Partition/PartitionCreationPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "..\Page.h" 3 | #include "PartitionTable.h" 4 | 5 | typedef struct SectorSpan { 6 | unsigned long long startSector; 7 | unsigned long long endSector; 8 | int partitionA; 9 | int partitionB; 10 | 11 | unsigned long long GetSize() { 12 | return endSector - startSector + 1; 13 | }; 14 | } *PSectorSpan; 15 | 16 | class PartitionCreationPage : public Page 17 | { 18 | public: 19 | void InitPage(); 20 | void DrawPage(); 21 | void UpdatePage(); 22 | void RunPage(); 23 | private: 24 | // Location 25 | SectorSpan* unallocatedSpans; 26 | int unallocatedSpanCount; 27 | int selectionIndex = 0; 28 | int scrollIndex = 0; 29 | int maxItems; 30 | 31 | // Size 32 | void ParseSize(); 33 | bool enteringSize = false; 34 | wchar_t sizeString[20]; 35 | unsigned long long size; 36 | 37 | int drawY = 0; 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /Panther2K/PartitionSelectionPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Page.h" 3 | #include 4 | 5 | typedef struct VOLUME_INFO; 6 | 7 | class PartitionSelectionPage : public Page 8 | { 9 | public: 10 | PartitionSelectionPage(const wchar_t* fileSystem, long long minimumSize, long long minimumBytesAvailable, int stringIndex, int displayIndex); 11 | void EnumeratePartitions(); 12 | VOLUME_INFO GetSelectedVolume(); 13 | protected: 14 | virtual void Init() override; 15 | virtual void Drawer() override; 16 | virtual void Redrawer() override; 17 | virtual bool KeyHandler(WPARAM wParam) override; 18 | private: 19 | int boxY = 0; 20 | int selectionIndex = 0; 21 | int scrollIndex = 0; 22 | std::vector volumeInfo; 23 | int stringTableIndex; 24 | int dispIndex; 25 | bool showAll = false; 26 | struct 27 | { 28 | int partitionSize; 29 | int partitionFree; 30 | const wchar_t* fileSystem; 31 | } requirements; 32 | }; 33 | 34 | -------------------------------------------------------------------------------- /Panther2K/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Panther2K.rc 4 | // 5 | #define IDC_MYICON 2 6 | #define IDR_FONT_IBM 3 7 | #define IDD_PANTHER2K_DIALOG 102 8 | #define IDS_APP_TITLE 103 9 | #define IDM_ABOUT 104 10 | #define IDM_EXIT 105 11 | #define IDI_PANTHER2K 107 12 | #define IDI_SMALL 108 13 | #define IDC_PANTHER2K 109 14 | #define IDR_MAINFRAME 128 15 | #define IDC_STATIC -1 16 | 17 | // Next default values for new objects 18 | // 19 | #ifdef APSTUDIO_INVOKED 20 | #ifndef APSTUDIO_READONLY_SYMBOLS 21 | #define _APS_NO_MFC 1 22 | #define _APS_NEXT_RESOURCE_VALUE 130 23 | #define _APS_NEXT_COMMAND_VALUE 32771 24 | #define _APS_NEXT_CONTROL_VALUE 1000 25 | #define _APS_NEXT_SYMED_VALUE 110 26 | #endif 27 | #endif 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![p2knotext.svg](p2knotext.svg) 2 | --- 3 | 4 | An advanced installer for Microsoft Windows that mimics the looks of the Windows XP and older installers. Takes any modern (Vista and newer) Windows ISO or WIM file and creates a old styled Windows Setup experience on the go. 5 | 6 | # Building 7 | 8 | To build Panther2K you'll need the following: 9 | - Visual Studio 2022 ([link](https://visualstudio.microsoft.com/vs/preview/)) 10 | - Visual Studio build tools for MSVC v143 11 | - Windows SDK 10.0* (any version) ([link](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)) 12 | - Windows ADK 10.0* (must match or supersede SDK version) ([link](https://docs.microsoft.com/en-us/windows-hardware/get-started/adk-install)) 13 | > \* Builds produced with the Windows 11 ADK can only be ran in x64 WinPE images. 14 | 15 | # Running 16 | 17 | Panther2K does not have any runtime requirements. See the wiki for how to get started. 18 | 19 | # License 20 | 21 | Panther2K is currently not licensed. It will be in the future. 22 | -------------------------------------------------------------------------------- /Panther2K/FinalPage.cpp: -------------------------------------------------------------------------------- 1 | #include "FinalPage.h" 2 | #include "WindowsSetup.h" 3 | 4 | void CALLBACK TimerProc(HWND, UINT, UINT_PTR, DWORD) 5 | { 6 | PostQuitMessage(0); 7 | } 8 | 9 | void FinalPage::Init() 10 | { 11 | text = L"Panther2K"; 12 | statusText = L" ENTER=Restart"; 13 | 14 | SetTimer(NULL, NULL, WindowsSetup::RebootTimer, TimerProc); 15 | } 16 | 17 | void FinalPage::Drawer() 18 | { 19 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 20 | console->SetForegroundColor(WindowsSetup::LightForegroundColor); 21 | 22 | console->SetPosition(3, 4); 23 | console->Write(L"Setup completed succesfully."); 24 | 25 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 26 | 27 | console->SetPosition(3, 6); 28 | console->Write(L"Setup has finished installing Windows onto your computer. The Windows \n Out-Of-Box Experience (OOBE) will guide you through the rest of the\n installation. Panther2K will restart your computer in 10 seconds."); 29 | 30 | console->SetPosition(3, 10); 31 | console->Write(L"To restart now press the ENTER key."); 32 | } 33 | 34 | void FinalPage::Redrawer() 35 | { 36 | } 37 | 38 | bool FinalPage::KeyHandler(WPARAM wParam) 39 | { 40 | return wParam != VK_RETURN; 41 | } 42 | -------------------------------------------------------------------------------- /P2KConsole/Logger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Version.h" 3 | #include 4 | 5 | // Shows only basic program flow and errors 6 | #define PANTHER_LL_BASIC 0 7 | // Shows warnings and progress reports 8 | #define PANTHER_LL_NORMAL 1 9 | // Shows program flow and progress reports 10 | #define PANTHER_LL_DETAILED 2 11 | // Shows verbose progress informations 12 | #define PANTHER_LL_VERBOSE 3 13 | 14 | #define wlogf(logger, level, buffersize, message, ...) { wchar_t buffer[buffersize]; swprintf_s(buffer, message, __VA_ARGS__); logger->Write(level, buffer); } 15 | 16 | namespace LibPanther 17 | { 18 | class Logger 19 | { 20 | public: 21 | // Initialized the logger with the desired log level 22 | Logger(const wchar_t* fileName, int logLevel); 23 | 24 | // Writes to the log file with formatted time and date information 25 | void Write(int level, const wchar_t* message); 26 | 27 | // Writes directly to the log file (uses as little memory as possible) 28 | void WriteDirect(int level, const wchar_t* message); 29 | private: 30 | wchar_t timeBuffer[100]; 31 | wchar_t messageBuffer[512]; 32 | HANDLE hLogFile; 33 | const wchar_t* szLogFile; 34 | int dwLogLevel; 35 | 36 | void formatTime(); 37 | }; 38 | } 39 | 40 | void *__cdecl safeMalloc(LibPanther::Logger* logger, size_t size); -------------------------------------------------------------------------------- /P2KConsole/include/PantherLogger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "PantherVersion.h" 4 | #include 5 | 6 | // Shows only basic program flow and errors 7 | #define PANTHER_LL_BASIC 0 8 | // Shows warnings and progress reports 9 | #define PANTHER_LL_NORMAL 1 10 | // Shows program flow and progress reports 11 | #define PANTHER_LL_DETAILED 2 12 | // Shows verbose progress informations 13 | #define PANTHER_LL_VERBOSE 3 14 | 15 | #define wlogf(logger, level, buffersize, message, ...) { wchar_t buffer[buffersize]; swprintf_s(buffer, message, __VA_ARGS__); logger->Write(level, buffer); } 16 | 17 | namespace LibPanther 18 | { 19 | class Logger 20 | { 21 | public: 22 | // Initialized the logger with the desired log level 23 | Logger(const wchar_t* fileName, int logLevel); 24 | 25 | // Writes to the log file with formatted time and date information 26 | void Write(int level, const wchar_t* message); 27 | 28 | // Writes directly to the log file (uses as little memory as possible) 29 | void WriteDirect(int level, const wchar_t* message); 30 | private: 31 | wchar_t timeBuffer[100]; 32 | wchar_t messageBuffer[512]; 33 | HANDLE hLogFile; 34 | const wchar_t* szLogFile; 35 | int dwLogLevel; 36 | 37 | void formatTime(); 38 | }; 39 | } 40 | 41 | void* __cdecl safeMalloc(LibPanther::Logger* logger, size_t size); -------------------------------------------------------------------------------- /Panther2K/wdkpartial.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "windows.h" 3 | 4 | typedef struct _IO_STATUS_BLOCK { 5 | union { 6 | NTSTATUS Status; 7 | PVOID Pointer; 8 | } DUMMYUNIONNAME; 9 | 10 | ULONG_PTR Information; 11 | } IO_STATUS_BLOCK, * PIO_STATUS_BLOCK; 12 | 13 | typedef enum _FSINFOCLASS { 14 | FileFsVolumeInformation = 1, 15 | FileFsLabelInformation, // 2 16 | FileFsSizeInformation, // 3 17 | FileFsDeviceInformation, // 4 18 | FileFsAttributeInformation, // 5 19 | FileFsControlInformation, // 6 20 | FileFsFullSizeInformation, // 7 21 | FileFsObjectIdInformation, // 8 22 | FileFsDriverPathInformation, // 9 23 | FileFsVolumeFlagsInformation, // 10 24 | FileFsSectorSizeInformation, // 11 25 | FileFsDataCopyInformation, // 12 26 | FileFsMetadataSizeInformation, // 13 27 | FileFsFullSizeInformationEx, // 14 28 | FileFsMaximumInformation 29 | } FS_INFORMATION_CLASS, * PFS_INFORMATION_CLASS; 30 | 31 | typedef struct _FILE_FS_FULL_SIZE_INFORMATION { 32 | LARGE_INTEGER TotalAllocationUnits; 33 | LARGE_INTEGER CallerAvailableAllocationUnits; 34 | LARGE_INTEGER ActualAvailableAllocationUnits; 35 | ULONG SectorsPerAllocationUnit; 36 | ULONG BytesPerSector; 37 | } FILE_FS_FULL_SIZE_INFORMATION, * PFILE_FS_FULL_SIZE_INFORMATION; 38 | 39 | typedef NTSTATUS(NTAPI * NtQueryVolumeInformationFileFunction) (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, FS_INFORMATION_CLASS); -------------------------------------------------------------------------------- /WinParted/WinParted.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // Engels (Verenigde Staten) resources 18 | 19 | IDR_FONT_IBM RCDATA "Bm437_IBM_VGA_8x16.FON" 20 | 21 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 22 | LANGUAGE 19, 1 23 | 24 | #ifdef APSTUDIO_INVOKED 25 | ///////////////////////////////////////////////////////////////////////////// 26 | // 27 | // TEXTINCLUDE 28 | // 29 | 30 | 1 TEXTINCLUDE 31 | BEGIN 32 | "resource.h\0" 33 | END 34 | 35 | 2 TEXTINCLUDE 36 | BEGIN 37 | "#include ""winres.h""\r\n" 38 | "\0" 39 | END 40 | 41 | 3 TEXTINCLUDE 42 | BEGIN 43 | "\r\n" 44 | "\0" 45 | END 46 | 47 | #endif // APSTUDIO_INVOKED 48 | 49 | #endif // Engels (Verenigde Staten) resources 50 | ///////////////////////////////////////////////////////////////////////////// 51 | 52 | 53 | 54 | #ifndef APSTUDIO_INVOKED 55 | ///////////////////////////////////////////////////////////////////////////// 56 | // 57 | // Generated from the TEXTINCLUDE 3 resource. 58 | // 59 | 60 | 61 | ///////////////////////////////////////////////////////////////////////////// 62 | #endif // not APSTUDIO_INVOKED 63 | -------------------------------------------------------------------------------- /WinParted/MessagePage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Page.h" 3 | 4 | enum class MessagePageResult 5 | { 6 | Fail = 0, 7 | OK = IDOK, 8 | Cancel = IDCANCEL, 9 | Abort = IDABORT, 10 | Retry = IDRETRY, 11 | Ignore = IDIGNORE, 12 | Yes = IDYES, 13 | No = IDNO, 14 | TryAgain = IDTRYAGAIN, 15 | Continue = IDCONTINUE, 16 | }; 17 | 18 | enum class MessagePageType 19 | { 20 | OK = MB_OK, 21 | OKCancel = MB_OKCANCEL, 22 | AbortRetryIgnore = MB_ABORTRETRYIGNORE, 23 | YesNoCancel = MB_YESNOCANCEL, 24 | YesNo = MB_YESNO, 25 | RetryCancel = MB_RETRYCANCEL, 26 | CancelTryContinue = MB_CANCELTRYCONTINUE, 27 | }; 28 | 29 | enum class MessagePageUI 30 | { 31 | Normal = 0, 32 | Error = 1, 33 | Warning = 2, 34 | }; 35 | 36 | class MessagePage : private Page 37 | { 38 | public: 39 | MessagePage(); 40 | MessagePage(Console* console); 41 | MessagePage(Console* console, const wchar_t* message); 42 | MessagePage(Console* console, const wchar_t* message, MessagePageType type); 43 | MessagePage(Console* console, const wchar_t* message, MessagePageType type, MessagePageUI uiType); 44 | MessagePageResult ShowDialog(); 45 | private: 46 | const wchar_t* messageText; 47 | MessagePageType messageType; 48 | MessagePageUI messageUI; 49 | static const wchar_t messageTypeButtons[][10]; 50 | static const MessagePageResult returnValues[7][3]; 51 | static const MessagePageResult escReturnValues[7]; 52 | MessagePageResult returnValue; 53 | int selection; 54 | int selectionMax; 55 | int boxX; 56 | int boxY; 57 | int boxWidth; 58 | int boxHeight; 59 | void InitPage(); 60 | void DrawPage(); 61 | void UpdatePage(); 62 | void RunPage(); 63 | }; 64 | 65 | -------------------------------------------------------------------------------- /Panther2K/MessageBoxPage.cpp: -------------------------------------------------------------------------------- 1 | #include "MessageBoxPage.h" 2 | #include "WindowsSetup.h" 3 | 4 | MessageBoxPage::MessageBoxPage(const wchar_t* text, bool isError, Page* par) 5 | { 6 | fullText = text; 7 | error = isError; 8 | lineCount = 0; 9 | lines = 0; 10 | shown = false; 11 | parent = par; 12 | } 13 | 14 | void MessageBoxPage::ShowDialog() 15 | { 16 | MSG msg; 17 | parent->AddPopup(this); 18 | 19 | for (KEY_EVENT_RECORD* record = console->Read(); 20 | !record->bKeyDown || HandleKey(record->wVirtualKeyCode); 21 | record = console->Read()) { 22 | } 23 | 24 | parent->RemovePopup(); 25 | } 26 | 27 | void MessageBoxPage::Init() 28 | { 29 | SIZE consoleSize = console->GetSize(); 30 | width = consoleSize.cx - (consoleSize.cx / 8 * 3); 31 | 32 | lines = SplitStringToLines(fullText, width - 2, &lineCount); 33 | height = lineCount + 2; 34 | 35 | statusText = L" ENTER=Continue"; 36 | 37 | customColor = true; 38 | 39 | back = WindowsSetup::ForegroundColor; 40 | if (error) 41 | fore = WindowsSetup::ErrorColor; 42 | else 43 | fore = WindowsSetup::DarkForegroundColor; 44 | } 45 | 46 | void MessageBoxPage::Drawer() 47 | { 48 | SIZE d = console->GetSize(); 49 | int boxWidth = width + 2; 50 | int boxHeight = height + 2; 51 | int boxX = (d.cx / 2) - (boxWidth / 2); 52 | int boxY = ((d.cy - 1) / 2) - (boxHeight / 2); 53 | 54 | for (int y = 0; y < lineCount; y++) 55 | { 56 | //console->SetPosition(boxX + ((width / 2) - (lstrlenW(lines[y]) / 2)), boxY + 1 + y); 57 | console->SetPosition(boxX + 1 + ((width / 2) - (lstrlenW(lines[y]) / 2)), boxY + 1 + y); 58 | console->Write(lines[y]); 59 | } 60 | } 61 | 62 | bool MessageBoxPage::KeyHandler(WPARAM wParam) 63 | { 64 | if (wParam == VK_RETURN) 65 | return false; 66 | return true; 67 | } 68 | -------------------------------------------------------------------------------- /WinParted/Partition/PartitionTable.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "windows.h" 3 | 4 | #pragma pack(push, 1) 5 | 6 | union CHS 7 | { 8 | char Bytes[3]; 9 | }; 10 | 11 | union LBA 12 | { 13 | unsigned long long ULL; 14 | unsigned long UL[2]; 15 | unsigned short US[4]; 16 | unsigned char Char[8]; 17 | }; 18 | 19 | struct GPT_ENTRY 20 | { 21 | GUID TypeGUID; 22 | GUID UniqueGUID; 23 | LBA StartLBA; 24 | LBA EndLBA; 25 | unsigned long long AttributeFlags; 26 | wchar_t Name[36]; 27 | }; 28 | 29 | struct GPT_HEADER 30 | { 31 | unsigned long long Signature; 32 | unsigned long Revision; 33 | unsigned long HeaderSize; 34 | unsigned long HeaderCRC; 35 | unsigned long Reserved; 36 | LBA CurrentHeaderLBA; 37 | LBA BackupHeaderLBA; 38 | LBA FirstUsableLBA; 39 | LBA LastUsableLBA; 40 | GUID DiskGUID; 41 | LBA TableLBA; 42 | unsigned long TableEntryCount; 43 | unsigned long TableEntrySize; 44 | unsigned long TableCRC; 45 | }; 46 | 47 | struct MBR_ENTRY 48 | { 49 | char BootIndicator; 50 | CHS StartCHS; 51 | char SystemID; 52 | CHS EndCHS; 53 | unsigned long StartLBA; 54 | unsigned long SectorCount; 55 | }; 56 | 57 | struct MBR_HEADER 58 | { 59 | char Bootstrap1[440]; 60 | unsigned long DiskSignature1; 61 | unsigned short DiskSignature2; 62 | MBR_ENTRY PartitionTable[4]; 63 | unsigned short BootSignature; 64 | }; 65 | 66 | struct VolumeInformation 67 | { 68 | wchar_t FileSystem[16]; 69 | wchar_t VolumeName[128]; 70 | wchar_t VolumeFile[128]; 71 | }; 72 | 73 | struct PartitionInformation 74 | { 75 | long DiskNumber; 76 | long PartitionNumber; 77 | union Type 78 | { 79 | GUID TypeGUID; 80 | char SystemID; 81 | } Type; 82 | LBA StartLBA; 83 | LBA EndLBA; 84 | unsigned long long SectorCount; 85 | wchar_t Name[36]; 86 | bool VolumeLoaded; 87 | VolumeInformation VolumeInformation; 88 | }; 89 | 90 | #pragma pack(pop) -------------------------------------------------------------------------------- /P2KConsole/include/P2KBaseConsole.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define VKEY unsigned int 6 | 7 | #define CONSOLE_COLOR_BG 0 8 | #define CONSOLE_COLOR_FG 1 9 | #define CONSOLE_COLOR_ERROR 2 10 | #define CONSOLE_COLOR_PROGBAR 3 11 | #define CONSOLE_COLOR_LIGHTFG 4 12 | #define CONSOLE_COLOR_DARKFG 5 13 | 14 | struct COLOR 15 | { 16 | unsigned char R, G, B; 17 | 18 | COLORREF ToColor() 19 | { 20 | return RGB(R, G, B); 21 | } 22 | }; 23 | 24 | wchar_t* CleanString(const wchar_t* string); 25 | wchar_t** SplitStringToLines(const wchar_t* string, int maxWidth, int* lineCount); 26 | 27 | class Console 28 | { 29 | public: 30 | Console(); 31 | virtual bool Init(); 32 | 33 | virtual void SetPosition(long x, long y); 34 | virtual POINT GetPosition(); 35 | virtual void SetSize(long columns, long rows); 36 | virtual SIZE GetSize(); 37 | 38 | void SetColors(COLOR* colorTable); 39 | void SetBackgroundColor(COLOR color); 40 | void SetBackgroundColor(int index); 41 | COLOR GetBackgroundColor(); 42 | void SetForegroundColor(COLOR color); 43 | void SetForegroundColor(int index); 44 | COLOR GetForegroundColor(); 45 | 46 | void SetColorTable(COLOR* colorTable, int colorTableSize); 47 | 48 | virtual void SetCursor(bool enabled, bool blinking); 49 | 50 | virtual void Write(const wchar_t* string); 51 | virtual void WriteLine(const wchar_t* string); 52 | virtual KEY_EVENT_RECORD* Read(int count = 1); 53 | virtual KEY_EVENT_RECORD* ReadLine(); 54 | virtual void Update(); 55 | virtual void Clear(); 56 | 57 | void DrawBox(int boxX, int boxY, int boxWidth, int boxHeight, bool useDouble); 58 | void DrawTextLeft(const wchar_t* string, int cx, int y); 59 | void DrawTextRight(const wchar_t* string, int cx, int y); 60 | void DrawTextCenter(const wchar_t* string, int cx, int y); 61 | protected: 62 | int backColorIndex; 63 | int foreColorIndex; 64 | COLOR backColor; 65 | COLOR foreColor; 66 | COLOR* colorTable; 67 | int colorTableSize; 68 | 69 | virtual void UpdateColorTable(); 70 | }; 71 | -------------------------------------------------------------------------------- /P2KConsole/Console.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Version.h" 4 | #include 5 | 6 | #define VKEY unsigned int 7 | 8 | #define CONSOLE_COLOR_BG 0 9 | #define CONSOLE_COLOR_FG 1 10 | #define CONSOLE_COLOR_ERROR 2 11 | #define CONSOLE_COLOR_PROGBAR 3 12 | #define CONSOLE_COLOR_LIGHTFG 4 13 | #define CONSOLE_COLOR_DARKFG 5 14 | 15 | struct COLOR 16 | { 17 | unsigned char R, G, B; 18 | 19 | COLORREF ToColor() 20 | { 21 | return RGB(R, G, B); 22 | } 23 | }; 24 | 25 | wchar_t* CleanString(const wchar_t* string); 26 | wchar_t** SplitStringToLines(const wchar_t* string, int maxWidth, int* lineCount); 27 | 28 | class Console 29 | { 30 | public: 31 | Console(); 32 | virtual bool Init(); 33 | 34 | virtual void SetPosition(long x, long y); 35 | virtual POINT GetPosition(); 36 | virtual void SetSize(long columns, long rows); 37 | virtual SIZE GetSize(); 38 | 39 | void SetColors(COLOR* colorTable); 40 | void SetBackgroundColor(COLOR color); 41 | void SetBackgroundColor(int index); 42 | COLOR GetBackgroundColor(); 43 | void SetForegroundColor(COLOR color); 44 | void SetForegroundColor(int index); 45 | COLOR GetForegroundColor(); 46 | 47 | void SetColorTable(COLOR* colorTable, int colorTableSize); 48 | 49 | virtual void SetCursor(bool enabled, bool blinking); 50 | 51 | virtual void Write(const wchar_t* string); 52 | virtual void WriteLine(const wchar_t* string); 53 | virtual KEY_EVENT_RECORD* Read(int count = 1); 54 | virtual KEY_EVENT_RECORD* ReadLine(); 55 | virtual void Update(); 56 | virtual void Clear(); 57 | 58 | void DrawBox(int boxX, int boxY, int boxWidth, int boxHeight, bool useDouble); 59 | void DrawTextLeft(const wchar_t* string, int cx, int y); 60 | void DrawTextRight(const wchar_t* string, int cx, int y); 61 | void DrawTextCenter(const wchar_t* string, int cx, int y); 62 | protected: 63 | int backColorIndex; 64 | int foreColorIndex; 65 | COLOR backColor; 66 | COLOR foreColor; 67 | COLOR* colorTable; 68 | int colorTableSize; 69 | 70 | virtual void UpdateColorTable(); 71 | }; 72 | -------------------------------------------------------------------------------- /P2KConsole/CustomConsole.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Console.h" 3 | #include 4 | 5 | namespace Gdiplus 6 | { 7 | class Font; 8 | class Bitmap; 9 | class Graphics; 10 | }; 11 | 12 | struct DISPLAYCHAR 13 | { 14 | wchar_t character; 15 | wchar_t reserved; 16 | int backColorIndex; 17 | int foreColorIndex; 18 | COLOR backColor; 19 | COLOR foreColor; 20 | bool updated; 21 | }; 22 | 23 | class CustomConsole : public Console 24 | { 25 | public: 26 | // Constructor 27 | CustomConsole(); 28 | 29 | bool Init(); 30 | void SetPosition(long x, long y); 31 | POINT GetPosition(); 32 | void SetSize(long columns, long rows); 33 | SIZE GetSize(); 34 | 35 | void SetPixelScale(int scale); 36 | 37 | void SetCursor(bool enabled, bool blinking); 38 | 39 | void Write(const wchar_t* string); 40 | void WriteLine(const wchar_t* string); 41 | KEY_EVENT_RECORD* Read(int count = 1); 42 | KEY_EVENT_RECORD* ReadLine(); 43 | void Update(); 44 | void Clear(); 45 | 46 | //void ReloadSettings(long columns, long rows, HFONT font); 47 | void RedrawImmediately(); 48 | HWND WindowHandle; 49 | protected: 50 | void UpdateColorTable(); 51 | private: 52 | // Message loop 53 | static DWORD consoleThreadId; 54 | static bool isThreadRunning; 55 | static void __stdcall ConsoleThreadProc(HANDLE pEvent); 56 | static void ConsoleMessageLoop(); 57 | static SIZE newConsoleSize; 58 | 59 | // Output information 60 | BITMAPINFO bitmapInfo; 61 | void* bitmapBits; 62 | HBITMAP hBuf; 63 | HDC hdcBuf; 64 | bool fullScreen; 65 | 66 | // Font information 67 | static HFONT font; 68 | static long fontWidth; 69 | static long fontHeight; 70 | static bool createFont(); 71 | 72 | // Screen buffer 73 | long columns; 74 | long rows; 75 | long screenPointerX; 76 | long screenPointerY; 77 | bool screenBufferUpdated; 78 | DISPLAYCHAR* screenBuffer; 79 | std::queue* inputBuffer; 80 | std::deque* outputBuffer; 81 | 82 | // Window 83 | static bool isWindowClassCreated; 84 | static bool createWindowClass(); 85 | LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); 86 | 87 | // Helpers 88 | void incrementX(); 89 | void incrementY(); 90 | DISPLAYCHAR* WcharPointerToDisplayCharPointer(const wchar_t* string); 91 | static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); 92 | }; 93 | 94 | -------------------------------------------------------------------------------- /WinParted/Page.cpp: -------------------------------------------------------------------------------- 1 | #include "Page.h" 2 | #include "CoreFunctions\PartitionManager.h" 3 | #include "MessagePage.h" 4 | #include "PantherVersion.h" 5 | 6 | Page::Page() 7 | { 8 | console = 0; 9 | statusText = L"WinParted is inspecting your computer's hardware configuration..."; 10 | text = L"WinParted " PANTHER_VERSION " milestone 13"; 11 | drawHeader = true; 12 | drawStatus = true; 13 | drawClear = true; 14 | } 15 | 16 | void Page::Initialize(Console* con) 17 | { 18 | console = con; 19 | 20 | InitPage(); 21 | } 22 | 23 | void Page::Draw() 24 | { 25 | console->SetCursor(false, false); 26 | if (drawClear) 27 | { 28 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 29 | console->SetForegroundColor(CONSOLE_COLOR_FG); 30 | 31 | console->Clear(); 32 | } 33 | if (drawHeader) 34 | { 35 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 36 | console->SetForegroundColor(CONSOLE_COLOR_FG); 37 | 38 | console->SetPosition(1, 1); 39 | console->WriteLine(text); 40 | for (int i = 0; i < lstrlen(text) + 2; i++) 41 | console->Write(L"\x2550"); 42 | } 43 | DrawPage(); 44 | Update(); 45 | } 46 | 47 | void Page::Update() 48 | { 49 | if (drawStatus) 50 | { 51 | console->SetBackgroundColor(CONSOLE_COLOR_FG); 52 | console->SetForegroundColor(CONSOLE_COLOR_DARKFG); 53 | 54 | SIZE f = console->GetSize(); 55 | console->SetPosition(0, f.cy - 1); 56 | for (int i = 0; i < f.cx; i++) 57 | console->Write(L" "); 58 | 59 | console->SetPosition(2, f.cy - 1); 60 | console->Write(statusText); 61 | } 62 | 63 | UpdatePage(); 64 | console->Update(); 65 | } 66 | 67 | void Page::Run() 68 | { 69 | RunPage(); 70 | } 71 | 72 | void Page::SetDecorations(bool header, bool status, bool clear) 73 | { 74 | drawHeader = header; 75 | drawStatus = status; 76 | drawClear = clear; 77 | } 78 | 79 | void Page::SetText(const wchar_t* txt) 80 | { 81 | text = txt; 82 | } 83 | 84 | void Page::SetStatusText(const wchar_t* txt) 85 | { 86 | statusText = txt; 87 | } 88 | 89 | void Page::InitPage() 90 | { 91 | } 92 | 93 | void Page::DrawPage() 94 | { 95 | } 96 | 97 | void Page::UpdatePage() 98 | { 99 | } 100 | 101 | void Page::RunPage() 102 | { 103 | //console->Read(1); 104 | } 105 | 106 | Console* Page::GetConsole() 107 | { 108 | return console; 109 | } 110 | -------------------------------------------------------------------------------- /P2KConsole/include/P2KCustomConsole.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "P2KBaseConsole.h" 3 | #include 4 | 5 | namespace Gdiplus 6 | { 7 | class Font; 8 | class Bitmap; 9 | class Graphics; 10 | }; 11 | 12 | struct DISPLAYCHAR 13 | { 14 | wchar_t character; 15 | wchar_t reserved; 16 | int backColorIndex; 17 | int foreColorIndex; 18 | COLOR backColor; 19 | COLOR foreColor; 20 | bool updated; 21 | }; 22 | 23 | class CustomConsole : public Console 24 | { 25 | public: 26 | // Constructor 27 | CustomConsole(); 28 | 29 | bool Init(); 30 | void SetPosition(long x, long y); 31 | POINT GetPosition(); 32 | void SetSize(long columns, long rows); 33 | SIZE GetSize(); 34 | 35 | void SetPixelScale(int scale); 36 | 37 | void SetCursor(bool enabled, bool blinking); 38 | 39 | void Write(const wchar_t* string); 40 | void WriteLine(const wchar_t* string); 41 | KEY_EVENT_RECORD* Read(int count = 1); 42 | KEY_EVENT_RECORD* ReadLine(); 43 | void Update(); 44 | void Clear(); 45 | 46 | //void ReloadSettings(long columns, long rows, HFONT font); 47 | void RedrawImmediately(); 48 | HWND WindowHandle; 49 | protected: 50 | void UpdateColorTable(); 51 | private: 52 | // Message loop 53 | static DWORD consoleThreadId; 54 | static bool isThreadRunning; 55 | static void __stdcall ConsoleThreadProc(HANDLE pEvent); 56 | static void ConsoleMessageLoop(); 57 | static SIZE newConsoleSize; 58 | 59 | // Output information 60 | BITMAPINFO bitmapInfo; 61 | void* bitmapBits; 62 | HBITMAP hBuf; 63 | HDC hdcBuf; 64 | bool fullScreen; 65 | 66 | // Font information 67 | static HFONT font; 68 | static long fontWidth; 69 | static long fontHeight; 70 | static bool createFont(); 71 | 72 | // Screen buffer 73 | long columns; 74 | long rows; 75 | long screenPointerX; 76 | long screenPointerY; 77 | bool screenBufferUpdated; 78 | DISPLAYCHAR* screenBuffer; 79 | std::queue* inputBuffer; 80 | std::deque* outputBuffer; 81 | 82 | // Window 83 | static bool isWindowClassCreated; 84 | static bool createWindowClass(); 85 | LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); 86 | 87 | // Helpers 88 | void incrementX(); 89 | void incrementY(); 90 | DISPLAYCHAR* WcharPointerToDisplayCharPointer(const wchar_t* string); 91 | static LRESULT CALLBACK StaticWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); 92 | }; 93 | 94 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Panther2K/PopupPage.cpp: -------------------------------------------------------------------------------- 1 | #include "PopupPage.h" 2 | #include "WindowsSetup.h" 3 | 4 | void PopupPage::Initialize(Console* con, Page* par) 5 | { 6 | console = con; 7 | parent = par; 8 | 9 | Init(); 10 | Draw(); 11 | } 12 | 13 | void PopupPage::Draw() 14 | { 15 | COLOR a, b; 16 | 17 | if (customColor) 18 | { 19 | a = console->GetBackgroundColor(); 20 | b = console->GetForegroundColor(); 21 | console->SetBackgroundColor(back); 22 | console->SetForegroundColor(fore); 23 | } 24 | else 25 | { 26 | a = console->GetBackgroundColor(); 27 | b = console->GetForegroundColor(); 28 | console->SetBackgroundColor(b); 29 | console->SetForegroundColor(a); 30 | } 31 | 32 | int boxWidth = width + 2; 33 | int boxHeight = height + 2; 34 | 35 | SIZE d = console->GetSize(); 36 | 37 | int boxX = (d.cx / 2) - (boxWidth / 2); 38 | int boxY = ((d.cy - 1) / 2) - (boxHeight / 2); 39 | 40 | for (int i = 0; i < boxHeight; i++) 41 | { 42 | console->SetPosition(boxX, boxY + i); 43 | for (int j = 0; j < boxWidth; j++) 44 | console->Write(L" "); 45 | } 46 | 47 | parent->DrawBox(boxX, boxY, boxWidth, boxHeight, true); 48 | 49 | /*console->SetPosition(boxX, boxY); 50 | console->Write(L"╔"); 51 | console->SetPosition(boxX + (boxWidth - 1), boxY); 52 | console->Write(L"╗"); 53 | console->SetPosition(boxX, boxY + (boxHeight - 1)); 54 | console->Write(L"╚"); 55 | console->SetPosition(boxX + (boxWidth - 1), boxY + (boxHeight - 1)); 56 | console->Write(L"╝"); 57 | 58 | console->SetPosition(boxX + 1, boxY); 59 | for (int i = 0; i < boxWidth - 2; i++) 60 | console->Write(L"═"); 61 | 62 | console->SetPosition(boxX + 1, boxY + boxHeight - 1); 63 | for (int i = 0; i < boxWidth - 2; i++) 64 | console->Write(L"═"); 65 | 66 | for (int i = 0; i < boxHeight - 2; i++) 67 | { 68 | console->SetPosition(boxX, boxY + 1 + i); 69 | console->Write(L"║"); 70 | } 71 | 72 | for (int i = 0; i < boxHeight - 2; i++) 73 | { 74 | console->SetPosition(boxX + boxWidth - 1, boxY + 1 + i); 75 | console->Write(L"║"); 76 | }*/ 77 | 78 | console->SetPosition(boxX, boxY + boxHeight - 1 - 2); 79 | console->Write(WindowsSetup::UseCp437 ? L"\xC7" : L"╟"); 80 | for (int i = 0; i < width; i++) 81 | { 82 | console->Write(WindowsSetup::UseCp437 ? L"\xC4" : L"─"); 83 | } 84 | console->Write(WindowsSetup::UseCp437 ? L"\xB6" : L"╢"); 85 | console->SetPosition(boxX + 1, boxY + boxHeight - 1 - 1); 86 | console->Write(statusText); 87 | 88 | Drawer(); 89 | 90 | console->SetBackgroundColor(a); 91 | console->SetForegroundColor(b); 92 | } 93 | 94 | bool PopupPage::HandleKey(WPARAM wParam) 95 | { 96 | return KeyHandler(wParam); 97 | } 98 | 99 | void PopupPage::Init() 100 | { 101 | } 102 | 103 | void PopupPage::Drawer() 104 | { 105 | } 106 | 107 | bool PopupPage::KeyHandler(WPARAM wParam) 108 | { 109 | return true; 110 | } 111 | -------------------------------------------------------------------------------- /P2KConsole/P2KConsole.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {dcaaec01-f214-49d8-8040-6e8562be0d6c} 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Include Files 29 | 30 | 31 | Include Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Include Files 41 | 42 | 43 | Header Files 44 | 45 | 46 | Include Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files 53 | 54 | 55 | Header Files 56 | 57 | 58 | Header Files 59 | 60 | 61 | 62 | 63 | Source Files 64 | 65 | 66 | Source Files 67 | 68 | 69 | Source Files 70 | 71 | 72 | Source Files 73 | 74 | 75 | Source Files 76 | 77 | 78 | -------------------------------------------------------------------------------- /Panther2K.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.1.32210.238 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Panther2K", "Panther2K\Panther2K.vcxproj", "{87BBE52A-F355-4BC7-8D09-DAC1E48B3753}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {E999838A-4F2D-4748-A038-39E2BDB49722} = {E999838A-4F2D-4748-A038-39E2BDB49722} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WinParted", "WinParted\WinParted.vcxproj", "{E999838A-4F2D-4748-A038-39E2BDB49722}" 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "P2KConsole", "P2KConsole\P2KConsole.vcxproj", "{A3DD51CE-63AB-4189-9D8A-3111288A3463}" 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|x64 = Debug|x64 18 | Debug|x86 = Debug|x86 19 | Release|x64 = Release|x64 20 | Release|x86 = Release|x86 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {87BBE52A-F355-4BC7-8D09-DAC1E48B3753}.Debug|x64.ActiveCfg = Debug|x64 24 | {87BBE52A-F355-4BC7-8D09-DAC1E48B3753}.Debug|x64.Build.0 = Debug|x64 25 | {87BBE52A-F355-4BC7-8D09-DAC1E48B3753}.Debug|x86.ActiveCfg = Debug|Win32 26 | {87BBE52A-F355-4BC7-8D09-DAC1E48B3753}.Debug|x86.Build.0 = Debug|Win32 27 | {87BBE52A-F355-4BC7-8D09-DAC1E48B3753}.Release|x64.ActiveCfg = Release|x64 28 | {87BBE52A-F355-4BC7-8D09-DAC1E48B3753}.Release|x64.Build.0 = Release|x64 29 | {87BBE52A-F355-4BC7-8D09-DAC1E48B3753}.Release|x86.ActiveCfg = Release|Win32 30 | {87BBE52A-F355-4BC7-8D09-DAC1E48B3753}.Release|x86.Build.0 = Release|Win32 31 | {E999838A-4F2D-4748-A038-39E2BDB49722}.Debug|x64.ActiveCfg = Debug|x64 32 | {E999838A-4F2D-4748-A038-39E2BDB49722}.Debug|x64.Build.0 = Debug|x64 33 | {E999838A-4F2D-4748-A038-39E2BDB49722}.Debug|x86.ActiveCfg = Debug|Win32 34 | {E999838A-4F2D-4748-A038-39E2BDB49722}.Debug|x86.Build.0 = Debug|Win32 35 | {E999838A-4F2D-4748-A038-39E2BDB49722}.Release|x64.ActiveCfg = Release|x64 36 | {E999838A-4F2D-4748-A038-39E2BDB49722}.Release|x64.Build.0 = Release|x64 37 | {E999838A-4F2D-4748-A038-39E2BDB49722}.Release|x86.ActiveCfg = Release|Win32 38 | {E999838A-4F2D-4748-A038-39E2BDB49722}.Release|x86.Build.0 = Release|Win32 39 | {A3DD51CE-63AB-4189-9D8A-3111288A3463}.Debug|x64.ActiveCfg = Debug|x64 40 | {A3DD51CE-63AB-4189-9D8A-3111288A3463}.Debug|x64.Build.0 = Debug|x64 41 | {A3DD51CE-63AB-4189-9D8A-3111288A3463}.Debug|x86.ActiveCfg = Debug|Win32 42 | {A3DD51CE-63AB-4189-9D8A-3111288A3463}.Debug|x86.Build.0 = Debug|Win32 43 | {A3DD51CE-63AB-4189-9D8A-3111288A3463}.Release|x64.ActiveCfg = Release|x64 44 | {A3DD51CE-63AB-4189-9D8A-3111288A3463}.Release|x64.Build.0 = Release|x64 45 | {A3DD51CE-63AB-4189-9D8A-3111288A3463}.Release|x86.ActiveCfg = Release|Win32 46 | {A3DD51CE-63AB-4189-9D8A-3111288A3463}.Release|x86.Build.0 = Release|Win32 47 | EndGlobalSection 48 | GlobalSection(SolutionProperties) = preSolution 49 | HideSolutionNode = FALSE 50 | EndGlobalSection 51 | GlobalSection(ExtensibilityGlobals) = postSolution 52 | SolutionGuid = {B36E5252-EE10-44AA-8434-4B868D456A72} 53 | EndGlobalSection 54 | EndGlobal 55 | -------------------------------------------------------------------------------- /Panther2K/iatpatch.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void ParseIAT(HINSTANCE h) 6 | { 7 | // Find the IAT size 8 | DWORD ulsize = 0; 9 | PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(h, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulsize); 10 | if (!pImportDesc) 11 | return; 12 | 13 | // Loop names 14 | for (; pImportDesc->Name; pImportDesc++) 15 | { 16 | PSTR pszModName = (PSTR)((PBYTE)h + pImportDesc->Name); 17 | if (!pszModName) 18 | break; 19 | 20 | HINSTANCE hImportDLL = LoadLibraryA(pszModName); 21 | if (!hImportDLL) 22 | { 23 | // ... (error) 24 | } 25 | 26 | // Get caller's import address table (IAT) for the callee's functions 27 | PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) 28 | ((PBYTE)h + pImportDesc->FirstThunk); 29 | 30 | // Replace current function address with new function address 31 | for (; pThunk->u1.Function; pThunk++) 32 | { 33 | FARPROC pfnNew = 0; 34 | size_t rva = 0; 35 | #ifdef _WIN64 36 | if (pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64) 37 | #else 38 | if (pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32) 39 | #endif 40 | { 41 | // Ordinal 42 | #ifdef _WIN64 43 | size_t ord = IMAGE_ORDINAL64(pThunk->u1.Ordinal); 44 | #else 45 | size_t ord = IMAGE_ORDINAL32(pThunk->u1.Ordinal); 46 | #endif 47 | 48 | PROC* ppfn = (PROC*)&pThunk->u1.Function; 49 | if (!ppfn) 50 | { 51 | // ... (error) 52 | } 53 | rva = (size_t)pThunk; 54 | 55 | char fe[100] = { 0 }; 56 | sprintf_s(fe, 100, "#%u", ord); 57 | pfnNew = GetProcAddress(hImportDLL, (LPCSTR)ord); 58 | if (!pfnNew) 59 | { 60 | // ... (error) 61 | } 62 | } 63 | else 64 | { 65 | // Get the address of the function address 66 | PROC* ppfn = (PROC*)&pThunk->u1.Function; 67 | if (!ppfn) 68 | { 69 | // ... (error) 70 | } 71 | rva = (size_t)pThunk; 72 | PSTR fName = (PSTR)h; 73 | fName += pThunk->u1.Function; 74 | fName += 2; 75 | if (!fName) 76 | break; 77 | pfnNew = GetProcAddress(hImportDLL, fName); 78 | if (!pfnNew) 79 | { 80 | // ... (error) 81 | } 82 | } 83 | 84 | // Patch it now... 85 | auto hp = GetCurrentProcess(); 86 | if (!WriteProcessMemory(hp, (LPVOID*)rva, &pfnNew, sizeof(pfnNew), NULL) && (ERROR_NOACCESS == GetLastError())) 87 | { 88 | DWORD dwOldProtect; 89 | if (VirtualProtect((LPVOID)rva, sizeof(pfnNew), PAGE_WRITECOPY, &dwOldProtect)) 90 | { 91 | if (!WriteProcessMemory(GetCurrentProcess(), (LPVOID*)rva, &pfnNew, sizeof(pfnNew), NULL)) 92 | { 93 | // ... (error) 94 | } 95 | if (!VirtualProtect((LPVOID)rva, sizeof(pfnNew), dwOldProtect, &dwOldProtect)) 96 | { 97 | // ... (error) 98 | } 99 | } 100 | } 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /Panther2K/WindowsSetup.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "Page.h" 6 | #include "WelcomePage.h" 7 | #include 8 | 9 | void DoEvents(); 10 | 11 | struct ImageInfo 12 | { 13 | unsigned int Architecture; 14 | wchar_t* DisplayName; 15 | SYSTEMTIME CreationTime; 16 | unsigned long long TotalSize; 17 | }; 18 | 19 | typedef struct VOLUME_INFO 20 | { 21 | wchar_t mountPoint[MAX_PATH + 1]; 22 | wchar_t fileSystem[MAX_PATH + 1]; 23 | wchar_t name[MAX_PATH + 1]; 24 | wchar_t guid[MAX_PATH + 1]; 25 | long long totalBytes; 26 | long long bytesFree; 27 | int diskNumber; 28 | int partitionNumber; 29 | long long partOffset; 30 | } *PVOLUME_INFO; 31 | 32 | static class WindowsSetup 33 | { 34 | public: 35 | // Miscellaneous functions 36 | static wchar_t GetFirstFreeDrive(); 37 | static bool GetVolumeInfoFromName(const wchar_t* volumeName, PVOLUME_INFO pvi); 38 | static bool LoadConfig(); 39 | 40 | // Program loop 41 | static int RunSetup(); 42 | static void LoadPhase(int phase); 43 | static bool KeyHandler(WPARAM wParam); 44 | static void LoadPage(Page* page); 45 | static void RequestExit(); 46 | 47 | // Partition selection (phase 4) 48 | static void SelectPartition(int stringIndex, VOLUME_INFO volume); 49 | static void SelectNextPartition(int index); 50 | 51 | // WinParted functions 52 | static bool SelectPartitionsWithDisk(int diskNumber); 53 | 54 | // Drivers 55 | static void LoadDrivers(); 56 | static void InstallDrivers(); 57 | 58 | // Wim file 59 | static bool LoadWimFile(); 60 | static void GetWimImageCount(); 61 | static void EnumerateImageInfo(); 62 | 63 | static void ShowError(const wchar_t* errorMessage, int systemError, int logLevel); 64 | 65 | static LibPanther::Logger* GetLogger(); 66 | 67 | /* 68 | * Configuration 69 | */ 70 | 71 | // Console 72 | static bool UseCp437; 73 | static long Columns; 74 | static long Rows; 75 | 76 | // Phase shit 77 | static bool CanGoBack; 78 | static bool SkipPhase1; 79 | static bool SkipPhase2Wim; 80 | static bool SkipPhase2Image; 81 | static bool SkipPhase3; 82 | static bool SkipPhase4_1; 83 | static bool SkipPhase4_2; 84 | static bool SkipPhase4_3; 85 | 86 | // Global 87 | static bool IsWinPE; 88 | static int BackgroundColor; 89 | static int ForegroundColor; 90 | static int ProgressBarColor; 91 | static int ErrorColor; 92 | static int LightForegroundColor; 93 | static int DarkForegroundColor; 94 | static COLOR ConfigBackgroundColor; 95 | static COLOR ConfigForegroundColor; 96 | static COLOR ConfigProgressBarColor; 97 | static COLOR ConfigErrorColor; 98 | static COLOR ConfigLightForegroundColor; 99 | static COLOR ConfigDarkForegroundColor; 100 | 101 | // Phase 2 102 | static const wchar_t* WimFile; 103 | static HANDLE WimHandle; 104 | static int WimImageCount; 105 | static ImageInfo* WimImageInfos; 106 | static int WimImageIndex; 107 | 108 | // Phase 3 109 | static bool UseLegacy; 110 | 111 | // Phase 4 112 | static VOLUME_INFO SystemPartition; 113 | static VOLUME_INFO BootPartition; 114 | static VOLUME_INFO RecoveryPartition; 115 | /*static const wchar_t* Partition1Volume; 116 | static const wchar_t* Partition2Volume; 117 | static const wchar_t* Partition3Volume; 118 | static const wchar_t* Partition1Mount; 119 | static const wchar_t* Partition2Mount; 120 | static const wchar_t* Partition3Mount;*/ 121 | static bool UseRecovery; 122 | static bool AllowOtherFileSystems; 123 | static bool AllowSmallVolumes; 124 | 125 | // Phase 5 126 | static bool ShowFileNames; 127 | static int FileNameLength; 128 | 129 | // Phase 6 130 | static bool ContinueWithoutRecovery; 131 | 132 | // Phase 7 133 | static int RebootTimer; 134 | private: 135 | //static bool LoadPartitionFromMount(const wchar_t* buffer, const wchar_t** destVolume, const wchar_t** destMount); 136 | //static bool LoadPartitionFromVolume(wchar_t* buffer, const wchar_t* rootPath, const wchar_t* mountPath, const wchar_t** destVolume, const wchar_t** destMount); 137 | static bool LocateWimFile(wchar_t* buffer); 138 | 139 | static LibPanther::Logger* logger; 140 | static Console* console; 141 | static Page* currentPage; 142 | static bool exitRequested; 143 | }; 144 | 145 | -------------------------------------------------------------------------------- /WinParted/WinParted.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | Source Files 59 | 60 | 61 | 62 | 63 | Header Files 64 | 65 | 66 | Header Files 67 | 68 | 69 | Header Files 70 | 71 | 72 | Header Files 73 | 74 | 75 | Header Files 76 | 77 | 78 | Header Files 79 | 80 | 81 | Header Files 82 | 83 | 84 | Header Files 85 | 86 | 87 | Header Files 88 | 89 | 90 | Header Files 91 | 92 | 93 | Header Files 94 | 95 | 96 | Header Files 97 | 98 | 99 | 100 | 101 | Resource Files 102 | 103 | 104 | 105 | 106 | Source Files 107 | 108 | 109 | -------------------------------------------------------------------------------- /Panther2K/WinPartedDll.cpp: -------------------------------------------------------------------------------- 1 | #include "WinPartedDll.h" 2 | #include "iatpatch.h" 3 | #include "WindowsSetup.h" 4 | 5 | /* 6 | EXPORTS 7 | InitializeCRT @1 8 | RunWinParted @2 9 | ApplyP2KLayoutToDiskGPT @3 10 | ApplyP2KLayoutToDiskMBR @4 11 | SetPartType @5 12 | ORD_MountPartition @6 13 | */ 14 | 15 | #define ORD_InitializeCRT (LPCSTR)1 16 | #define ORD_RunWinParted (LPCSTR)2 17 | #define ORD_ApplyP2KLayoutToDiskGPT (LPCSTR)3 18 | #define ORD_ApplyP2KLayoutToDiskMBR (LPCSTR)4 19 | #define ORD_SetPartType (LPCSTR)5 20 | #define ORD_MountPartition (LPCSTR)6 21 | 22 | typedef void (*InitializeCRTStub)(); 23 | typedef int (*RunWinPartedStub)(Console*, LibPanther::Logger*); 24 | typedef HRESULT(*ApplyP2KLayoutToDiskGPTStub)(Console*, LibPanther::Logger*, int, bool, wchar_t***, wchar_t***); 25 | typedef HRESULT(*ApplyP2KLayoutToDiskMBRStub)(Console*, LibPanther::Logger*, int, bool, wchar_t***, wchar_t***); 26 | typedef HRESULT(*SetPartTypeStub)(Console*, LibPanther::Logger*, int, unsigned long long, short); 27 | typedef HRESULT(*MountPartitionStub)(Console*, LibPanther::Logger*, int, unsigned long long, const wchar_t*); 28 | 29 | bool WinPartedDll::partedInitialized = false; 30 | HMODULE WinPartedDll::hWinParted = NULL; 31 | 32 | int WinPartedDll::RunWinParted(Console* console, LibPanther::Logger* logger) 33 | { 34 | if (!partedInitialized && InitParted() != ERROR_SUCCESS) 35 | return ERROR_BAD_FORMAT; 36 | auto runWinParted = (RunWinPartedStub)GetProcAddress(hWinParted, ORD_RunWinParted); 37 | return runWinParted(console, logger); 38 | } 39 | 40 | HRESULT WinPartedDll::ApplyP2KLayoutToDiskGPT(Console* console, LibPanther::Logger* logger, int diskNumber, bool letters, wchar_t*** mountPath, wchar_t*** volumeList) 41 | { 42 | HRESULT res; 43 | if (!partedInitialized && (res = InitParted()) != ERROR_SUCCESS) 44 | return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, ERROR_BAD_FORMAT); 45 | 46 | auto applyP2kLayout = (ApplyP2KLayoutToDiskGPTStub)GetProcAddress(hWinParted, ORD_ApplyP2KLayoutToDiskGPT); 47 | return applyP2kLayout(console, logger, diskNumber, letters, mountPath, volumeList); 48 | } 49 | 50 | HRESULT WinPartedDll::ApplyP2KLayoutToDiskMBR(Console* console, LibPanther::Logger* logger, int diskNumber, bool letters, wchar_t*** mountPath, wchar_t*** volumeList) 51 | { 52 | HRESULT res; 53 | if (!partedInitialized && (res = InitParted()) != ERROR_SUCCESS) 54 | return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, res); 55 | 56 | auto applyP2kLayout = (ApplyP2KLayoutToDiskMBRStub)GetProcAddress(hWinParted, ORD_ApplyP2KLayoutToDiskMBR); 57 | return applyP2kLayout(console, logger, diskNumber, letters, mountPath, volumeList); 58 | } 59 | 60 | HRESULT WinPartedDll::SetPartType(Console* console, LibPanther::Logger* logger, int diskNumber, unsigned long long partOffset, short partType) 61 | { 62 | HRESULT res; 63 | if (!partedInitialized && (res = InitParted()) != ERROR_SUCCESS) 64 | return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, res); 65 | 66 | auto setPartType = (SetPartTypeStub)GetProcAddress(hWinParted, ORD_SetPartType); 67 | return setPartType(console, logger, diskNumber, partOffset, partType); 68 | } 69 | 70 | HRESULT WinPartedDll::MountPartition(Console* console, LibPanther::Logger* logger, int diskNumber, unsigned long long partOffset, const wchar_t* mountPoint) 71 | { 72 | 73 | HRESULT res; 74 | if (!partedInitialized && (res = InitParted()) != ERROR_SUCCESS) 75 | return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, res); 76 | 77 | auto mountPartition = (MountPartitionStub)GetProcAddress(hWinParted, ORD_MountPartition); 78 | return mountPartition(console, logger, diskNumber, partOffset, mountPoint); 79 | } 80 | 81 | HRESULT WinPartedDll::InitParted() 82 | { 83 | if (partedInitialized) return ERROR_SUCCESS; 84 | 85 | // Try loading WinParted 86 | hWinParted = LoadLibraryA("WinParted.exe"); 87 | if (!hWinParted) 88 | { 89 | wlogf(WindowsSetup::GetLogger(), PANTHER_LL_BASIC, 60, L"Error occurred while loading WinParted (0x%08x).", GetLastError()); 90 | return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); 91 | } 92 | 93 | ParseIAT(hWinParted); 94 | auto initializeCRT = (InitializeCRTStub)GetProcAddress(hWinParted, ORD_InitializeCRT); 95 | if (!initializeCRT) 96 | { 97 | wlogf(WindowsSetup::GetLogger(), PANTHER_LL_BASIC, 80, L"Error occurred while initializing WinParted CRT runtime (0x%08x).", GetLastError()); 98 | return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, GetLastError()); 99 | }; 100 | 101 | initializeCRT(); 102 | 103 | partedInitialized = true; 104 | return ERROR_SUCCESS; 105 | } -------------------------------------------------------------------------------- /WinParted/DiskSelectionPage.cpp: -------------------------------------------------------------------------------- 1 | #include "DiskSelectionPage.h" 2 | #include "CoreFunctions\PartitionManager.h" 3 | #include "DiskPartitioningPage.h" 4 | 5 | void DiskSelectionPage::InitPage() 6 | { 7 | if (PartitionManager::DiskInformationTable == NULL) 8 | PartitionManager::PopulateDiskInformation(); 9 | 10 | SetStatusText(L""); 11 | 12 | scrollIndex = 0; 13 | selectionIndex = 0; 14 | 15 | return; 16 | } 17 | 18 | void DiskSelectionPage::DrawPage() 19 | { 20 | Console* console = GetConsole(); 21 | SIZE consoleSize = console->GetSize(); 22 | 23 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 24 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 25 | console->SetPosition(3, 4); 26 | console->Write(L"Welcome to WinParted."); 27 | 28 | console->SetForegroundColor(CONSOLE_COLOR_FG); 29 | console->SetPosition(3, console->GetPosition().y + 2); 30 | console->Write(L"To begin partitioning, you need to select a disk first."); 31 | 32 | console->SetPosition(6, console->GetPosition().y + 2); 33 | console->Write(L"\x2022 To select a disk, use the UP and DOWN keys"); 34 | 35 | console->SetPosition(6, console->GetPosition().y + 2); 36 | console->Write(L"\x2022 To start partitioning the selected disk, press ENTER"); 37 | 38 | console->SetPosition(6, console->GetPosition().y + 2); 39 | console->Write(L"\x2022 To refresh the list of disks, press F5"); 40 | 41 | console->SetPosition(6, console->GetPosition().y + 2); 42 | console->Write(L"\x2022 To quit WinParted (and return to Panther2K) press F3"); 43 | 44 | console->SetPosition(3, console->GetPosition().y + 2); 45 | 46 | boxY = console->GetPosition().y; 47 | int consoleHeight = consoleSize.cy - boxY - 2; 48 | console->DrawBox(3, console->GetPosition().y, consoleSize.cx - 6, consoleHeight, true); 49 | maxItems = consoleHeight - 3; 50 | 51 | console->SetPosition(4, boxY + 1); 52 | console->WriteLine(L" Disk Device Name Part count Type Sectorsize/count"); 53 | 54 | } 55 | 56 | void DiskSelectionPage::UpdatePage() 57 | { 58 | Console* console = GetConsole(); 59 | SIZE consoleSize = console->GetSize(); 60 | 61 | int bufferSize = consoleSize.cx - 12; 62 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 63 | for (int i = 0; i < min(PartitionManager::DiskInformationTableSize, maxItems); i++) 64 | { 65 | int j = i + scrollIndex; 66 | if (i == selectionIndex) 67 | { 68 | console->SetBackgroundColor(CONSOLE_COLOR_FG); 69 | console->SetForegroundColor(CONSOLE_COLOR_BG); 70 | } 71 | else 72 | { 73 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 74 | console->SetForegroundColor(CONSOLE_COLOR_FG); 75 | } 76 | 77 | DISK_INFORMATION* diskInfo = PartitionManager::DiskInformationTable + j; 78 | console->SetPosition(6, boxY + 2 + i); 79 | swprintf(buffer, bufferSize, L"%-*s", bufferSize - 1, L""); 80 | console->Write(buffer); 81 | console->SetPosition(6, boxY + 2 + i); 82 | swprintf(buffer, bufferSize, L"%4d %-*.*s %10d %-9s %d/%lld", diskInfo->DiskNumber, bufferSize - 46, bufferSize - 46, diskInfo->DeviceName, diskInfo->PartitionCount, L"Standard", diskInfo->SectorSize, diskInfo->SectorCount); 83 | console->Write(buffer); 84 | } 85 | 86 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 87 | console->SetForegroundColor(CONSOLE_COLOR_FG); 88 | 89 | int boxY = 14; 90 | int boxHeight = consoleSize.cy - 17; 91 | 92 | bool canScrollDown = (scrollIndex + maxItems) < PartitionManager::DiskInformationTableSize; 93 | bool canScrollUp = scrollIndex != 0; 94 | 95 | console->SetPosition(consoleSize.cx - 6, boxY + boxHeight - 2); 96 | if (canScrollDown) console->Write(L"\x2193"); 97 | else console->Write(L" "); 98 | 99 | console->SetPosition(consoleSize.cx - 6, boxY + 2); 100 | if (canScrollUp) console->Write(L"\x2191"); 101 | else console->Write(L" "); 102 | } 103 | 104 | void DiskSelectionPage::RunPage() 105 | { 106 | Console* console = GetConsole(); 107 | 108 | while (KEY_EVENT_RECORD* key = console->Read()) 109 | { 110 | switch (key->wVirtualKeyCode) 111 | { 112 | case VK_DOWN: 113 | if (selectionIndex + 1 < min(maxItems, PartitionManager::DiskInformationTableSize)) 114 | selectionIndex++; 115 | else if (selectionIndex + scrollIndex + 1 < PartitionManager::DiskInformationTableSize) 116 | scrollIndex++; 117 | Update(); 118 | break; 119 | case VK_UP: 120 | if (selectionIndex - 1 >= 0) 121 | selectionIndex--; 122 | else if (selectionIndex + scrollIndex - 1 >= 0) 123 | scrollIndex--; 124 | Update(); 125 | break; 126 | case VK_F5: 127 | PartitionManager::PopulateDiskInformation(); 128 | Draw(); 129 | break; 130 | case VK_RETURN: 131 | if (PartitionManager::LoadDisk(PartitionManager::DiskInformationTable + (scrollIndex + selectionIndex), false)) 132 | { 133 | DiskPartitioningPage* page = new DiskPartitioningPage(); 134 | PartitionManager::PushPage(page); 135 | return; 136 | } 137 | break; 138 | case VK_F3: 139 | PartitionManager::Exit(0); 140 | return; 141 | } 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /Panther2K/ImageSelectionPage.cpp: -------------------------------------------------------------------------------- 1 | #include "ImageSelectionPage.h" 2 | #include "WindowsSetup.h" 3 | #include "QuitingPage.h" 4 | 5 | void ImageSelectionPage::Init() 6 | { 7 | text = L"Leet's Panther2K Setup"; 8 | statusText = L" ENTER=Select ESC=Back F3=Quit"; 9 | 10 | wchar_t buffer[256]; 11 | 12 | ::std::array a; 13 | 14 | WindowsSetup::EnumerateImageInfo(); 15 | 16 | for (int i = 0; i < WindowsSetup::WimImageCount; i++) 17 | { 18 | ImageInfo* info = WindowsSetup::WimImageInfos + i; 19 | const wchar_t* arch; 20 | switch (info->Architecture) 21 | { 22 | case 0: 23 | arch = L"x86"; 24 | break; 25 | case 9: 26 | arch = L"x86_64"; 27 | break; 28 | case 5: 29 | arch = L"ARM64"; 30 | break; 31 | default: 32 | arch = L"NaN"; 33 | break; 34 | } 35 | 36 | swprintf(buffer, 256, L"%-*s %-6s %02d/%02d/%04d", console->GetSize().cx - 16 - 18, info->DisplayName, arch, info->CreationTime.wDay, info->CreationTime.wMonth, info->CreationTime.wYear); 37 | memcpy(a.data(), buffer, sizeof(wchar_t) * 256); 38 | //::std::copy(::std::begin(buffer), ::std::end(buffer), a.begin()); 39 | //MessageBoxW(console->WindowHandle, a.data(), L"", MB_OK); 40 | FormattedStrings.push_back(a); 41 | } 42 | } 43 | 44 | void ImageSelectionPage::Drawer() 45 | { 46 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 47 | console->SetForegroundColor(WindowsSetup::LightForegroundColor); 48 | console->SetPosition(3, 4); 49 | console->Write(L"Select the operating system to be installed."); 50 | 51 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 52 | DrawTextLeft(L"Multiple operating systems were detected inside the WIM or ESD image. Please select the copy of Microsoft(R) Windows(TM) you would like to install onto your computer.", console->GetSize().cx - 6, 6); 53 | DrawTextLeft(L"Use the UP and DOWN arrow keys to select an operating system.", console->GetSize().cx - 6, console->GetPosition().y + 2); 54 | 55 | SIZE consoleSize = console->GetSize(); 56 | int boxX = 3; 57 | int boxWidth = consoleSize.cx - 6; 58 | boxY = console->GetPosition().y + 2; 59 | int boxHeight = consoleSize.cy - boxY - 2; 60 | int maxItems = boxHeight - 3; 61 | DrawBox(boxX, boxY, boxWidth, boxHeight, false); 62 | 63 | DrawTextLeft(L"Name", console->GetSize().cx - 16, boxY + 1); 64 | DrawTextRight(L"Arch Date ", console->GetSize().cx - 16, boxY + 1); 65 | } 66 | 67 | void ImageSelectionPage::Redrawer() 68 | { 69 | SIZE consoleSize = console->GetSize(); 70 | int boxHeight = consoleSize.cy - boxY - 2; 71 | int maxItems = boxHeight - 3; 72 | 73 | bool canScrollDown = (scrollIndex + maxItems) < WindowsSetup::WimImageCount; 74 | bool canScrollUp = scrollIndex != 0; 75 | 76 | for (int i = 0; i < min(maxItems, WindowsSetup::WimImageCount); i++) 77 | { 78 | int j = i + scrollIndex; 79 | wchar_t* text = FormattedStrings[j].data(); 80 | /*wchar_t buffer[100]; 81 | swprintf(buffer, 100, L"maxItems: %i\nimageCount: %i\nstringCount: %i\ni: %i\nscroll: %i\nj: %i", maxItems, WindowsSetup::WimImageCount, FormattedStrings.size(), i, scrollIndex, j); 82 | MessageBoxW(console->WindowHandle, buffer, L"", MB_OK);*/ 83 | 84 | if (i == selectionIndex) 85 | { 86 | console->SetBackgroundColor(WindowsSetup::ForegroundColor); 87 | console->SetForegroundColor(WindowsSetup::BackgroundColor); 88 | } 89 | else 90 | { 91 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 92 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 93 | } 94 | console->SetPosition(8, boxY + 2 + i); 95 | console->Write(text); 96 | } 97 | 98 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 99 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 100 | 101 | console->SetPosition(console->GetSize().cx - 6, boxY + boxHeight - 2); 102 | if (canScrollDown) console->Write(WindowsSetup::UseCp437 ? L"\x19" : L"↓"); 103 | else console->Write(L" "); 104 | 105 | console->SetPosition(console->GetSize().cx - 6, boxY + 2); 106 | if (canScrollUp) console->Write(WindowsSetup::UseCp437 ? L"\x18" : L"↑"); 107 | else console->Write(L" "); 108 | } 109 | 110 | bool ImageSelectionPage::KeyHandler(WPARAM wParam) 111 | { 112 | SIZE consoleSize = console->GetSize(); 113 | int boxHeight = consoleSize.cy - boxY - 2; 114 | int maxItems = boxHeight - 3; 115 | int totalItems = FormattedStrings.size(); 116 | 117 | switch (wParam) 118 | { 119 | case VK_DOWN: 120 | if (selectionIndex + 1 < min(maxItems, totalItems)) 121 | selectionIndex++; 122 | else if (selectionIndex + scrollIndex + 1 < totalItems) 123 | scrollIndex++; 124 | Redraw(); 125 | break; 126 | case VK_UP: 127 | if (selectionIndex - 1 >= 0) 128 | selectionIndex--; 129 | else if (selectionIndex + scrollIndex - 1 >= 0) 130 | scrollIndex--; 131 | Redraw(); 132 | break; 133 | case VK_RETURN: 134 | WindowsSetup::WimImageIndex = scrollIndex + selectionIndex + 1; 135 | WindowsSetup::LoadPhase(3); 136 | break; 137 | case VK_F3: 138 | AddPopup(new QuitingPage()); 139 | break; 140 | case VK_ESCAPE: 141 | WindowsSetup::LoadPhase(1); 142 | break; 143 | } 144 | return true; 145 | } 146 | -------------------------------------------------------------------------------- /Panther2K/Page.cpp: -------------------------------------------------------------------------------- 1 | #include "Page.h" 2 | #include "WindowsSetup.h" 3 | 4 | Page::Page() 5 | { 6 | console = 0; 7 | page = 0; 8 | statusText = 0; 9 | text = 0; 10 | } 11 | 12 | void Page::Initialize(Console* con) 13 | { 14 | console = con; 15 | 16 | Init(); 17 | Draw(); 18 | } 19 | 20 | void Page::Draw() 21 | { 22 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 23 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 24 | 25 | console->Clear(); 26 | 27 | Drawer(); 28 | Redraw(false); 29 | 30 | if (page != 0) 31 | page->Draw(); 32 | 33 | //console->RedrawImmediately(); 34 | } 35 | 36 | void Page::Redraw(bool redraw) 37 | { 38 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 39 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 40 | 41 | console->SetPosition(1, 1); 42 | console->WriteLine(text); 43 | for (int i = 0; i < lstrlen(text) + 2; i++) 44 | console->Write(WindowsSetup::UseCp437 ? L"\xCD" : L"═"); 45 | 46 | console->SetBackgroundColor(WindowsSetup::ForegroundColor); 47 | console->SetForegroundColor(WindowsSetup::DarkForegroundColor); 48 | 49 | SIZE f = console->GetSize(); 50 | console->SetPosition(0, f.cy - 1); 51 | for (int i = 0; i < f.cx; i++) 52 | console->Write(L" "); 53 | 54 | console->SetPosition(0, f.cy - 1); 55 | console->Write(statusText); 56 | 57 | Redrawer(); 58 | //if (redraw) 59 | // console->RedrawImmediately(); 60 | } 61 | 62 | bool Page::HandleKey(WPARAM wParam) 63 | { 64 | if (wParam == VK_F5) 65 | Draw(); 66 | else if (page != 0) 67 | return page->HandleKey(wParam); 68 | else 69 | return KeyHandler(wParam); 70 | } 71 | 72 | void Page::DrawBox(int boxX, int boxY, int boxWidth, int boxHeight, bool useDouble) 73 | { 74 | for (int i = 0; i < boxHeight; i++) 75 | { 76 | console->SetPosition(boxX, boxY + i); 77 | for (int j = 0; j < boxWidth; j++) 78 | console->Write(L" "); 79 | } 80 | 81 | console->SetPosition(boxX, boxY); 82 | console->Write(useDouble ? (WindowsSetup::UseCp437 ? L"\xC9" : L"╔") : (WindowsSetup::UseCp437 ? L"\xDA" : L"┌")); 83 | console->SetPosition(boxX + (boxWidth - 1), boxY); 84 | console->Write(useDouble ? (WindowsSetup::UseCp437 ? L"\xBB" : L"╗") : (WindowsSetup::UseCp437 ? L"\xBF" : L"┐")); 85 | console->SetPosition(boxX, boxY + (boxHeight - 1)); 86 | console->Write(useDouble ? (WindowsSetup::UseCp437 ? L"\xC8" : L"╚") : (WindowsSetup::UseCp437 ? L"\xC0" : L"└")); 87 | console->SetPosition(boxX + (boxWidth - 1), boxY + (boxHeight - 1)); 88 | console->Write(useDouble ? (WindowsSetup::UseCp437 ? L"\xBC" : L"╝") : (WindowsSetup::UseCp437 ? L"\xD9" : L"┘")); 89 | 90 | console->SetPosition(boxX + 1, boxY); 91 | for (int i = 0; i < boxWidth - 2; i++) 92 | console->Write(useDouble ? (WindowsSetup::UseCp437 ? L"\xCD" : L"═") : (WindowsSetup::UseCp437 ? L"\xC4" : L"─")); 93 | 94 | console->SetPosition(boxX + 1, boxY + boxHeight - 1); 95 | for (int i = 0; i < boxWidth - 2; i++) 96 | console->Write(useDouble ? (WindowsSetup::UseCp437 ? L"\xCD" : L"═") : (WindowsSetup::UseCp437 ? L"\xC4" : L"─")); 97 | 98 | for (int i = 0; i < boxHeight - 2; i++) 99 | { 100 | console->SetPosition(boxX, boxY + 1 + i); 101 | console->Write(useDouble ? (WindowsSetup::UseCp437 ? L"\xBA" : L"║") : (WindowsSetup::UseCp437 ? L"\xB3" : L"│")); 102 | } 103 | 104 | for (int i = 0; i < boxHeight - 2; i++) 105 | { 106 | console->SetPosition(boxX + boxWidth - 1, boxY + 1 + i); 107 | console->Write(useDouble ? (WindowsSetup::UseCp437 ? L"\xBA" : L"║") : (WindowsSetup::UseCp437 ? L"\xB3" : L"│")); 108 | } 109 | } 110 | 111 | void Page::DrawTextLeft(const wchar_t* string, int cx, int y) 112 | { 113 | int lineCount = 0; 114 | wchar_t** lines = SplitStringToLines(string, cx, &lineCount); 115 | 116 | int x = (console->GetSize().cx - cx) / 2; 117 | for (int i = 0; i < lineCount; i++, y++) 118 | { 119 | console->SetPosition(x, y); 120 | console->Write(lines[i]); 121 | } 122 | } 123 | 124 | void Page::DrawTextRight(const wchar_t* string, int cx, int y) 125 | { 126 | int lineCount = 0; 127 | wchar_t** lines = SplitStringToLines(string, cx, &lineCount); 128 | 129 | int paragraphX = (console->GetSize().cx - cx) / 2; 130 | for (int i = 0; i < lineCount; i++, y++) 131 | { 132 | int x = paragraphX + (cx - lstrlenW(lines[i])); 133 | console->SetPosition(x, y); 134 | console->Write(lines[i]); 135 | } 136 | } 137 | 138 | void Page::DrawTextCenter(const wchar_t* string, int cx, int y) 139 | { 140 | int lineCount = 0; 141 | wchar_t** lines = SplitStringToLines(string, cx, &lineCount); 142 | 143 | int paragraphX = (console->GetSize().cx - cx) / 2; 144 | for (int i = 0; i < lineCount; i++, y++) 145 | { 146 | int x = paragraphX + ((cx - lstrlenW(lines[i]) ) / 2); 147 | console->SetPosition(x, y); 148 | console->Write(lines[i]); 149 | } 150 | } 151 | 152 | void Page::AddPopup(PopupPage* popup) 153 | { 154 | page = popup; 155 | page->Initialize(console, this); 156 | Draw(); 157 | } 158 | 159 | void Page::RemovePopup() 160 | { 161 | page = 0; 162 | Draw(); 163 | } 164 | 165 | void Page::Init() 166 | { 167 | } 168 | 169 | void Page::Drawer() 170 | { 171 | } 172 | 173 | void Page::Redrawer() 174 | { 175 | } 176 | 177 | bool Page::KeyHandler(WPARAM wParam) 178 | { 179 | return true; 180 | } 181 | -------------------------------------------------------------------------------- /WinParted/Partition/PartitionGuidSelectionPage.cpp: -------------------------------------------------------------------------------- 1 | #include "PartitionGuidSelectionPage.h" 2 | #include "..\CoreFunctions\PartitionManager.h" 3 | 4 | void PartitionGuidSelectionPage::InitPage() 5 | { 6 | // This is what a GUID looks like. 7 | // 12345678-1234-1234-1234-123456789abc 8 | 9 | SetStatusText(L""); 10 | 11 | /*for (int i = 0; i < 36; i++) enteredChars[i] = L' '; 12 | enteredChars[8] = L'-'; 13 | enteredChars[12] = L'-'; 14 | enteredChars[16] = L'-'; 15 | enteredChars[20] = L'-'; 16 | enteredChars[36] = L'\0';*/ 17 | 18 | GPT_ENTRY* CurrentPartitionGPT = reinterpret_cast( 19 | reinterpret_cast(PartitionManager::CurrentDiskGPTTable) + 20 | (PartitionManager::CurrentDiskGPT.TableEntrySize * 21 | (PartitionManager::CurrentPartition.PartitionNumber - 1))); 22 | PartitionManager::GetGuidStringFromStructure(CurrentPartitionGPT->UniqueGUID, enteredChars); 23 | 24 | inputIndex = 36; 25 | } 26 | 27 | void PartitionGuidSelectionPage::DrawPage() 28 | { 29 | Console* console = GetConsole(); 30 | SIZE consoleSize = console->GetSize(); 31 | int bufferSize = consoleSize.cx + 1; 32 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 33 | 34 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 35 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 36 | console->SetPosition(3, 4); 37 | swprintf(buffer, bufferSize, L"Partitioning Disk %d. (%s)", PartitionManager::CurrentDisk.DiskNumber, PartitionManager::CurrentDisk.DeviceName); 38 | console->Write(buffer); 39 | if (PartitionManager::CurrentDiskPartitionsModified) 40 | console->Write(L" (partitions modified)"); 41 | 42 | console->SetForegroundColor(CONSOLE_COLOR_FG); 43 | console->SetPosition(3, console->GetPosition().y + 1); 44 | if (PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT) 45 | swprintf(buffer, bufferSize, L"Modifying Partition %d. (%s)", PartitionManager::CurrentPartition.PartitionNumber, PartitionManager::CurrentPartition.Name); 46 | else 47 | swprintf(buffer, bufferSize, L"Modifying Partition %d.", PartitionManager::CurrentPartition.PartitionNumber); 48 | console->Write(buffer); 49 | 50 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 51 | console->SetPosition(3, console->GetPosition().y + 2); 52 | console->Write(L"Enter the new unique GUID of the partition."); 53 | 54 | console->SetForegroundColor(CONSOLE_COLOR_FG); 55 | console->SetPosition(6, console->GetPosition().y + 2); 56 | console->Write(L"\x2022 To set the new GUID, enter it below."); 57 | console->SetPosition(6, console->GetPosition().y + 1); 58 | console->Write(L"\x2022 To save the new GUID, press ENTER."); 59 | console->SetPosition(6, console->GetPosition().y + 1); 60 | console->Write(L"\x2022 To go back to the partition information screen, press ESC"); 61 | 62 | console->SetPosition(3, console->GetPosition().y + 2); 63 | console->Write(L"Type ID: "); 64 | textLocation = console->GetPosition(); 65 | 66 | free(buffer); 67 | } 68 | 69 | void PartitionGuidSelectionPage::UpdatePage() 70 | { 71 | Console* console = GetConsole(); 72 | SIZE consoleSize = console->GetSize(); 73 | int bufferSize = consoleSize.cx + 1; 74 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 75 | wchar_t guidBuffer[37]; 76 | 77 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 78 | console->SetForegroundColor(CONSOLE_COLOR_FG); 79 | 80 | buffer[1] = L'\x00'; 81 | console->SetPosition(textLocation.x, textLocation.y); 82 | for (int i = 0; i < 36; i++) 83 | { 84 | buffer[0] = i < inputIndex ? enteredChars[i] : L' '; 85 | console->Write(buffer); 86 | } 87 | 88 | console->SetPosition(0, textLocation.y + 1); 89 | for (int i = 0; i < bufferSize - 1; i++) 90 | buffer[i] = L' '; 91 | buffer[bufferSize - 1] = L'\0'; 92 | console->Write(buffer); 93 | 94 | console->SetPosition(textLocation.x + inputIndex, textLocation.y); 95 | console->SetCursor(true, true); 96 | 97 | free(buffer); 98 | } 99 | 100 | void PartitionGuidSelectionPage::RunPage() 101 | { 102 | Console* console = GetConsole(); 103 | 104 | while (KEY_EVENT_RECORD* key = console->Read()) 105 | { 106 | switch (key->wVirtualKeyCode) 107 | { 108 | case L'0': case L'1': case L'2': case L'3': 109 | case L'4': case L'5': case L'6': case L'7': 110 | case L'8': case L'9': case L'A': case L'B': 111 | case L'C': case L'D': case L'E': case L'F': 112 | if (inputIndex < 36) 113 | { 114 | enteredChars[inputIndex++] = key->wVirtualKeyCode; 115 | if (inputIndex == 8 || inputIndex == 13 || 116 | inputIndex == 18 || inputIndex == 23) 117 | inputIndex++; 118 | Update(); 119 | } 120 | break; 121 | case VK_BACK: 122 | if (inputIndex > 0) 123 | { 124 | if (inputIndex == 9 || inputIndex == 14 || 125 | inputIndex == 19 || inputIndex == 24) 126 | inputIndex--; 127 | enteredChars[--inputIndex] = L'0'; 128 | Update(); 129 | } 130 | break; 131 | case VK_RETURN: 132 | { 133 | if (inputIndex < 36) 134 | break; 135 | 136 | GUID newGuid; 137 | PartitionManager::GetGuidStructureFromString(&newGuid, enteredChars); 138 | PartitionManager::SetCurrentPartitionGuid(newGuid); 139 | } 140 | case VK_ESCAPE: 141 | PartitionManager::PopPage(); 142 | return; 143 | case VK_F3: 144 | PartitionManager::Exit(0); 145 | return; 146 | } 147 | } 148 | } -------------------------------------------------------------------------------- /WinParted/CoreFunctions/PartitionManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "..\Partition\PartitionTable.h" 8 | #include "..\Page.h" 9 | #include "..\MessagePage.h" 10 | 11 | enum class PartitionTableType 12 | { 13 | Unknown = 0, 14 | MBR = 1, 15 | GPT = 2, 16 | PMBR = 4, 17 | GPT_PMBR = GPT | PMBR, 18 | GPT_HMBR = GPT | MBR, 19 | }; 20 | 21 | enum class OperatingMode 22 | { 23 | Unknown, 24 | MBR, 25 | GPT, 26 | }; 27 | 28 | struct DISK_INFORMATION 29 | { 30 | unsigned int DiskNumber; 31 | wchar_t DiskPath[64]; 32 | wchar_t DeviceName[256]; 33 | unsigned int PartitionCount; 34 | MEDIA_TYPE MediaType; 35 | unsigned int SectorSize; 36 | unsigned long long SectorCount; 37 | }; 38 | 39 | struct PartitionType 40 | { 41 | short gDiskType; 42 | GUID guid; 43 | const wchar_t* display_name; 44 | }; 45 | 46 | struct WP_PART_DESCRIPTION 47 | { 48 | int PartitionNumber; 49 | short PartitionType; 50 | wchar_t PartitionSize[10]; 51 | wchar_t FileSystem[10]; 52 | const wchar_t* MountPoint; 53 | }; 54 | 55 | struct WP_PART_LAYOUT 56 | { 57 | int PartitionCount; 58 | WP_PART_DESCRIPTION Partitions[1]; 59 | }; 60 | 61 | #define PartitionTypeCount 224 62 | #define PartitionTypeCommonCount 16 63 | 64 | class PartitionManager 65 | { 66 | public: 67 | static const PartitionType GptTypes[PartitionTypeCount]; 68 | 69 | // 70 | // UI management 71 | // 72 | 73 | static void SetConsole(Console* console); 74 | static void SetLogger(LibPanther::Logger* logger); 75 | static LibPanther::Logger* GetLogger(); 76 | static int RunWinParted(Console* console); 77 | static void PushPage(Page* page); 78 | static void PopPage(); 79 | static MessagePageResult ShowMessagePage(const wchar_t* message, MessagePageType type = MessagePageType::OK, MessagePageUI uiStyle = MessagePageUI::Normal); 80 | static void Exit(int returnCode); 81 | static void Restart(); 82 | 83 | // 84 | // Disk manipulation 85 | // 86 | 87 | static void PopulateDiskInformation(); 88 | static PartitionTableType GetPartitionTableType(DISK_INFORMATION* diskInfo); 89 | static bool LoadDisk(DISK_INFORMATION* diskInfo, bool forceOperatingMode); 90 | 91 | // 92 | // Partition table manipulation 93 | // 94 | 95 | static bool LoadPartitionTable(); 96 | static bool SavePartitionTableToDisk(); 97 | static bool AddPartition(PartitionInformation* partInfo, unsigned long long flags); 98 | static bool DeletePartition(PartitionInformation* partInfo); 99 | static HRESULT ApplyPartitionLayoutGPT(WP_PART_LAYOUT* layout); 100 | static HRESULT ApplyPartitionLayoutMBR(WP_PART_LAYOUT* layout); 101 | 102 | static DISK_INFORMATION* DiskInformationTable; 103 | static long DiskInformationTableSize; 104 | static DISK_INFORMATION CurrentDisk; 105 | static PartitionTableType CurrentDiskType; 106 | static MBR_HEADER CurrentDiskMBR; 107 | static GPT_HEADER CurrentDiskGPT; 108 | static GPT_ENTRY* CurrentDiskGPTTable; 109 | static OperatingMode CurrentDiskOperatingMode; 110 | static PartitionInformation* CurrentDiskPartitions; 111 | static long CurrentDiskPartitionCount; 112 | static bool CurrentDiskPartitionsModified; 113 | static bool CurrentDiskPartitionTableDestroyed; 114 | static long CurrentDiskFirstAvailablePartition; 115 | 116 | // 117 | // Partition manipulation 118 | // 119 | 120 | static bool LoadPartition(PartitionInformation* partition); 121 | static bool SetCurrentPartitionType(short value); 122 | static bool SetCurrentPartitionGuid(GUID value); 123 | 124 | // 125 | // Vds Functions 126 | // 127 | 128 | static HRESULT FormatPartition(PartitionInformation* partition, const wchar_t* fileSystem, const wchar_t* volumeName = L""); 129 | static HRESULT MountPartition(PartitionInformation* partition, const wchar_t* mountPoint); 130 | static HRESULT FormatAndMountPartition(PartitionInformation* partition, const wchar_t* fileSystem, const wchar_t* mountPoint, const wchar_t* volumeName = L""); 131 | static HRESULT QueryPartitionSupportedFilesystems(PartitionInformation* partition, wchar_t** query); 132 | //static HRESULT FormatAndOrMountPartition(PartitionInformation* partition, const wchar_t* fileSystem, const wchar_t* mountPoint, wchar_t** query = 0); 133 | 134 | static PartitionInformation CurrentPartition; 135 | 136 | // 137 | // Miscellaneous conversion stuff 138 | // 139 | 140 | static const wchar_t* GetOperatingModeString(); 141 | static const wchar_t* GetOperatingModeExtraString(); 142 | static void GetSizeStringFromBytes(unsigned long long bytes, wchar_t buffer[10]); 143 | static void GetGuidStringFromStructure(GUID bytes, wchar_t buffer[37]); 144 | static void GetGuidStructureFromString(GUID* bytes, const wchar_t buffer[37]); 145 | static const wchar_t* GetStringFromPartitionTypeGUID(GUID guid); 146 | static const wchar_t* GetStringFromPartitionSystemID(char systemID); 147 | static const wchar_t* GetStringFromPartitionTypeCode(short typeCode); 148 | static const GUID* GetGUIDFromPartitionTypeCode(short typeCode); 149 | static long CalculateCRC32(char* data, unsigned long long length); 150 | 151 | static Page* CurrentPage; 152 | static bool ShowNoInfoDialogs; 153 | private: 154 | static Console* currentConsole; 155 | static LibPanther::Logger* logger; 156 | static Page* nextPage; 157 | static std::stack pageStack; 158 | static bool shouldExit; 159 | static int exitCode; 160 | }; 161 | -------------------------------------------------------------------------------- /Panther2K/Panther2K.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {81f6313f-caa3-4c87-ba1b-fceea9a59a57} 18 | 19 | 20 | {a332ce52-c175-42c2-981d-852ab2d472e4} 21 | 22 | 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | Header Files 32 | 33 | 34 | Header Files 35 | 36 | 37 | Header Files 38 | 39 | 40 | Header Files 41 | 42 | 43 | Header Files\Pages 44 | 45 | 46 | Header Files 47 | 48 | 49 | Header Files 50 | 51 | 52 | Header Files\Pages 53 | 54 | 55 | Header Files\Pages 56 | 57 | 58 | Header Files\Pages 59 | 60 | 61 | Header Files\Pages 62 | 63 | 64 | Header Files\Pages 65 | 66 | 67 | Header Files\Pages 68 | 69 | 70 | Header Files 71 | 72 | 73 | Header Files\Pages 74 | 75 | 76 | Header Files\Pages 77 | 78 | 79 | Header Files 80 | 81 | 82 | Header Files\Pages 83 | 84 | 85 | Header Files 86 | 87 | 88 | 89 | 90 | Source Files 91 | 92 | 93 | Source Files 94 | 95 | 96 | Source Files 97 | 98 | 99 | Source Files 100 | 101 | 102 | Source Files\Pages 103 | 104 | 105 | Source Files\Pages 106 | 107 | 108 | Source Files\Pages 109 | 110 | 111 | Source Files\Pages 112 | 113 | 114 | Source Files\Pages 115 | 116 | 117 | Source Files\Pages 118 | 119 | 120 | Source Files\Pages 121 | 122 | 123 | Source Files\Pages 124 | 125 | 126 | Source Files\Pages 127 | 128 | 129 | Source Files\Pages 130 | 131 | 132 | Source Files 133 | 134 | 135 | 136 | 137 | Resource Files 138 | 139 | 140 | 141 | 142 | Resource Files 143 | 144 | 145 | Resource Files 146 | 147 | 148 | 149 | 150 | Resource Files 151 | 152 | 153 | -------------------------------------------------------------------------------- /WinParted/MessagePage.cpp: -------------------------------------------------------------------------------- 1 | #include "MessagePage.h" 2 | 3 | const wchar_t MessagePage::messageTypeButtons[][10] = { 4 | L"", 5 | L"OK", 6 | L"Cancel", 7 | L"Abort", 8 | L"Retry", 9 | L"Ignore", 10 | L"Yes", 11 | L"No", 12 | L"Try again", 13 | L"Continue" 14 | }; 15 | 16 | const MessagePageResult MessagePage::returnValues[7][3] = { 17 | { MessagePageResult::OK, MessagePageResult::Fail, MessagePageResult::Fail }, 18 | { MessagePageResult::OK, MessagePageResult::Cancel, MessagePageResult::Fail }, 19 | { MessagePageResult::Abort, MessagePageResult::Retry, MessagePageResult::Ignore }, 20 | { MessagePageResult::Yes, MessagePageResult::No, MessagePageResult::Cancel }, 21 | { MessagePageResult::Yes, MessagePageResult::No, MessagePageResult::Fail }, 22 | { MessagePageResult::Retry, MessagePageResult::Cancel, MessagePageResult::Fail }, 23 | { MessagePageResult::Cancel, MessagePageResult::TryAgain, MessagePageResult::Continue } 24 | }; 25 | const MessagePageResult MessagePage::escReturnValues[7] = { 26 | MessagePageResult::Fail, MessagePageResult::Cancel, MessagePageResult::Abort , 27 | MessagePageResult::Cancel, MessagePageResult::Fail, MessagePageResult::Cancel, 28 | MessagePageResult::Cancel 29 | }; 30 | 31 | MessagePage::MessagePage() : MessagePage(NULL) { } 32 | MessagePage::MessagePage(Console* console) : MessagePage(console, L"No message was supplied for this page") { } 33 | MessagePage::MessagePage(Console* console, const wchar_t* message) : MessagePage(console, message, MessagePageType::OK) { } 34 | MessagePage::MessagePage(Console* console, const wchar_t* message, MessagePageType type) : MessagePage(console, message, type, MessagePageUI::Normal) { } 35 | MessagePage::MessagePage(Console* console, const wchar_t* message, MessagePageType type, MessagePageUI uiType) 36 | { 37 | messageText = message; 38 | messageType = type; 39 | messageUI = uiType; 40 | returnValue = MessagePageResult::Fail; 41 | 42 | SetStatusText(L""); 43 | 44 | selection = 0; selectionMax = 0; 45 | boxX = 0; boxY = 0; boxWidth = 0; boxHeight = 0; 46 | Initialize(console); 47 | } 48 | 49 | MessagePageResult MessagePage::ShowDialog() 50 | { 51 | returnValue = MessagePageResult::Fail; 52 | if (GetConsole()) 53 | { 54 | Draw(); 55 | Run(); 56 | } 57 | return returnValue; 58 | } 59 | 60 | void MessagePage::InitPage() 61 | { 62 | SetDecorations(false, true, false); 63 | } 64 | 65 | void MessagePage::DrawPage() 66 | { 67 | // Box with centered text, two indent on each side. 68 | // Should be 3/8 of the size of the window 69 | int lineCount; 70 | Console* console = GetConsole(); 71 | SIZE consoleSize = console->GetSize(); 72 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * consoleSize.cx); 73 | int textWidth = consoleSize.cx - (consoleSize.cx / 8 * 3); 74 | wchar_t** lines = SplitStringToLines(messageText, textWidth - 2, &lineCount); 75 | int textHeight = lineCount + 2; 76 | 77 | const int UIBoxColors[] = { CONSOLE_COLOR_DARKFG, CONSOLE_COLOR_ERROR, CONSOLE_COLOR_PROGBAR }; 78 | const int UIFgColors[] = { CONSOLE_COLOR_DARKFG, CONSOLE_COLOR_ERROR, CONSOLE_COLOR_DARKFG }; 79 | 80 | console->SetBackgroundColor(CONSOLE_COLOR_FG); 81 | console->SetForegroundColor(UIBoxColors[(int)messageUI]); 82 | 83 | boxWidth = textWidth + 2; 84 | boxHeight = textHeight + 4; 85 | boxX = (consoleSize.cx / 2) - (boxWidth / 2); 86 | boxY = ((consoleSize.cy - 1) / 2) - (boxHeight / 2); 87 | console->DrawBox(boxX, boxY, boxWidth, boxHeight, true); 88 | 89 | console->SetForegroundColor(UIFgColors[(int)messageUI]); 90 | 91 | for (int y = 0; y < lineCount; y++) 92 | { 93 | //console->SetPosition(boxX + ((width / 2) - (lstrlenW(lines[y]) / 2)), boxY + 1 + y); 94 | console->SetPosition(boxX + 1 + ((textWidth / 2) - (lstrlenW(lines[y]) / 2)), boxY + 2 + y); 95 | console->Write(lines[y]); 96 | } 97 | 98 | /*console->SetPosition(boxX, boxY + boxHeight - 3); 99 | console->Write(L"\x255F"); 100 | for (int i = 0; i < boxWidth - 2; i++) 101 | console->Write(L"\x2500"); 102 | console->Write(L"\x2562");*/ 103 | 104 | free(buffer); 105 | } 106 | 107 | void MessagePage::UpdatePage() 108 | { 109 | Console* console = GetConsole(); 110 | 111 | selectionMax = 0; 112 | for (int i = 0; i < 3; i++) 113 | if (returnValues[(int)messageType][i] != MessagePageResult::Fail) 114 | selectionMax++; 115 | 116 | int totalWidth = boxWidth - 2; 117 | int regionWidth = totalWidth / selectionMax; 118 | 119 | for (int i = 0; i < 3; i++) 120 | { 121 | if (returnValues[(int)messageType][i] != MessagePageResult::Fail) 122 | { 123 | int buttonWidth = 4 + lstrlenW(messageTypeButtons[(int)returnValues[(int)messageType][i]]); 124 | console->SetPosition(boxX + (i * regionWidth) + (regionWidth / 2) - (buttonWidth / 2), boxY + boxHeight - 3); 125 | 126 | console->SetBackgroundColor(CONSOLE_COLOR_LIGHTFG); 127 | console->SetForegroundColor(CONSOLE_COLOR_DARKFG); 128 | 129 | bool isSelected = i == selection; 130 | if (isSelected) 131 | { 132 | console->SetBackgroundColor(CONSOLE_COLOR_DARKFG); 133 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 134 | } 135 | 136 | console->Write(isSelected ? L"< " : L" "); 137 | console->Write(messageTypeButtons[(int)returnValues[(int)messageType][i]]); 138 | console->Write(isSelected ? L" >" : L" "); 139 | } 140 | } 141 | selectionMax--; 142 | } 143 | 144 | void MessagePage::RunPage() 145 | { 146 | Console* console = GetConsole(); 147 | 148 | while (KEY_EVENT_RECORD* key = console->Read()) 149 | { 150 | switch (key->wVirtualKeyCode) 151 | { 152 | case VK_LEFT: 153 | selection--; 154 | if (selection < 0) 155 | selection = 0; 156 | Update(); 157 | break; 158 | case VK_RIGHT: 159 | selection++; 160 | if (selection > selectionMax) 161 | selection = selectionMax; 162 | Update(); 163 | break; 164 | case VK_RETURN: 165 | returnValue = returnValues[(int)messageType][selection]; 166 | return; 167 | case VK_ESCAPE: 168 | returnValue = escReturnValues[(int)messageType]; 169 | if (returnValue != MessagePageResult::Fail) 170 | return; 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /P2KConsole/Win32Console.cpp: -------------------------------------------------------------------------------- 1 | #include "pch.h" 2 | #include "Win32Console.h" 3 | #include 4 | 5 | bool rgbMode = false; 6 | 7 | bool Win32Console::Init() 8 | { 9 | //hScreenBuffer = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, NULL, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); 10 | printf("Enabling virtual terminal..."); 11 | hInputBuffer = GetStdHandle(STD_INPUT_HANDLE); 12 | hScreenBuffer = GetStdHandle(STD_OUTPUT_HANDLE); 13 | DWORD mode = 0; 14 | GetConsoleMode(hScreenBuffer, &mode); 15 | mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; 16 | SetConsoleMode(hScreenBuffer, mode); 17 | 18 | printf("Setting color palette..."); 19 | SetBackgroundColor(0); 20 | wchar_t buffer[32]; 21 | 22 | if (rgbMode) 23 | for (int i = 0; i < 6; i++) 24 | { 25 | swprintf(buffer, 32, L"\u001b]4;%d;rgb:%x/%x/%x\u001b\\", 26 | i, colorTable[i].R, colorTable[i].G, colorTable[i].B); 27 | WriteConsoleW(hScreenBuffer, buffer, lstrlenW(buffer), NULL, NULL); 28 | } 29 | 30 | return true; 31 | } 32 | 33 | void Win32Console::Init(bool createNewConsole) 34 | { 35 | if (createNewConsole) 36 | AllocConsole(); 37 | 38 | Init(); 39 | } 40 | 41 | void Win32Console::SetPosition(long x, long y) 42 | { 43 | SetConsoleCursorPosition(hScreenBuffer, { static_cast(x), static_cast(y) }); 44 | } 45 | 46 | POINT Win32Console::GetPosition() 47 | { 48 | CONSOLE_SCREEN_BUFFER_INFO bufferInfo = { 0 }; 49 | GetConsoleScreenBufferInfo(hScreenBuffer, &bufferInfo); 50 | return { bufferInfo.dwCursorPosition.X, bufferInfo.dwCursorPosition.Y }; 51 | } 52 | 53 | void Win32Console::SetSize(long columns, long rows) 54 | { 55 | /*SMALL_RECT DisplayArea = { 0, 0, 0, 0 }; 56 | DisplayArea.Right = columns; DisplayArea.Bottom = rows; 57 | SetConsoleWindowInfo(hScreenBuffer, );*/ 58 | } 59 | 60 | SIZE Win32Console::GetSize() 61 | { 62 | CONSOLE_SCREEN_BUFFER_INFO bufferInfo = { 0 }; 63 | GetConsoleScreenBufferInfo(hScreenBuffer, &bufferInfo); 64 | return { bufferInfo.srWindow.Right - bufferInfo.srWindow.Left + 1, bufferInfo.srWindow.Bottom - bufferInfo.srWindow.Top + 1 }; 65 | } 66 | 67 | void Win32Console::SetCursor(bool enabled, bool blinking) 68 | { 69 | wchar_t buffer[32]; 70 | swprintf(buffer, 32, L"\u001b[?25%s\u001b[?12%s", enabled ? L"h" : L"l", blinking ? L"h" : L"l"); 71 | WriteConsoleW(hScreenBuffer, buffer, lstrlenW(buffer), NULL, NULL); 72 | } 73 | 74 | void Win32Console::Write(const wchar_t* string) 75 | { 76 | int strlen = lstrlenW(string); 77 | wchar_t* stringwithcolorescape = (wchar_t*)malloc(sizeof(wchar_t) * (lstrlenW(string) + 40 + 1)); 78 | 79 | if (rgbMode) 80 | { 81 | swprintf(stringwithcolorescape, (lstrlenW(string) + 40 + 1), L"\u001b[38;2;%03d;%03d;%03dm\u001b[48;2;%03d;%03d;%03dm%s", foreColor.R, foreColor.G, foreColor.B, backColor.R, backColor.G, backColor.B, string); 82 | WriteConsoleW(hScreenBuffer, stringwithcolorescape, lstrlenW(stringwithcolorescape), NULL, NULL); 83 | } 84 | else 85 | { 86 | const int ansiColorIndecesFg[6] = { 30, 37, 31, 33, 97, 30 }; 87 | const int ansiColorIndecesBg[6] = { 40, 47, 41, 43, 107, 40 }; 88 | swprintf(stringwithcolorescape, (lstrlenW(string) + 40 + 1), L"\u001b[%dm\u001b[%dm%s", ansiColorIndecesFg[foreColorIndex], ansiColorIndecesBg[backColorIndex], string); 89 | WriteConsoleW(hScreenBuffer, stringwithcolorescape, lstrlenW(stringwithcolorescape), NULL, NULL); 90 | } 91 | free(stringwithcolorescape); 92 | } 93 | 94 | void Win32Console::WriteLine(const wchar_t* string) 95 | { 96 | wchar_t* stringwithlinebreak = (wchar_t*)malloc(sizeof(wchar_t) * (lstrlenW(string) + 2)); 97 | 98 | memcpy(stringwithlinebreak, string, sizeof(wchar_t) * lstrlenW(string)); 99 | stringwithlinebreak[lstrlenW(string)] = L'\n'; 100 | stringwithlinebreak[lstrlenW(string) + 1] = L'\0'; 101 | Write(stringwithlinebreak); 102 | 103 | free(stringwithlinebreak); 104 | } 105 | 106 | KEY_EVENT_RECORD* Win32Console::Read(int count) 107 | { 108 | KEY_EVENT_RECORD* keys = (KEY_EVENT_RECORD*)malloc(sizeof(KEY_EVENT_RECORD) * count); 109 | if (!keys) 110 | return NULL; 111 | 112 | INPUT_RECORD input; 113 | DWORD eventsRead; 114 | int i = 0; 115 | while (i != count) 116 | { 117 | ReadConsoleInputW(hInputBuffer, &input, 1, &eventsRead); 118 | 119 | int j = GetLastError(); 120 | 121 | if (input.EventType != KEY_EVENT) 122 | continue; 123 | 124 | if (!input.Event.KeyEvent.bKeyDown) 125 | continue; 126 | 127 | keys[i] = input.Event.KeyEvent; 128 | 129 | i++; 130 | } 131 | return keys; 132 | } 133 | 134 | KEY_EVENT_RECORD* Win32Console::ReadLine() 135 | { 136 | return nullptr; 137 | } 138 | 139 | void Win32Console::Update() { } 140 | 141 | void Win32Console::Clear() 142 | { 143 | CONSOLE_SCREEN_BUFFER_INFO csbi; 144 | SMALL_RECT scrollRect; 145 | COORD scrollTarget; 146 | CHAR_INFO fill; 147 | 148 | // Write a space to make sure the correct colors are selected 149 | Write(L" "); 150 | 151 | // Get the number of character cells in the current buffer. 152 | if (!GetConsoleScreenBufferInfo(hScreenBuffer, &csbi)) 153 | { 154 | return; 155 | } 156 | 157 | // Scroll the rectangle of the entire buffer. 158 | scrollRect.Left = 0; 159 | scrollRect.Top = 0; 160 | scrollRect.Right = csbi.dwSize.X; 161 | scrollRect.Bottom = csbi.dwSize.Y; 162 | 163 | // Scroll it upwards off the top of the buffer with a magnitude of the entire height. 164 | scrollTarget.X = 0; 165 | scrollTarget.Y = (SHORT)(0 - csbi.dwSize.Y); 166 | 167 | // Fill with empty spaces with the buffer's default text attribute. 168 | fill.Char.UnicodeChar = L' '; 169 | fill.Attributes = 0; 170 | 171 | // Do the scroll 172 | ScrollConsoleScreenBufferW(hScreenBuffer, &scrollRect, NULL, scrollTarget, &fill); 173 | 174 | // Move the cursor to the top left corner too. 175 | csbi.dwCursorPosition.X = 0; 176 | csbi.dwCursorPosition.Y = 0; 177 | 178 | SetConsoleCursorPosition(hScreenBuffer, csbi.dwCursorPosition); 179 | } 180 | 181 | void Win32Console::UpdateColorTable() 182 | { 183 | } 184 | -------------------------------------------------------------------------------- /WinParted/Partition/PartitionInformationPage.cpp: -------------------------------------------------------------------------------- 1 | #include "PartitionInformationPage.h" 2 | #include "PartitionTypeSelectionPage.h" 3 | #include "PartitionGuidSelectionPage.h" 4 | #include "PartitionFormatPage.h" 5 | #include "..\CoreFunctions\PartitionManager.h" 6 | 7 | void PartitionInformationPage::InitPage() 8 | { 9 | SetStatusText(L""); 10 | } 11 | 12 | void PartitionInformationPage::DrawPage() 13 | { 14 | Console* console = GetConsole(); 15 | SIZE consoleSize = console->GetSize(); 16 | int bufferSize = consoleSize.cx + 1; 17 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 18 | 19 | wchar_t sizeBuffer[10]; 20 | wchar_t guidBuffer[37]; 21 | 22 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 23 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 24 | console->SetPosition(3, 4); 25 | swprintf(buffer, bufferSize, L"Partitioning Disk %d. (%s)", PartitionManager::CurrentDisk.DiskNumber, PartitionManager::CurrentDisk.DeviceName); 26 | console->Write(buffer); 27 | if (PartitionManager::CurrentDiskPartitionsModified) 28 | console->Write(L" (partitions modified)"); 29 | 30 | console->SetForegroundColor(CONSOLE_COLOR_FG); 31 | console->SetPosition(3, console->GetPosition().y + 1); 32 | if (PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT) 33 | swprintf(buffer, bufferSize, L"Modifying Partition %d. (%s)", PartitionManager::CurrentPartition.PartitionNumber, PartitionManager::CurrentPartition.Name); 34 | else 35 | swprintf(buffer, bufferSize, L"Modifying Partition %d.", PartitionManager::CurrentPartition.PartitionNumber); 36 | console->Write(buffer); 37 | 38 | console->SetPosition(3, console->GetPosition().y + 2); 39 | swprintf(buffer, bufferSize, L"Partition type: %s", 40 | PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT ? 41 | PartitionManager::GetStringFromPartitionTypeGUID(PartitionManager::CurrentPartition.Type.TypeGUID) : 42 | PartitionManager::GetStringFromPartitionSystemID(PartitionManager::CurrentPartition.Type.SystemID)); 43 | console->Write(buffer); 44 | 45 | unsigned long long byteCount = PartitionManager::CurrentPartition.SectorCount * PartitionManager::CurrentDisk.SectorSize; 46 | PartitionManager::GetSizeStringFromBytes(byteCount, sizeBuffer); 47 | console->SetPosition(3, console->GetPosition().y + 1); 48 | swprintf(buffer, bufferSize, L"Partition size: %s (%llu bytes)", sizeBuffer, byteCount); 49 | console->Write(buffer); 50 | 51 | if (PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT) 52 | { 53 | GPT_ENTRY* CurrentPartitionGPT = reinterpret_cast( 54 | reinterpret_cast(PartitionManager::CurrentDiskGPTTable) + 55 | (PartitionManager::CurrentDiskGPT.TableEntrySize * 56 | (PartitionManager::CurrentPartition.PartitionNumber - 1))); 57 | PartitionManager::GetGuidStringFromStructure(CurrentPartitionGPT->UniqueGUID, guidBuffer); 58 | console->SetPosition(3, console->GetPosition().y + 1); 59 | swprintf(buffer, bufferSize, L"Partition GUID: %s", guidBuffer); 60 | console->Write(buffer); 61 | 62 | console->SetPosition(3, console->GetPosition().y + 1); 63 | swprintf(buffer, bufferSize, L"Partition attribute flags: %016llx", CurrentPartitionGPT->AttributeFlags); 64 | console->Write(buffer); 65 | } 66 | 67 | console->SetPosition(6, console->GetPosition().y + 2); 68 | console->Write(L"\x2022 To change the partition type, press T"); 69 | if (PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT) 70 | { 71 | console->SetPosition(6, console->GetPosition().y + 1); 72 | console->Write(L"\x2022 To change the partition GUID, press G"); 73 | console->SetPosition(6, console->GetPosition().y + 1); 74 | console->Write(L"\x2022 To change the attributes flags, press A"); 75 | } 76 | 77 | console->SetPosition(3, console->GetPosition().y + 1); 78 | 79 | if (!PartitionManager::CurrentDiskPartitionsModified) 80 | { 81 | if (PartitionManager::CurrentPartition.VolumeLoaded) 82 | { 83 | console->SetPosition(3, console->GetPosition().y + 1); 84 | if (lstrlenW(PartitionManager::CurrentPartition.VolumeInformation.VolumeName)) 85 | { 86 | swprintf(buffer, bufferSize, L"Volume name: %s", PartitionManager::CurrentPartition.VolumeInformation.VolumeName); 87 | console->Write(buffer); 88 | } 89 | else console->Write(L"The volume has no name."); 90 | 91 | console->SetPosition(3, console->GetPosition().y + 1); 92 | swprintf(buffer, bufferSize, L"Volume filesystem: %s", PartitionManager::CurrentPartition.VolumeInformation.FileSystem); 93 | console->Write(buffer); 94 | 95 | console->SetPosition(6, console->GetPosition().y + 2); 96 | console->Write(L"\x2022 To change the name of the partition or volume, press N"); 97 | } 98 | else 99 | { 100 | console->SetPosition(3, console->GetPosition().y + 1); 101 | console->Write(L"Cannot determine volume information:"); 102 | console->SetPosition(3, console->GetPosition().y + 1); 103 | console->Write(L"The volume does not exist or cannot be read."); 104 | console->SetPosition(3, console->GetPosition().y + 1); 105 | } 106 | 107 | console->SetPosition(6, console->GetPosition().y + 1); 108 | console->Write(L"\x2022 To format this partition, press F"); 109 | } 110 | else 111 | { 112 | console->SetPosition(3, console->GetPosition().y + 1); 113 | console->Write(L"Cannot determine or modify volume information:"); 114 | console->SetPosition(3, console->GetPosition().y + 1); 115 | console->Write(L"The partition table was modified, but not saved."); 116 | console->SetPosition(3, console->GetPosition().y + 1); 117 | } 118 | 119 | console->SetPosition(6, console->GetPosition().y + 1); 120 | console->Write(L"\x2022 To go back to the disk partitioning menu, press ESC"); 121 | } 122 | 123 | void PartitionInformationPage::UpdatePage() 124 | { 125 | 126 | } 127 | 128 | void PartitionInformationPage::RunPage() 129 | { 130 | Console* console = GetConsole(); 131 | 132 | while (KEY_EVENT_RECORD* key = console->Read()) 133 | { 134 | switch (key->wVirtualKeyCode) 135 | { 136 | case 'T': 137 | { 138 | PartitionTypeSelectionPage* page = new PartitionTypeSelectionPage(); 139 | PartitionManager::PushPage(page); 140 | return; 141 | } 142 | case 'G': 143 | if (PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT) 144 | { 145 | PartitionGuidSelectionPage* page = new PartitionGuidSelectionPage(); 146 | PartitionManager::PushPage(page); 147 | return; 148 | } 149 | break; 150 | case 'F': 151 | if (PartitionManager::CurrentDiskPartitionsModified) 152 | { 153 | PartitionManager::ShowMessagePage(L"The partition can not be formatted because the partition table has not been saved. Please save the partition table before formatting the partition.", MessagePageType::OK, MessagePageUI::Error); 154 | } 155 | else 156 | { 157 | PartitionManager::PushPage(new PartitionFormatPage()); 158 | return; 159 | } 160 | break; 161 | case VK_RETURN: 162 | //DiskPartitioningPage* page = new DiskPartitioningPage(); 163 | //PartitionManager::SetNextPage(page); 164 | break; 165 | case VK_ESCAPE: 166 | PartitionManager::PopPage(); 167 | return; 168 | case VK_F3: 169 | PartitionManager::Exit(0); 170 | return; 171 | } 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /WinParted/WinParted.cpp: -------------------------------------------------------------------------------- 1 | // WinParted.cpp : This file contains the 'main' function. Program execution begins and ends there. 2 | // 3 | 4 | #include 5 | #include "CoreFunctions\PartitionManager.h" 6 | 7 | int main() 8 | { 9 | //PrintVdsData(); 10 | PartitionManager::RunWinParted(NULL); 11 | 12 | return 0; 13 | } 14 | 15 | // Run program: Ctrl + F5 or Debug > Start Without Debugging menu 16 | // Debug program: F5 or Debug > Start Debugging menu 17 | 18 | // Tips for Getting Started: 19 | // 1. Use the Solution Explorer window to add/manage files 20 | // 2. Use the Team Explorer window to connect to source control 21 | // 3. Use the Output window to see build output and other messages 22 | // 4. Use the Error List window to view errors 23 | // 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project 24 | // 6. In the future, to open this project again, go to File > Open > Project and select the .sln file 25 | 26 | 27 | 28 | 29 | 30 | 31 | /* 32 | 33 | Hiërachy of WinParted: 34 | 35 | 36 | Welcome/Disk selection (DiskSelectionPage) 37 | │ 38 | └──Disk partitioning 39 | │ 40 | ├──Partition creation 41 | │ 42 | ├──Partition deletion 43 | │ 44 | ├──Partition table creation 45 | │ 46 | └──Partition operations 47 | │ 48 | ├──Volume creation 49 | │ 50 | ├──Partition type selection 51 | │ 52 | ├──Partition attribute selection 53 | │ 54 | ├──Partition GUID selection 55 | │ 56 | ├──Partition name selection 57 | │ 58 | └──Volume name selection 59 | 60 | 61 | ---------------------------------------------------------------------------------------------------------------- 62 | Welcome Screen 63 | ---------------------------------------------------------------------------------------------------------------- 64 | 65 | WinParted 66 | =========== 67 | 68 | Welcome to WinParted. 69 | 70 | To begin partitioning, you need to select a disk first. 71 | 72 | • To select a disk, use the UP and DOWN keys 73 | 74 | • To start partitioning the selected disk, press ENTER 75 | 76 | • To quit WinParted (and return to Panther2K) press F3 77 | 78 | ╔════════════════════════════════════════════════════════════════════════╗ 79 | ║ Disk Device Name Part count Type Sectorsize/count ║ 80 | ║ 0 AMD-RAID Array 1 3 Standard 512 / 466575360 ║ 81 | ║ 1 WDC WD10EADS-11M 1 Standard 512 / 1953520065 ║ 82 | ║ 2 ST1000DM010-2EP1 1 Standard 512 / 1953520065 ║ 83 | ║ 5 USB SanDisk 3.2Gen1 2 Removable 512 / 60083100 ║ 84 | ║ ║ 85 | ╚════════════════════════════════════════════════════════════════════════╝ 86 | 87 | 88 | ████████████████████████████████████████████████████████████████████████████████ 89 | ---------------------------------------------------------------------------------------------------------------- 90 | Disk operation screen (After selecting disk) 91 | ---------------------------------------------------------------------------------------------------------------- 92 | 93 | WinParted 94 | =========== 95 | 96 | Partitioning Disk 0 (AMD-RAID Array 1) 97 | The disk uses GPT partitioning (protective MBR). 98 | 99 | • To select a partition, use the UP and DOWN keys 100 | • To modify a partition, press ENTER 101 | 102 | • To create a new partition, press N 103 | • To delete a partition, press D 104 | • To create an empty (new) partition table, press E 105 | • To write the currently modified partition table, press W 106 | 107 | ╔════════════════════════════════════════════════════════════════════════╗ 108 | ║ Part # Partition type Start End Size ║ 109 | ║ 1 EFI system partition 2048 1026047 1024000 ║ 110 | ║ 2 Microsoft basic data 1026048 368267230 367241181 ║ 111 | ║ 3 Linux filesystem 368269312 466575326 98306015 ║ 112 | ║ ║ 113 | ║ ║ 114 | ╚════════════════════════════════════════════════════════════════════════╝ 115 | Sector size=512 Alignment=2048 116 | 117 | ██ESC=Back██F3=Quit█████████████████████████████████████████████████████████████ 118 | ---------------------------------------------------------------------------------------------------------------- 119 | Partition operation sceen (After selecting partition) 120 | ---------------------------------------------------------------------------------------------------------------- 121 | 122 | WinParted 123 | =========== 124 | 125 | Partitioning Disk 0 (AMD-RAID Array 1) 126 | 127 | Modifying Partition 1 128 | 129 | Partition type: EFI System Partition 130 | Partition size: 500MiB (524288000 bytes) 131 | Partition name: EFI System Partition 132 | Partition GUID: 8B83AABE-28FC-4B1F-9D23-5A101CB17C0A 133 | Attribute flags: 0000000000000000 134 | Volume name: EFI | Cannot determine or modify volume information: 135 | Volume filesystem: FAT32 | The partition table was modified, but not saved. 136 | 137 | • To change the partition type, press T 138 | • To change the partition GUID, press G 139 | • To change the attributes flags, press A 140 | • To change the name of the partition or volume, press N 141 | • To format this partition, press F 142 | • To go back to the disk partitioning menu, press ESC 143 | 144 | 145 | ████████████████████████████████████████████████████████████████████████████████ 146 | ----- 147 | New partition screen 148 | ----- 149 | /* 150 | 151 | WinParted 1.2.0m12 152 | ======================== 153 | 154 | Partitioning Disk 0. (AMD-RAID Array) 155 | 156 | Creating new partition. 157 | 158 | Please select one of the free spaces of the disk below, and specify the 159 | size of the partition. 160 | 161 | ╔════════════════════════════════════════════════════════════════════════╗ 162 | ║ Location Start End Available ║ 163 | ║ *At the start of the disk 2048 500MB ║ 164 | ║ Before partition 1 1026047 500MB ║ 165 | ║ After partition 1 2052096 400GB ║ 166 | ║ At the end of the disk 1232896000 400GB ║ 167 | ║ ║ 168 | ║ ║ 169 | ╚════════════════════════════════════════════════════════════════════════╝ 170 | 171 | Size: 250M (512000 sectors) 172 | 0B [████████████████████████████████ ] 500M 173 | 174 | ████████████████████████████████████████████████████████████████████████████████ 175 | */ -------------------------------------------------------------------------------- /Panther2K/PartitionSelectionPage.cpp: -------------------------------------------------------------------------------- 1 | #include "PartitionSelectionPage.h" 2 | #include "WindowsSetup.h" 3 | #include "QuitingPage.h" 4 | #include "MessageBoxPage.h" 5 | #include "WinPartedDll.h" 6 | 7 | const wchar_t* const part1Strings[] = 8 | { 9 | L"Select the System partition.", 10 | L"Select the EFI System Partition partition.", 11 | L"Select the System Reserved partition.", 12 | L"Select the Recovery partition." 13 | }; 14 | const wchar_t* const part2Strings[] = 15 | { 16 | L"Panther2K will use this partition to store the system files for the Microsoft Windows operating system. This partition will be available as the C: drive from within Windows.", 17 | L"Panther2K will use this partition to store the files required for booting Microsoft Windows on your computer. This is a system reserved partition that will not be available for use inside Windows after installation.", 18 | L"Panther2K will use this partition to store the files required for booting Microsoft Windows on your computer. This is a system reserved partition that will not be available for use inside Windows after installation.", 19 | L"Panther2K will use this partition to store the files required for booting into the Windows Recovery Environment (WinRE). WinRE can be used whenever Windows fails to load, for example due to an incompatible driver update." 20 | }; 21 | 22 | PartitionSelectionPage::PartitionSelectionPage(const wchar_t* fileSystem, long long minimumSize, long long minimumBytesAvailable, int stringIndex, int displayIndex) 23 | { 24 | requirements.fileSystem = fileSystem; 25 | requirements.partitionSize = minimumSize; 26 | requirements.partitionFree = minimumBytesAvailable; 27 | stringTableIndex = stringIndex; 28 | dispIndex = displayIndex; 29 | } 30 | 31 | void PartitionSelectionPage::EnumeratePartitions() 32 | { 33 | BOOL success; 34 | wchar_t szNextVolName[MAX_PATH + 1]; 35 | HANDLE volume; 36 | 37 | volume = FindFirstVolume(szNextVolName, MAX_PATH); 38 | success = (volume != INVALID_HANDLE_VALUE); 39 | while (success) 40 | { 41 | VOLUME_INFO vi; 42 | if (!WindowsSetup::GetVolumeInfoFromName(szNextVolName, &vi)) 43 | goto nextVol; 44 | if (!showAll && !WindowsSetup::AllowSmallVolumes && (vi.bytesFree < requirements.partitionFree || vi.totalBytes < requirements.partitionSize)) 45 | goto nextVol; 46 | if (!showAll && !WindowsSetup::AllowOtherFileSystems && lstrcmpW(vi.fileSystem, requirements.fileSystem) != 0) 47 | goto nextVol; 48 | 49 | volumeInfo.push_back(vi); 50 | nextVol: 51 | success = FindNextVolume(volume, szNextVolName, MAX_PATH) != 0; 52 | } 53 | 54 | Draw(); 55 | } 56 | 57 | VOLUME_INFO PartitionSelectionPage::GetSelectedVolume() 58 | { 59 | return volumeInfo[scrollIndex + selectionIndex]; 60 | } 61 | 62 | void PartitionSelectionPage::Init() 63 | { 64 | wchar_t* displayName = WindowsSetup::WimImageInfos[WindowsSetup::WimImageIndex - 1].DisplayName; 65 | int length = lstrlenW(displayName); 66 | wchar_t* textBuffer = (wchar_t*)safeMalloc(WindowsSetup::GetLogger(), length * sizeof(wchar_t) + 14); 67 | memcpy(textBuffer, displayName, length * sizeof(wchar_t)); 68 | memcpy(textBuffer + length, L" Setup", 14); 69 | text = textBuffer; 70 | statusText = L" ENTER=Select F8=Run WinParted F9=Display all ESC=Back F3=Quit"; 71 | } 72 | 73 | void PartitionSelectionPage::Drawer() 74 | { 75 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 76 | console->SetForegroundColor(WindowsSetup::LightForegroundColor); 77 | 78 | DrawTextLeft(part1Strings[stringTableIndex], console->GetSize().cx - 6, 4); 79 | 80 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 81 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 82 | 83 | DrawTextLeft(part2Strings[stringTableIndex], console->GetSize().cx - 6, console->GetPosition().y + 2); 84 | 85 | DrawTextLeft(L"Use the UP and DOWN ARROW keys to select the partition.", console->GetSize().cx - 6, console->GetPosition().y + 2); 86 | 87 | DrawTextLeft(L"Press F8 to modify your partition layout using DiskPart.", console->GetSize().cx - 6, console->GetPosition().y + 1); 88 | 89 | int boxX = 3; 90 | boxY = console->GetPosition().y + 2; 91 | int boxWidth = console->GetSize().cx - 6; 92 | int boxHeight = console->GetSize().cy - (boxY + 2); 93 | DrawBox(boxX, boxY, boxWidth, boxHeight, true); 94 | 95 | wchar_t* buffer = (wchar_t*)safeMalloc(WindowsSetup::GetLogger(), sizeof(wchar_t) * (boxWidth - 2)); 96 | swprintf(buffer, boxWidth - 2, L" Disk Partition Volume Name%*sSize (GB) Mount Point ", boxWidth - 58, L""); 97 | console->SetPosition(boxX + 1, boxY + 1); 98 | console->Write(buffer); 99 | free(buffer); 100 | } 101 | 102 | void PartitionSelectionPage::Redrawer() 103 | { 104 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 105 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 106 | 107 | int boxX = 3; 108 | int boxWidth = console->GetSize().cx - 6; 109 | int boxHeight = console->GetSize().cy - (boxY + 2); 110 | int maxItems = boxHeight - 3; 111 | 112 | bool canScrollDown = (scrollIndex + maxItems) < WindowsSetup::WimImageCount; 113 | bool canScrollUp = scrollIndex != 0; 114 | 115 | wchar_t* buffer = (wchar_t*)safeMalloc(WindowsSetup::GetLogger(), sizeof(wchar_t) * (boxWidth - 2)); 116 | for (int i = 0; i < min(volumeInfo.size(), maxItems); i++) 117 | { 118 | if (i == selectionIndex) 119 | { 120 | console->SetBackgroundColor(WindowsSetup::ForegroundColor); 121 | console->SetForegroundColor(WindowsSetup::BackgroundColor); 122 | } 123 | else 124 | { 125 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 126 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 127 | } 128 | 129 | console->SetPosition(boxX + 4, boxY + i + 2); 130 | swprintf(buffer, boxWidth - 2, L"%4d %-9d %-*s%10.1F %-11s", volumeInfo[i].diskNumber, volumeInfo[i].partitionNumber, boxWidth - 48, volumeInfo[i].name, static_cast(volumeInfo[i].totalBytes / 1000) / 1000.0, volumeInfo[i].mountPoint); 131 | console->Write(buffer); 132 | } 133 | free(buffer); 134 | } 135 | 136 | bool PartitionSelectionPage::KeyHandler(WPARAM wParam) 137 | { 138 | int boxX = 3; 139 | int boxWidth = console->GetSize().cx - 6; 140 | int boxHeight = console->GetSize().cy - (boxY + 2); 141 | int maxItems = boxHeight - 3; 142 | int totalItems = volumeInfo.size(); 143 | switch (wParam) 144 | { 145 | case VK_DOWN: 146 | if (selectionIndex + 1 < min(maxItems, totalItems)) 147 | selectionIndex++; 148 | else if (selectionIndex + scrollIndex + 1 < totalItems) 149 | scrollIndex++; 150 | Redraw(); 151 | break; 152 | case VK_UP: 153 | if (selectionIndex - 1 >= 0) 154 | selectionIndex--; 155 | else if (selectionIndex + scrollIndex - 1 >= 0) 156 | scrollIndex--; 157 | Redraw(); 158 | break; 159 | case VK_F3: 160 | AddPopup(new QuitingPage()); 161 | break; 162 | case VK_F8: 163 | WinPartedDll::RunWinParted(console, WindowsSetup::GetLogger()); 164 | Draw(); 165 | break; 166 | case VK_F9: 167 | showAll = !showAll; 168 | EnumeratePartitions(); 169 | break; 170 | case VK_ESCAPE: 171 | WindowsSetup::SelectNextPartition(dispIndex - 1); 172 | break; 173 | case VK_RETURN: 174 | WindowsSetup::SelectPartition(stringTableIndex, GetSelectedVolume()); 175 | WindowsSetup::SelectNextPartition(dispIndex + 1); 176 | break; 177 | } 178 | return true; 179 | } 180 | -------------------------------------------------------------------------------- /WinParted/DiskPartitioningPage.cpp: -------------------------------------------------------------------------------- 1 | #include "DiskPartitioningPage.h" 2 | #include "CoreFunctions\PartitionManager.h" 3 | #include "Partition\PartitionInformationPage.h" 4 | #include "Partition\PartitionCreationPage.h" 5 | #include "Partition\PartitionTypeSelectionPage.h" 6 | 7 | void DiskPartitioningPage::InitPage() 8 | { 9 | if (PartitionManager::CurrentDiskPartitions == NULL) 10 | PartitionManager::LoadPartitionTable(); 11 | 12 | SetStatusText(L""); 13 | 14 | scrollIndex = 0; 15 | selectionIndex = 0; 16 | 17 | return; 18 | } 19 | 20 | void DiskPartitioningPage::DrawPage() 21 | { 22 | Console* console = GetConsole(); 23 | SIZE consoleSize = console->GetSize(); 24 | int bufferSize = consoleSize.cx + 1; 25 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 26 | 27 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 28 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 29 | console->SetPosition(3, 4); 30 | swprintf(buffer, bufferSize, L"Partitioning Disk %d. (%s)", PartitionManager::CurrentDisk.DiskNumber, PartitionManager::CurrentDisk.DeviceName); 31 | console->Write(buffer); 32 | if (PartitionManager::CurrentDiskPartitionsModified) 33 | console->Write(L" (partitions modified)"); 34 | 35 | console->SetForegroundColor(CONSOLE_COLOR_FG); 36 | console->SetPosition(3, 5); 37 | swprintf(buffer, bufferSize, L"The disk uses %s partitioning.%s", PartitionManager::GetOperatingModeString(), PartitionManager::GetOperatingModeExtraString()); 38 | console->Write(buffer); 39 | 40 | console->SetPosition(6, 7); 41 | console->Write(L"\x2022 To select a partition, use the UP and DOWN keys"); 42 | console->SetPosition(6, 8); 43 | console->Write(L"\x2022 To modify a partition, press ENTER"); 44 | 45 | console->SetPosition(6, 10); 46 | console->Write(L"\x2022 To create a new partition, press N"); 47 | console->SetPosition(6, 11); 48 | console->Write(L"\x2022 To delete a partition, press D"); 49 | console->SetPosition(6, 12); 50 | console->Write(L"\x2022 To create an empty (new) partition table, press E"); 51 | 52 | 53 | console->DrawBox(3, 15, consoleSize.cx - 6, consoleSize.cy - 17, true); 54 | maxItems = consoleSize.cy - 17 - 3; 55 | 56 | console->SetPosition(4, 16); 57 | console->WriteLine(L" Part # Partition type Start End Size"); 58 | } 59 | 60 | void DiskPartitioningPage::UpdatePage() 61 | { 62 | Console* console = GetConsole(); 63 | SIZE consoleSize = console->GetSize(); 64 | 65 | int bufferSize = consoleSize.cx - 13 + 1; 66 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 67 | wchar_t sizeBuffer[10]; 68 | for (int i = 0; i < min(PartitionManager::CurrentDiskPartitionCount, maxItems); i++) 69 | { 70 | int j = i + scrollIndex; 71 | if (i == selectionIndex) 72 | { 73 | console->SetBackgroundColor(CONSOLE_COLOR_FG); 74 | console->SetForegroundColor(CONSOLE_COLOR_BG); 75 | } 76 | else 77 | { 78 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 79 | console->SetForegroundColor(CONSOLE_COLOR_FG); 80 | } 81 | 82 | 83 | swprintf(buffer, bufferSize, L"%-*s", bufferSize - 1, L""); 84 | console->SetPosition(6, 17 + i); 85 | console->Write(buffer); 86 | 87 | PartitionInformation* partitionInfo = PartitionManager::CurrentDiskPartitions + j; 88 | PartitionManager::GetSizeStringFromBytes(partitionInfo->SectorCount * PartitionManager::CurrentDisk.SectorSize, sizeBuffer); 89 | swprintf(buffer, bufferSize, L"%6d %-20.20s %-11llu %-11llu %s", 90 | partitionInfo->PartitionNumber, 91 | PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT ? 92 | PartitionManager::GetStringFromPartitionTypeGUID(partitionInfo->Type.TypeGUID) : 93 | PartitionManager::GetStringFromPartitionSystemID(partitionInfo->Type.SystemID), 94 | partitionInfo->StartLBA.ULL, 95 | partitionInfo->EndLBA.ULL, 96 | sizeBuffer); 97 | console->SetPosition(6, 17 + i); 98 | console->Write(buffer); 99 | } 100 | 101 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 102 | console->SetForegroundColor(CONSOLE_COLOR_FG); 103 | 104 | if (PartitionManager::CurrentDiskPartitionsModified) 105 | { 106 | console->SetPosition(6, 13); 107 | console->Write(L"\x2022 To write the currently modified partition table, press F10"); 108 | } 109 | 110 | int boxY = 15; 111 | int boxHeight = consoleSize.cy - 17; 112 | 113 | bool canScrollDown = (scrollIndex + maxItems) < PartitionManager::CurrentDiskPartitionCount; 114 | bool canScrollUp = scrollIndex != 0; 115 | 116 | console->SetPosition(consoleSize.cx - 6, boxY + boxHeight - 2); 117 | if (canScrollDown) console->Write(L"\x2193"); 118 | else console->Write(L" "); 119 | 120 | console->SetPosition(consoleSize.cx - 6, boxY + 2); 121 | if (canScrollUp) console->Write(L"\x2191"); 122 | else console->Write(L" "); 123 | } 124 | 125 | void DiskPartitioningPage::RunPage() 126 | { 127 | Console* console = GetConsole(); 128 | 129 | while (KEY_EVENT_RECORD* key = console->Read()) 130 | { 131 | switch (key->wVirtualKeyCode) 132 | { 133 | case 'T': 134 | if (PartitionManager::LoadPartition(PartitionManager::CurrentDiskPartitions + (selectionIndex + scrollIndex))) 135 | { 136 | PartitionTypeSelectionPage* page = new PartitionTypeSelectionPage(); 137 | PartitionManager::PushPage(page); 138 | return; 139 | } 140 | break; 141 | case 'D': 142 | if (PartitionManager::ShowMessagePage(L"Are you sure you would like to remove this partition?", MessagePageType::YesNo) == MessagePageResult::Yes) 143 | { 144 | PartitionManager::DeletePartition(PartitionManager::CurrentDiskPartitions + (selectionIndex + scrollIndex)); 145 | selectionIndex = 0; 146 | scrollIndex = 0; 147 | Draw(); 148 | } 149 | break; 150 | case 'N': 151 | PartitionManager::PushPage(new PartitionCreationPage()); 152 | return; 153 | case VK_DOWN: 154 | if (selectionIndex + 1 < min(maxItems, PartitionManager::CurrentDiskPartitionCount)) 155 | selectionIndex++; 156 | else if (selectionIndex + scrollIndex + 1 < PartitionManager::CurrentDiskPartitionCount) 157 | scrollIndex++; 158 | Update(); 159 | break; 160 | case VK_UP: 161 | if (selectionIndex - 1 >= 0) 162 | selectionIndex--; 163 | else if (selectionIndex + scrollIndex - 1 >= 0) 164 | scrollIndex--; 165 | Update(); 166 | break; 167 | case VK_RETURN: 168 | if (PartitionManager::LoadPartition(PartitionManager::CurrentDiskPartitions + (selectionIndex + scrollIndex))) 169 | { 170 | PartitionInformationPage* page = new PartitionInformationPage(); 171 | PartitionManager::PushPage(page); 172 | return; 173 | } 174 | break; 175 | case VK_ESCAPE: 176 | if (PartitionManager::CurrentDiskPartitionsModified) 177 | { 178 | switch (PartitionManager::ShowMessagePage(L"The partition table was modified, but it was not saved to disk. Would you like to save the modified partition table before returning to the disk selection page?", MessagePageType::YesNoCancel)) 179 | { 180 | case MessagePageResult::Yes: 181 | // Save and return 182 | PartitionManager::SavePartitionTableToDisk(); 183 | PartitionManager::PopPage(); 184 | return; 185 | case MessagePageResult::No: 186 | // Discard and return 187 | PartitionManager::CurrentDiskPartitionsModified = false; 188 | PartitionManager::PopPage(); 189 | return; 190 | case MessagePageResult::Cancel: 191 | // Just break 192 | break; 193 | } 194 | } 195 | else 196 | { 197 | PartitionManager::PopPage(); 198 | return; 199 | } 200 | break; 201 | case VK_F3: 202 | PartitionManager::Exit(0); 203 | return; 204 | case VK_F10: 205 | if (PartitionManager::CurrentDiskPartitionsModified) 206 | PartitionManager::SavePartitionTableToDisk(); 207 | break; 208 | } 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Ww][Ii][Nn]32/ 27 | [Aa][Rr][Mm]/ 28 | [Aa][Rr][Mm]64/ 29 | bld/ 30 | [Bb]in/ 31 | [Oo]bj/ 32 | [Oo]ut/ 33 | [Ll]og/ 34 | [Ll]ogs/ 35 | 36 | # Visual Studio 2015/2017 cache/options directory 37 | .vs/ 38 | # Uncomment if you have tasks that create the project's static files in wwwroot 39 | #wwwroot/ 40 | 41 | # Visual Studio 2017 auto generated files 42 | Generated\ Files/ 43 | 44 | # MSTest test Results 45 | [Tt]est[Rr]esult*/ 46 | [Bb]uild[Ll]og.* 47 | 48 | # NUnit 49 | *.VisualState.xml 50 | TestResult.xml 51 | nunit-*.xml 52 | 53 | # Build Results of an ATL Project 54 | [Dd]ebugPS/ 55 | [Rr]eleasePS/ 56 | dlldata.c 57 | 58 | # Benchmark Results 59 | BenchmarkDotNet.Artifacts/ 60 | 61 | # .NET Core 62 | project.lock.json 63 | project.fragment.lock.json 64 | artifacts/ 65 | 66 | # ASP.NET Scaffolding 67 | ScaffoldingReadMe.txt 68 | 69 | # StyleCop 70 | StyleCopReport.xml 71 | 72 | # Files built by Visual Studio 73 | *_i.c 74 | *_p.c 75 | *_h.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.iobj 80 | *.pch 81 | *.pdb 82 | *.ipdb 83 | *.pgc 84 | *.pgd 85 | *.rsp 86 | *.sbr 87 | *.tlb 88 | *.tli 89 | *.tlh 90 | *.tmp 91 | *.tmp_proj 92 | *_wpftmp.csproj 93 | *.log 94 | *.vspscc 95 | *.vssscc 96 | .builds 97 | *.pidb 98 | *.svclog 99 | *.scc 100 | 101 | # Chutzpah Test files 102 | _Chutzpah* 103 | 104 | # Visual C++ cache files 105 | ipch/ 106 | *.aps 107 | *.ncb 108 | *.opendb 109 | *.opensdf 110 | *.sdf 111 | *.cachefile 112 | *.VC.db 113 | *.VC.VC.opendb 114 | 115 | # Visual Studio profiler 116 | *.psess 117 | *.vsp 118 | *.vspx 119 | *.sap 120 | 121 | # Visual Studio Trace Files 122 | *.e2e 123 | 124 | # TFS 2012 Local Workspace 125 | $tf/ 126 | 127 | # Guidance Automation Toolkit 128 | *.gpState 129 | 130 | # ReSharper is a .NET coding add-in 131 | _ReSharper*/ 132 | *.[Rr]e[Ss]harper 133 | *.DotSettings.user 134 | 135 | # TeamCity is a build add-in 136 | _TeamCity* 137 | 138 | # DotCover is a Code Coverage Tool 139 | *.dotCover 140 | 141 | # AxoCover is a Code Coverage Tool 142 | .axoCover/* 143 | !.axoCover/settings.json 144 | 145 | # Coverlet is a free, cross platform Code Coverage Tool 146 | coverage*.json 147 | coverage*.xml 148 | coverage*.info 149 | 150 | # Visual Studio code coverage results 151 | *.coverage 152 | *.coveragexml 153 | 154 | # NCrunch 155 | _NCrunch_* 156 | .*crunch*.local.xml 157 | nCrunchTemp_* 158 | 159 | # MightyMoose 160 | *.mm.* 161 | AutoTest.Net/ 162 | 163 | # Web workbench (sass) 164 | .sass-cache/ 165 | 166 | # Installshield output folder 167 | [Ee]xpress/ 168 | 169 | # DocProject is a documentation generator add-in 170 | DocProject/buildhelp/ 171 | DocProject/Help/*.HxT 172 | DocProject/Help/*.HxC 173 | DocProject/Help/*.hhc 174 | DocProject/Help/*.hhk 175 | DocProject/Help/*.hhp 176 | DocProject/Help/Html2 177 | DocProject/Help/html 178 | 179 | # Click-Once directory 180 | publish/ 181 | 182 | # Publish Web Output 183 | *.[Pp]ublish.xml 184 | *.azurePubxml 185 | # Note: Comment the next line if you want to checkin your web deploy settings, 186 | # but database connection strings (with potential passwords) will be unencrypted 187 | *.pubxml 188 | *.publishproj 189 | 190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 191 | # checkin your Azure Web App publish settings, but sensitive information contained 192 | # in these scripts will be unencrypted 193 | PublishScripts/ 194 | 195 | # NuGet Packages 196 | *.nupkg 197 | # NuGet Symbol Packages 198 | *.snupkg 199 | # The packages folder can be ignored because of Package Restore 200 | **/[Pp]ackages/* 201 | # except build/, which is used as an MSBuild target. 202 | !**/[Pp]ackages/build/ 203 | # Uncomment if necessary however generally it will be regenerated when needed 204 | #!**/[Pp]ackages/repositories.config 205 | # NuGet v3's project.json files produces more ignorable files 206 | *.nuget.props 207 | *.nuget.targets 208 | 209 | # Microsoft Azure Build Output 210 | csx/ 211 | *.build.csdef 212 | 213 | # Microsoft Azure Emulator 214 | ecf/ 215 | rcf/ 216 | 217 | # Windows Store app package directories and files 218 | AppPackages/ 219 | BundleArtifacts/ 220 | Package.StoreAssociation.xml 221 | _pkginfo.txt 222 | *.appx 223 | *.appxbundle 224 | *.appxupload 225 | 226 | # Visual Studio cache files 227 | # files ending in .cache can be ignored 228 | *.[Cc]ache 229 | # but keep track of directories ending in .cache 230 | !?*.[Cc]ache/ 231 | 232 | # Others 233 | ClientBin/ 234 | ~$* 235 | *~ 236 | *.dbmdl 237 | *.dbproj.schemaview 238 | *.jfm 239 | *.pfx 240 | *.publishsettings 241 | orleans.codegen.cs 242 | 243 | # Including strong name files can present a security risk 244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 245 | #*.snk 246 | 247 | # Since there are multiple workflows, uncomment next line to ignore bower_components 248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 249 | #bower_components/ 250 | 251 | # RIA/Silverlight projects 252 | Generated_Code/ 253 | 254 | # Backup & report files from converting an old project file 255 | # to a newer Visual Studio version. Backup files are not needed, 256 | # because we have git ;-) 257 | _UpgradeReport_Files/ 258 | Backup*/ 259 | UpgradeLog*.XML 260 | UpgradeLog*.htm 261 | ServiceFabricBackup/ 262 | *.rptproj.bak 263 | 264 | # SQL Server files 265 | *.mdf 266 | *.ldf 267 | *.ndf 268 | 269 | # Business Intelligence projects 270 | *.rdl.data 271 | *.bim.layout 272 | *.bim_*.settings 273 | *.rptproj.rsuser 274 | *- [Bb]ackup.rdl 275 | *- [Bb]ackup ([0-9]).rdl 276 | *- [Bb]ackup ([0-9][0-9]).rdl 277 | 278 | # Microsoft Fakes 279 | FakesAssemblies/ 280 | 281 | # GhostDoc plugin setting file 282 | *.GhostDoc.xml 283 | 284 | # Node.js Tools for Visual Studio 285 | .ntvs_analysis.dat 286 | node_modules/ 287 | 288 | # Visual Studio 6 build log 289 | *.plg 290 | 291 | # Visual Studio 6 workspace options file 292 | *.opt 293 | 294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 295 | *.vbw 296 | 297 | # Visual Studio LightSwitch build output 298 | **/*.HTMLClient/GeneratedArtifacts 299 | **/*.DesktopClient/GeneratedArtifacts 300 | **/*.DesktopClient/ModelManifest.xml 301 | **/*.Server/GeneratedArtifacts 302 | **/*.Server/ModelManifest.xml 303 | _Pvt_Extensions 304 | 305 | # Paket dependency manager 306 | .paket/paket.exe 307 | paket-files/ 308 | 309 | # FAKE - F# Make 310 | .fake/ 311 | 312 | # CodeRush personal settings 313 | .cr/personal 314 | 315 | # Python Tools for Visual Studio (PTVS) 316 | __pycache__/ 317 | *.pyc 318 | 319 | # Cake - Uncomment if you are using it 320 | # tools/** 321 | # !tools/packages.config 322 | 323 | # Tabs Studio 324 | *.tss 325 | 326 | # Telerik's JustMock configuration file 327 | *.jmconfig 328 | 329 | # BizTalk build output 330 | *.btp.cs 331 | *.btm.cs 332 | *.odx.cs 333 | *.xsd.cs 334 | 335 | # OpenCover UI analysis results 336 | OpenCover/ 337 | 338 | # Azure Stream Analytics local run output 339 | ASALocalRun/ 340 | 341 | # MSBuild Binary and Structured Log 342 | *.binlog 343 | 344 | # NVidia Nsight GPU debugger configuration file 345 | *.nvuser 346 | 347 | # MFractors (Xamarin productivity tool) working folder 348 | .mfractor/ 349 | 350 | # Local History for Visual Studio 351 | .localhistory/ 352 | 353 | # BeatPulse healthcheck temp database 354 | healthchecksdb 355 | 356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 357 | MigrationBackup/ 358 | 359 | # Ionide (cross platform F# VS Code tools) working folder 360 | .ionide/ 361 | 362 | # Fody - auto-generated XML schema 363 | FodyWeavers.xsd -------------------------------------------------------------------------------- /WinParted/Partition/PartitionFormatPage.cpp: -------------------------------------------------------------------------------- 1 | #include "PartitionFormatPage.h" 2 | #include "..\CoreFunctions\PartitionManager.h" 3 | 4 | /* 5 | 6 | WinParted 1.2.0m12 7 | ======================== 8 | 9 | Partitioning Disk 0. (AMD-RAID Array) 10 | Modifying partition 0. (Microsoft Basic Data) 11 | 12 | Select the new filesystem type and name of the partition. 13 | 14 | * To select a filesystem type, use the UP and DOWN keys. 15 | * To switch to entering the name, press the TAB key. 16 | * To format the partition, press the ENTER key. 17 | 18 | ╔═════════╗ 19 | ║ FAT32 ║ 20 | ║ NTFS ║ 21 | ║ ExFAT ║ 22 | ╚═════════╝ 23 | 24 | Name: FileSystemNameBlaBla 25 | 26 | ████████████████████████████████████████████████████████████████████████████████ 27 | */ 28 | 29 | void PartitionFormatPage::InitPage() 30 | { 31 | SetStatusText(L"Querying supported filesystems..."); 32 | Draw(); 33 | 34 | wchar_t* fileSystems; 35 | PartitionManager::QueryPartitionSupportedFilesystems(&PartitionManager::CurrentPartition, &fileSystems); 36 | wlogf(PartitionManager::GetLogger(), PANTHER_LL_BASIC, 128, L"Found filesystems: %s", fileSystems); 37 | 38 | wchar_t* context; 39 | wchar_t* token = wcstok_s(fileSystems, L"|", &context); 40 | supportedFsCount = 0; 41 | while (token != NULL) 42 | { 43 | int tokenSize = lstrlenW(token); 44 | supportedFileSystems[supportedFsCount] = (wchar_t*)malloc(tokenSize + 1); 45 | if (!supportedFileSystems[supportedFsCount]) 46 | continue; 47 | wcscpy_s(supportedFileSystems[supportedFsCount++], tokenSize + 1, token); 48 | biggestFsName = max(biggestFsName, tokenSize); 49 | 50 | token = wcstok_s(NULL, L"|", &context); 51 | } 52 | SetStatusText(L""); 53 | } 54 | 55 | void PartitionFormatPage::DrawPage() 56 | { 57 | Console* console = GetConsole(); 58 | SIZE consoleSize = console->GetSize(); 59 | int bufferSize = consoleSize.cx + 1; 60 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 61 | 62 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 63 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 64 | 65 | console->SetPosition(3, 4); 66 | swprintf(buffer, bufferSize, L"Partitioning Disk %d. (%s)", PartitionManager::CurrentDisk.DiskNumber, PartitionManager::CurrentDisk.DeviceName); 67 | console->Write(buffer); 68 | if (PartitionManager::CurrentDiskPartitionsModified) 69 | console->Write(L" (partitions modified)"); 70 | 71 | console->SetForegroundColor(CONSOLE_COLOR_FG); 72 | console->SetPosition(3, console->GetPosition().y + 1); 73 | if (PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT) 74 | swprintf(buffer, bufferSize, L"Modifying Partition %d. (%s)", PartitionManager::CurrentPartition.PartitionNumber, PartitionManager::CurrentPartition.Name); 75 | else 76 | swprintf(buffer, bufferSize, L"Modifying Partition %d.", PartitionManager::CurrentPartition.PartitionNumber); 77 | console->Write(buffer); 78 | 79 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 80 | console->SetPosition(3, console->GetPosition().y + 2); 81 | console->Write(L"Select the new filesystem type and name of the partition."); 82 | console->SetForegroundColor(CONSOLE_COLOR_FG); 83 | 84 | console->SetPosition(6, console->GetPosition().y + 2); 85 | console->Write(L"\x2022 To select the desired filesystem type, use the UP and DOWN keys."); 86 | console->SetPosition(6, console->GetPosition().y + 1); 87 | console->Write(L"\x2022 To switch to entering the volume name, press the TAB key."); 88 | console->SetPosition(6, console->GetPosition().y + 1); 89 | console->Write(L"\x2022 To format the partition, press the ENTER key."); 90 | console->SetPosition(6, console->GetPosition().y + 1); 91 | console->Write(L"\x2022 To go back to the partition information screen, press ESC"); 92 | 93 | drawY = console->GetPosition().y + 2; 94 | } 95 | 96 | void PartitionFormatPage::UpdatePage() 97 | { 98 | Console* console = GetConsole(); 99 | SIZE consoleSize = console->GetSize(); 100 | 101 | unsigned long long bufferSize = consoleSize.cx + 1; 102 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 103 | 104 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 105 | console->SetForegroundColor(CONSOLE_COLOR_FG); 106 | 107 | int boxHeight = min(consoleSize.cy - drawY - 5, supportedFsCount + 2); 108 | console->DrawBox(3, drawY, biggestFsName + 6, boxHeight, true); 109 | 110 | maxItems = boxHeight - 2; 111 | for (int i = 0; i < maxItems; i++) 112 | { 113 | if (i == selectionIndex) 114 | { 115 | console->SetBackgroundColor(CONSOLE_COLOR_FG); 116 | console->SetForegroundColor(CONSOLE_COLOR_BG); 117 | } 118 | else 119 | { 120 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 121 | console->SetForegroundColor(CONSOLE_COLOR_FG); 122 | } 123 | 124 | int j = i + scrollIndex; 125 | if (j > supportedFsCount) break; 126 | 127 | swprintf_s(buffer, bufferSize, L"%s", supportedFileSystems[j]); 128 | 129 | console->SetPosition(6, drawY + 1 + i); 130 | console->Write(buffer); 131 | } 132 | 133 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 134 | console->SetForegroundColor(CONSOLE_COLOR_FG); 135 | 136 | console->DrawTextLeft(L"Name: ", consoleSize.cx - 6, drawY + boxHeight + 1); 137 | POINT p = console->GetPosition(); 138 | for (int i = 0; i <= 63; i++) 139 | console->Write(L" "); 140 | console->SetPosition(p.x, p.y); 141 | console->Write(nameString); 142 | if (enteringName) 143 | { 144 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 145 | console->Write(L"_"); 146 | } 147 | } 148 | 149 | void PartitionFormatPage::RunPage() 150 | { 151 | Console* console = GetConsole(); 152 | bool holdingShift; 153 | 154 | while (KEY_EVENT_RECORD* key = console->Read()) 155 | { 156 | if (key->wVirtualKeyCode >= VK_NUMPAD0 && key->wVirtualKeyCode <= VK_NUMPAD9) 157 | key->wVirtualKeyCode -= 0x30; 158 | 159 | bool number = key->wVirtualKeyCode >= '0' && key->wVirtualKeyCode <= '9'; 160 | bool letter = key->wVirtualKeyCode >= 'A' && key->wVirtualKeyCode <= 'Z'; 161 | 162 | if (letter && !(key->dwControlKeyState & SHIFT_PRESSED)) 163 | key->wVirtualKeyCode += 0x20; 164 | 165 | if (enteringName && (number || letter || key->wVirtualKeyCode == VK_SPACE)) 166 | { 167 | int index = lstrlenW(nameString); 168 | if (index == 63) 169 | break; 170 | nameString[index] = key->wVirtualKeyCode; 171 | nameString[index + 1] = 0; 172 | 173 | Update(); 174 | } 175 | else switch (key->wVirtualKeyCode) 176 | { 177 | case VK_BACK: 178 | { 179 | if (!enteringName) 180 | break; 181 | int index = lstrlenW(nameString); 182 | if (index == 0) break; 183 | nameString[index - 1] = 0; 184 | Update(); 185 | break; 186 | } 187 | case VK_TAB: 188 | enteringName = !enteringName; 189 | Update(); 190 | break; 191 | case VK_RETURN: 192 | { 193 | if (PartitionManager::ShowMessagePage(L"Warning: All data on the partition will be lost and a new file system will be created. Would you like to continue?", MessagePageType::YesNo, MessagePageUI::Warning) != MessagePageResult::Yes) 194 | break; 195 | 196 | SetStatusText(L"Formatting the partition..."); 197 | Update(); 198 | HRESULT hR = PartitionManager::FormatPartition(&PartitionManager::CurrentPartition, supportedFileSystems[selectionIndex + scrollIndex], nameString); 199 | if (hR != S_OK) 200 | { 201 | wchar_t buffer[MAX_PATH * 2]; 202 | swprintf_s(buffer, L"Could not format the partition: 0x%08X", hR); 203 | PartitionManager::ShowMessagePage(buffer, MessagePageType::OK, MessagePageUI::Error); 204 | } 205 | PartitionManager::LoadPartition(&PartitionManager::CurrentPartition); 206 | PartitionManager::PopPage(); 207 | return; 208 | } 209 | case VK_DOWN: 210 | if (enteringName) 211 | break; 212 | if (selectionIndex + 1 < min(maxItems, supportedFsCount)) 213 | selectionIndex++; 214 | else if (selectionIndex + scrollIndex + 1 < supportedFsCount) 215 | scrollIndex++; 216 | Update(); 217 | break; 218 | case VK_UP: 219 | if (enteringName) 220 | break; 221 | if (selectionIndex - 1 >= 0) 222 | selectionIndex--; 223 | else if (selectionIndex + scrollIndex - 1 >= 0) 224 | scrollIndex--; 225 | Update(); 226 | break; 227 | case VK_ESCAPE: 228 | PartitionManager::PopPage(); 229 | return; 230 | } 231 | } 232 | } 233 | -------------------------------------------------------------------------------- /WinParted/Partition/PartitionTypeSelectionPage.cpp: -------------------------------------------------------------------------------- 1 | #include "PartitionTypeSelectionPage.h" 2 | 3 | void PartitionTypeSelectionPage::InitPage() 4 | { 5 | SetStatusText(L""); 6 | 7 | scrollIndex = 0; 8 | selectionIndex = 0; 9 | 10 | LoadItems(false); 11 | 12 | for (int i = 0; i < 4; i++) enteredChars[i] = L'0'; 13 | enteredChars[4] = L'\0'; 14 | 15 | inputIndex = 0; 16 | inputSelected = false; 17 | } 18 | 19 | void PartitionTypeSelectionPage::DrawPage() 20 | { 21 | Console* console = GetConsole(); 22 | SIZE consoleSize = console->GetSize(); 23 | int bufferSize = consoleSize.cx + 1; 24 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 25 | 26 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 27 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 28 | console->SetPosition(3, 4); 29 | swprintf(buffer, bufferSize, L"Partitioning Disk %d. (%s)", PartitionManager::CurrentDisk.DiskNumber, PartitionManager::CurrentDisk.DeviceName); 30 | console->Write(buffer); 31 | if (PartitionManager::CurrentDiskPartitionsModified) 32 | console->Write(L" (partitions modified)"); 33 | 34 | console->SetForegroundColor(CONSOLE_COLOR_FG); 35 | console->SetPosition(3, console->GetPosition().y + 1); 36 | if (PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT) 37 | swprintf(buffer, bufferSize, L"Modifying Partition %d. (%s)", PartitionManager::CurrentPartition.PartitionNumber, PartitionManager::CurrentPartition.Name); 38 | else 39 | swprintf(buffer, bufferSize, L"Modifying Partition %d.", PartitionManager::CurrentPartition.PartitionNumber); 40 | console->Write(buffer); 41 | 42 | console->SetForegroundColor(CONSOLE_COLOR_LIGHTFG); 43 | console->SetPosition(3, console->GetPosition().y + 2); 44 | console->Write(L"Select the new type of the partition."); 45 | 46 | console->SetForegroundColor(CONSOLE_COLOR_FG); 47 | console->SetPosition(6, console->GetPosition().y + 2); 48 | console->Write(L"\x2022 To select a type use the UP and DOWN keys."); 49 | console->SetPosition(6, console->GetPosition().y + 1); 50 | console->Write(L"\x2022 To display all partition types, press F9."); 51 | console->SetPosition(6, console->GetPosition().y + 1); 52 | console->Write(L"\x2022 Alternatively, enter the type code below."); 53 | console->SetPosition(6, console->GetPosition().y + 1); 54 | console->Write(L"\x2022 To save the new type, press ENTER."); 55 | console->SetPosition(6, console->GetPosition().y + 1); 56 | console->Write(L"\x2022 To go back to the partition information screen, press ESC"); 57 | 58 | console->SetPosition(3, console->GetPosition().y + 2); 59 | console->Write(L"Type ID: "); 60 | textLocation = console->GetPosition(); 61 | 62 | boxY = console->GetPosition().y + 3; 63 | int boxHeight = consoleSize.cy - boxY - 2; 64 | console->DrawBox(3, boxY, consoleSize.cx - 6, boxHeight, true); 65 | maxItems = boxHeight - 3; 66 | 67 | console->SetPosition(6, boxY + 1); 68 | console->Write(PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT ? 69 | L"Type GUID Name Code" : 70 | L"Type Code Name"); 71 | 72 | free(buffer); 73 | } 74 | 75 | void PartitionTypeSelectionPage::UpdatePage() 76 | { 77 | Console* console = GetConsole(); 78 | SIZE consoleSize = console->GetSize(); 79 | int bufferSize = consoleSize.cx + 1; 80 | wchar_t* buffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 81 | wchar_t guidBuffer[37]; 82 | 83 | int selbufferSize = consoleSize.cx - 12 + 1; 84 | wchar_t* selbuffer = (wchar_t*)malloc(sizeof(wchar_t) * bufferSize); 85 | for (int i = 0; i < min(totalItems, maxItems); i++) 86 | { 87 | int j = i + scrollIndex; 88 | if (i == selectionIndex && !inputSelected) 89 | { 90 | console->SetBackgroundColor(CONSOLE_COLOR_FG); 91 | console->SetForegroundColor(CONSOLE_COLOR_BG); 92 | } 93 | else 94 | { 95 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 96 | console->SetForegroundColor(CONSOLE_COLOR_FG); 97 | } 98 | 99 | console->SetPosition(6, boxY + 2 + i); 100 | swprintf(selbuffer, selbufferSize, L"%-*s", selbufferSize - 1, L""); 101 | console->Write(selbuffer); 102 | console->SetPosition(6, boxY + 2 + i); 103 | if (PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT) 104 | { 105 | PartitionManager::GetGuidStringFromStructure(items[j].guid, guidBuffer); 106 | swprintf(selbuffer, selbufferSize, L"%s %-22.22s 0x%04hX", guidBuffer, 107 | items[j].display_name, items[j].gDiskType); 108 | } 109 | else 110 | swprintf(selbuffer, selbufferSize, L"0x%4hX %s", items[j].gDiskType, items[j].display_name); 111 | 112 | console->Write(selbuffer); 113 | } 114 | 115 | console->SetBackgroundColor(CONSOLE_COLOR_BG); 116 | console->SetForegroundColor(CONSOLE_COLOR_FG); 117 | 118 | buffer[1] = L'\x00'; 119 | console->SetPosition(textLocation.x, textLocation.y); 120 | for (int i = 0; i < 4; i++) 121 | { 122 | buffer[0] = i < inputIndex ? enteredChars[i] : L' '; 123 | console->Write(buffer); 124 | } 125 | 126 | console->SetPosition(0, textLocation.y + 1); 127 | for (int i = 0; i < bufferSize - 1; i++) 128 | buffer[i] = L' '; 129 | buffer[bufferSize - 1] = L'\0'; 130 | console->Write(buffer); 131 | 132 | if (inputIndex >= 2) 133 | { 134 | short value; 135 | if (swscanf_s(enteredChars, L"%hX", &value)) 136 | { 137 | console->SetPosition(3, textLocation.y + 1); 138 | console->Write(L"Detected type: "); 139 | console->Write(PartitionManager::GetStringFromPartitionTypeCode(value)); 140 | } 141 | } 142 | 143 | console->SetPosition(textLocation.x + inputIndex, textLocation.y); 144 | console->SetCursor(inputSelected, inputSelected); 145 | 146 | free(buffer); 147 | } 148 | 149 | void PartitionTypeSelectionPage::RunPage() 150 | { 151 | Console* console = GetConsole(); 152 | 153 | while (KEY_EVENT_RECORD* key = console->Read()) 154 | { 155 | switch (key->wVirtualKeyCode) 156 | { 157 | case VK_DOWN: 158 | if (inputSelected) 159 | inputSelected = false; 160 | else if (selectionIndex + 1 < min(maxItems, totalItems)) 161 | selectionIndex++; 162 | else if (selectionIndex + scrollIndex + 1 < totalItems) 163 | scrollIndex++; 164 | Update(); 165 | break; 166 | case VK_UP: 167 | if (selectionIndex + scrollIndex == 0) 168 | inputSelected = true; 169 | else if (selectionIndex - 1 >= 0) 170 | selectionIndex--; 171 | else if (selectionIndex + scrollIndex - 1 >= 0) 172 | scrollIndex--; 173 | Update(); 174 | break; 175 | case L'0': case L'1': case L'2': case L'3': 176 | case L'4': case L'5': case L'6': case L'7': 177 | case L'8': case L'9': case L'A': case L'B': 178 | case L'C': case L'D': case L'E': case L'F': 179 | if (inputSelected) 180 | { 181 | if (inputIndex < (PartitionManager::CurrentDiskOperatingMode == OperatingMode::MBR ? 2 : 4)) 182 | { 183 | enteredChars[inputIndex++] = key->wVirtualKeyCode; 184 | Update(); 185 | } 186 | } 187 | break; 188 | case VK_BACK: 189 | if (inputSelected) 190 | { 191 | if (inputIndex > 0) 192 | { 193 | enteredChars[--inputIndex] = L'0'; 194 | Update(); 195 | } 196 | } 197 | break; 198 | case VK_RETURN: 199 | { 200 | if (inputSelected) 201 | { 202 | if (inputIndex < 2) 203 | break; 204 | 205 | short value; 206 | if (!swscanf_s(enteredChars, L"%hX", &value)) 207 | break; 208 | 209 | const wchar_t* string = PartitionManager::GetStringFromPartitionTypeCode(value); 210 | if (!wcsncmp(string, L"Unknown type", 12)) 211 | break; 212 | 213 | PartitionManager::SetCurrentPartitionType(value); 214 | } 215 | else 216 | { 217 | PartitionManager::SetCurrentPartitionType(PartitionManager::GptTypes[selectionIndex + scrollIndex + 1].gDiskType); 218 | } 219 | } 220 | case VK_ESCAPE: 221 | PartitionManager::PopPage(); 222 | return; 223 | case VK_F3: 224 | PartitionManager::Exit(0); 225 | return; 226 | case VK_F9: 227 | LoadItems(!allItemsShown); 228 | Update(); 229 | break; 230 | } 231 | } 232 | } 233 | 234 | void PartitionTypeSelectionPage::LoadItems(bool showAll) 235 | { 236 | GUID zero = { 0 }; 237 | int i = 1; 238 | int j = 0; 239 | while (i < (showAll ? PartitionTypeCount : PartitionTypeCommonCount)) 240 | { 241 | PartitionType type = PartitionManager::GptTypes[i++]; 242 | if (PartitionManager::CurrentDiskOperatingMode == OperatingMode::GPT && !memcmp(&zero, &type.guid, sizeof(GUID))) 243 | continue; 244 | items[j++] = type; 245 | } 246 | 247 | totalItems = j; 248 | allItemsShown = showAll; 249 | selectionIndex = 0; 250 | scrollIndex = 0; 251 | } -------------------------------------------------------------------------------- /Panther2K/DiskSelectionPage.cpp: -------------------------------------------------------------------------------- 1 | #include "DiskSelectionPage.h" 2 | #include "WindowsSetup.h" 3 | #include "QuitingPage.h" 4 | #include "MessageBoxPage.h" 5 | 6 | void GetSizeStringFromBytes(unsigned long long bytes, wchar_t buffer[10]) 7 | { 8 | // Overkill 9 | bool useSI = false; 10 | double factor = useSI ? 1000.0 : 1024.0; 11 | const wchar_t valueStringsSI[9][4] = { L"B", L"KB", L"MB", L"GB", L"TB", L"PB", L"EB", L"ZB", L"YB" }; 12 | const wchar_t valueStringsBinary[9][4] = { L"B", L"KiB", L"MiB", L"GiB", L"TiB", L"PiB", L"EiB", L"ZiB", L"YiB" }; 13 | 14 | int index = 0; 15 | double bytesFp = bytes; 16 | while (bytesFp > factor && index < 9) 17 | { 18 | bytesFp /= factor; 19 | index++; 20 | } 21 | swprintf(buffer, 10, L"%.1f%s", bytesFp, useSI ? valueStringsSI[index] : valueStringsBinary[index]); 22 | } 23 | 24 | void DiskSelectionPage::Init() 25 | { 26 | wchar_t* displayName = WindowsSetup::WimImageInfos[WindowsSetup::WimImageIndex - 1].DisplayName; 27 | int length = lstrlenW(displayName); 28 | wchar_t* textBuffer = (wchar_t*)safeMalloc(WindowsSetup::GetLogger(), length * sizeof(wchar_t) + 14); 29 | memcpy(textBuffer, displayName, length * sizeof(wchar_t)); 30 | memcpy(textBuffer + length, L" Setup", 14); 31 | text = textBuffer; 32 | statusText = L" ENTER=Select ESC=Back F3=Quit"; 33 | 34 | HANDLE diskFileHandle; 35 | DWORD byteCount; 36 | DISK_GEOMETRY dg; 37 | STORAGE_PROPERTY_QUERY spq; 38 | STORAGE_DEVICE_DESCRIPTOR sdd; 39 | PSTORAGE_DEVICE_DESCRIPTOR psdd; 40 | wchar_t buffer[256]; 41 | 42 | if (diskInfo != NULL) 43 | free(diskInfo); 44 | 45 | wchar_t* dosdevs = (wchar_t*)safeMalloc(WindowsSetup::GetLogger(), sizeof(wchar_t*) * 65536); 46 | 47 | QueryDosDeviceW(NULL, dosdevs, 65536); 48 | diskCount = 0; 49 | for (wchar_t* pos = dosdevs; *pos; pos += lstrlenW(pos) + 1) 50 | if (wcsncmp(pos, L"PhysicalDrive", 13) == 0) 51 | diskCount++; 52 | 53 | diskInfo = (DISK_INFO*)safeMalloc(WindowsSetup::GetLogger(), sizeof(DISK_INFO) * diskCount); 54 | 55 | int i = 0; 56 | for (wchar_t* pos = dosdevs; *pos; pos += lstrlenW(pos) + 1) 57 | { 58 | if (wcsncmp(pos, L"PhysicalDrive", 13) == 0) 59 | { 60 | diskInfo[i].diskNumber = wcstol(pos + 13, NULL, 10); 61 | 62 | swprintf_s(buffer, L"\\\\.\\\PHYSICALDRIVE%d", diskInfo[i].diskNumber); 63 | diskFileHandle = CreateFileW(buffer, FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE | FILE_TRAVERSE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); 64 | if (diskFileHandle == INVALID_HANDLE_VALUE) 65 | { 66 | if (GetLastError() == 5) 67 | { 68 | MessageBoxPage* msgBox = new MessageBoxPage(L"Failed to enumerate disks: Access denied. Please re-run Panther2K as Administrator. Panther2K will exit.", true, this); 69 | msgBox->ShowDialog(); 70 | delete msgBox; 71 | WindowsSetup::RequestExit(); 72 | return; 73 | } 74 | else 75 | { 76 | diskCount--; 77 | continue; 78 | } 79 | } 80 | 81 | if (!DeviceIoControl(diskFileHandle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0, &dg, sizeof(dg), &byteCount, NULL)) 82 | { 83 | diskCount--; 84 | goto clean; 85 | } 86 | 87 | // IOCTL_STORAGE_QUERY_PROPERTY 88 | // Determines the name of the disk 89 | // See: https://docs.microsoft.com/en-us/windows/win32/api/winioctl/ne-winioctl-storage_property_id 90 | spq.PropertyId = StorageDeviceProperty; 91 | spq.QueryType = PropertyStandardQuery; 92 | if (!DeviceIoControl(diskFileHandle, IOCTL_STORAGE_QUERY_PROPERTY, &spq, sizeof(spq), &sdd, sizeof(sdd), &byteCount, NULL) && GetLastError() != ERROR_INSUFFICIENT_BUFFER) 93 | { 94 | diskCount--; 95 | goto clean; 96 | } 97 | psdd = (STORAGE_DEVICE_DESCRIPTOR*)malloc(sdd.Size); 98 | if (psdd == NULL || !DeviceIoControl(diskFileHandle, IOCTL_STORAGE_QUERY_PROPERTY, &spq, sizeof(spq), psdd, sdd.Size, &byteCount, NULL)) 99 | { 100 | diskCount--; 101 | goto clean; 102 | } 103 | 104 | // Concatenate vendor id + product id 105 | // Convert the name into a wide string 106 | { 107 | wchar_t* destPtr = diskInfo[i].name; 108 | int sizeOfSrcString = strlen((char*)psdd + psdd->VendorIdOffset); 109 | int sizeOfDestString = 260; 110 | char* srcPtr = (char*)psdd + psdd->VendorIdOffset; 111 | size_t count = _TRUNCATE; 112 | size_t bytesWritten; 113 | 114 | if (sizeOfSrcString > 0) 115 | { 116 | mbstowcs_s(&bytesWritten, destPtr, sizeOfDestString, srcPtr, count); 117 | diskInfo[i].name[bytesWritten - 1] = L' '; 118 | } 119 | 120 | destPtr = diskInfo[i].name + bytesWritten; 121 | sizeOfSrcString = strlen((char*)psdd + psdd->ProductIdOffset); 122 | sizeOfDestString = 256 - bytesWritten; 123 | srcPtr = (char*)psdd + psdd->ProductIdOffset; 124 | mbstowcs_s(&bytesWritten, destPtr, sizeOfDestString, srcPtr, count); 125 | 126 | wchar_t* temp = CleanString(diskInfo[i].name); 127 | if (temp) 128 | { 129 | lstrcpyW(diskInfo[i].name, temp); 130 | free(temp); 131 | } 132 | } 133 | 134 | diskInfo[i].size = dg.Cylinders.QuadPart * dg.TracksPerCylinder * dg.SectorsPerTrack * dg.BytesPerSector; 135 | diskInfo[i].mediaType = dg.MediaType; 136 | 137 | clean: 138 | CloseHandle(diskFileHandle); 139 | i++; 140 | } 141 | } 142 | } 143 | 144 | void DiskSelectionPage::Drawer() 145 | { 146 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 147 | console->SetForegroundColor(WindowsSetup::LightForegroundColor); 148 | 149 | DrawTextLeft(L"Select the disk to install Windows to.", console->GetSize().cx - 6, 4); 150 | 151 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 152 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 153 | 154 | DrawTextLeft(L"Windows will be installed to the disk specified. All data on the disk will be destroyed and Panther2K will create a bootable Windows installation on the disk. To install Windows without wiping a disk or while using a custom partition layout, select \"Custom\"", console->GetSize().cx - 6, console->GetPosition().y + 2); 155 | 156 | DrawTextLeft(L"Use the UP and DOWN ARROW keys to select the disk.", console->GetSize().cx - 6, console->GetPosition().y + 2); 157 | 158 | int boxX = 3; 159 | boxY = console->GetPosition().y + 2; 160 | int boxWidth = console->GetSize().cx - 6; 161 | int boxHeight = console->GetSize().cy - (boxY + 2); 162 | DrawBox(boxX, boxY, boxWidth, boxHeight, true); 163 | 164 | wchar_t* buffer = (wchar_t*)safeMalloc(WindowsSetup::GetLogger(), sizeof(wchar_t) * (boxWidth - 2)); 165 | swprintf(buffer, boxWidth - 2, L" Disk Device Name %*sType Disk size ", boxWidth - 68, L""); 166 | console->SetPosition(boxX + 1, boxY + 1); 167 | console->Write(buffer); 168 | free(buffer); 169 | } 170 | 171 | void DiskSelectionPage::Redrawer() 172 | { 173 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 174 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 175 | 176 | int boxX = 3; 177 | int boxWidth = console->GetSize().cx - 6; 178 | int boxHeight = console->GetSize().cy - (boxY + 2); 179 | int maxItems = boxHeight - 3; 180 | 181 | bool canScrollDown = (scrollIndex + maxItems) < WindowsSetup::WimImageCount; 182 | bool canScrollUp = scrollIndex != 0; 183 | 184 | wchar_t* buffer = (wchar_t*)safeMalloc(WindowsSetup::GetLogger(), sizeof(wchar_t) * (boxWidth - 2)); 185 | wchar_t sizeBuffer[10]; 186 | for (int i = 0; i < min(diskCount + 1, maxItems); i++) 187 | { 188 | if (i == selectionIndex) 189 | { 190 | console->SetBackgroundColor(WindowsSetup::ForegroundColor); 191 | console->SetForegroundColor(WindowsSetup::BackgroundColor); 192 | } 193 | else 194 | { 195 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 196 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 197 | } 198 | 199 | console->SetPosition(boxX + 4, boxY + i + 2); 200 | 201 | if (i == diskCount) { 202 | swprintf_s(buffer, boxWidth - 2, L" Custom...%*s", boxWidth - 19, L""); 203 | } 204 | else { 205 | GetSizeStringFromBytes(diskInfo[i].size, sizeBuffer); 206 | swprintf_s(buffer, boxWidth - 2, L"%4d %-*s %-8s %-9s", diskInfo[i].diskNumber, boxWidth - 35, diskInfo[i].name, L"Standard", sizeBuffer); 207 | } 208 | 209 | console->Write(buffer); 210 | } 211 | free(buffer); 212 | } 213 | 214 | bool DiskSelectionPage::KeyHandler(WPARAM wParam) 215 | { 216 | int boxX = 3; 217 | int boxWidth = console->GetSize().cx - 6; 218 | int boxHeight = console->GetSize().cy - (boxY + 2); 219 | int maxItems = boxHeight - 3; 220 | switch (wParam) 221 | { 222 | case VK_DOWN: 223 | if (selectionIndex + 1 < min(maxItems, diskCount + 1)) 224 | selectionIndex++; 225 | else if (selectionIndex + scrollIndex + 1 < diskCount + 1) 226 | scrollIndex++; 227 | Redraw(); 228 | break; 229 | case VK_UP: 230 | if (selectionIndex - 1 >= 0) 231 | selectionIndex--; 232 | else if (selectionIndex + scrollIndex - 1 >= 0) 233 | scrollIndex--; 234 | Redraw(); 235 | break; 236 | case VK_ESCAPE: 237 | WindowsSetup::LoadPhase(3); 238 | break; 239 | case VK_RETURN: 240 | if (selectionIndex == diskCount) 241 | WindowsSetup::SelectNextPartition(0); 242 | else 243 | { 244 | if (WindowsSetup::SelectPartitionsWithDisk(diskInfo[selectionIndex].diskNumber)) 245 | WindowsSetup::LoadPhase(5); 246 | } 247 | break; 248 | case VK_F3: 249 | AddPopup(new QuitingPage()); 250 | break; 251 | } 252 | return true; 253 | } 254 | -------------------------------------------------------------------------------- /Panther2K/WimApplyPage.cpp: -------------------------------------------------------------------------------- 1 | #include "WimApplyPage.h" 2 | #include "WindowsSetup.h" 3 | #include 4 | #include 5 | #include "MessageBoxPage.h" 6 | 7 | #define WM_PROGRESSUPDATE WM_APP 8 | #define WM_FILENAMEUPDATE WM_APP + 1 9 | #define WM_FINISHUPDATE WM_APP + 2 10 | 11 | int hResult = 0; 12 | bool runMessageLoop = true; 13 | bool canSendProgress = true; 14 | bool canSendFileName = true; 15 | unsigned int progress = 0; 16 | LibPanther::Logger* installLog = nullptr; 17 | 18 | void WriteToFile(const wchar_t* string) 19 | { 20 | DWORD bytes; 21 | if (!installLog) 22 | { 23 | wchar_t buffer[MAX_PATH]; 24 | swprintf_s(buffer, L"%s%s", WindowsSetup::SystemPartition.mountPoint, L"panther2k.log"); 25 | installLog = new LibPanther::Logger(buffer, PANTHER_LL_VERBOSE); 26 | 27 | WriteToFile(L"Starting Panther2K installation log..."); 28 | swprintf_s(buffer, L" Installing %s to %s.", 29 | WindowsSetup::WimImageInfos[WindowsSetup::WimImageIndex - 1].DisplayName, 30 | WindowsSetup::SystemPartition.name); 31 | WriteToFile(buffer); 32 | swprintf_s(buffer, L" Total installation size: %llu bytes", WindowsSetup::WimImageInfos[WindowsSetup::WimImageIndex - 1].TotalSize); 33 | } 34 | 35 | if (string) 36 | { 37 | WindowsSetup::GetLogger()->Write(PANTHER_LL_BASIC, string); 38 | installLog->Write(PANTHER_LL_BASIC, string); 39 | } 40 | } 41 | 42 | DWORD __stdcall MessageCallback(IN DWORD Msg, IN WPARAM wParam, IN LPARAM lParam, IN PDWORD dwThreadId) 43 | { 44 | wchar_t buffer[MAX_PATH * 2]; 45 | switch (Msg) 46 | { 47 | case WIM_MSG_PROGRESS: 48 | swprintf_s(buffer, L"Installation progress: %lld%%", wParam); 49 | WriteToFile(buffer); 50 | PostThreadMessageW(*dwThreadId, WM_PROGRESSUPDATE, wParam, 0); 51 | break; 52 | case WIM_MSG_PROCESS: 53 | if (WindowsSetup::ShowFileNames && canSendFileName) 54 | if (PostThreadMessageW(*dwThreadId, WM_FILENAMEUPDATE, wParam, lParam)) 55 | canSendFileName = false; 56 | break; 57 | case WIM_MSG_INFO: 58 | { 59 | wchar_t messageBuffer[MAX_PATH]; 60 | FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lParam, NULL, messageBuffer, MAX_PATH, NULL); 61 | swprintf_s(buffer, L"System message (File %s): %s", (wchar_t*)wParam, messageBuffer); 62 | WriteToFile(buffer); 63 | break; 64 | } 65 | case WIM_MSG_ERROR: 66 | { 67 | wchar_t messageBuffer[MAX_PATH]; 68 | FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lParam, NULL, messageBuffer, MAX_PATH, NULL); 69 | swprintf_s(buffer, L"Error (File %s): %s", (wchar_t*)wParam, messageBuffer); 70 | WriteToFile(buffer); 71 | break; 72 | } 73 | case WIM_MSG_WARNING: 74 | { 75 | wchar_t messageBuffer[MAX_PATH]; 76 | FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lParam, NULL, messageBuffer, MAX_PATH, NULL); 77 | swprintf_s(buffer, L"Warning (File %s): %s", (wchar_t*)wParam, messageBuffer); 78 | WriteToFile(buffer); 79 | break; 80 | } 81 | case WIM_MSG_TEXT: 82 | swprintf_s(buffer, L"%s\n", (wchar_t*)lParam); 83 | WriteToFile(buffer); 84 | break; 85 | case WIM_MSG_SETRANGE: 86 | swprintf_s(buffer, L" Total number of files to be applied: %lld.", lParam); 87 | WriteToFile(buffer); 88 | WriteToFile(L"Starting Windows installation..."); 89 | break; 90 | case WIM_MSG_SETPOS: 91 | swprintf_s(buffer, L"Number of files applied: %lld.", lParam); 92 | WriteToFile(buffer); 93 | break; 94 | case WIM_MSG_QUERY_ABORT: 95 | WriteToFile(L"Abort opportunity given, but not aborting."); 96 | break; 97 | case WIM_MSG_METADATA_EXCLUDE: 98 | case WIM_MSG_STEPIT: 99 | case WIM_MSG_STEPNAME: 100 | break; 101 | default: 102 | swprintf_s(buffer, L"Unknown message: %d.", Msg); 103 | WriteToFile(buffer); 104 | break; 105 | } 106 | return WIM_MSG_SUCCESS; 107 | } 108 | 109 | void __stdcall WimApplyThread(PDWORD dwThreadId) 110 | { 111 | WIMRegisterMessageCallback(WindowsSetup::WimHandle, (FARPROC)MessageCallback, dwThreadId); 112 | HANDLE him = WIMLoadImage(WindowsSetup::WimHandle, WindowsSetup::WimImageIndex); 113 | BOOL result = WIMApplyImage(him, WindowsSetup::SystemPartition.mountPoint, WIM_FLAG_INDEX); 114 | hResult = GetLastError(); 115 | WIMUnregisterMessageCallback(WindowsSetup::WimHandle, (FARPROC)MessageCallback); 116 | runMessageLoop = false; 117 | PostThreadMessageW(*dwThreadId, WM_FINISHUPDATE, 0, 0); 118 | } 119 | 120 | void WimApplyPage::WimMessageLoop() 121 | { 122 | MSG msg; 123 | int progress = 0; 124 | wchar_t* filename = 0; 125 | runMessageLoop = true; 126 | 127 | while (GetMessageW(&msg, nullptr, WM_PROGRESSUPDATE, WM_FINISHUPDATE) && runMessageLoop) 128 | { 129 | switch (msg.message) 130 | { 131 | case WM_PROGRESSUPDATE: 132 | Update(msg.wParam); 133 | break; 134 | case WM_FILENAMEUPDATE: 135 | Update((wchar_t*)msg.wParam); 136 | break; 137 | case WM_FINISHUPDATE: 138 | runMessageLoop = false; 139 | break; 140 | } 141 | 142 | TranslateMessage(&msg); 143 | DispatchMessageW(&msg); 144 | Sleep(25); 145 | canSendFileName = true; 146 | } 147 | 148 | if (hResult) 149 | { 150 | MessageBoxPage* msgBox = new MessageBoxPage(L"The installation has failed. See the installation log for more details.", true, this); 151 | msgBox->ShowDialog(); 152 | delete msgBox; 153 | WindowsSetup::RequestExit(); 154 | } 155 | 156 | end: 157 | return; 158 | } 159 | 160 | WimApplyPage::~WimApplyPage() 161 | { 162 | free((wchar_t*)text); 163 | } 164 | 165 | void WimApplyPage::Update(int prog) 166 | { 167 | progress = prog; 168 | Redraw(); 169 | } 170 | 171 | LPTSTR PathFindFileName( 172 | LPTSTR pPath) 173 | { 174 | LPTSTR pT; 175 | 176 | for (pT = pPath; *pPath; pPath++) { 177 | if ((pPath[0] == TEXT('\\') || pPath[0] == TEXT(':') || pPath[0] == TEXT('/')) 178 | && pPath[1] && pPath[1] != TEXT('\\') && pPath[1] != TEXT('/')) 179 | pT = pPath + 1; 180 | } 181 | 182 | return pT; 183 | } 184 | 185 | void WimApplyPage::Update(wchar_t* fileName) 186 | { 187 | int length = console->GetSize().cx; 188 | int bufferSize = length + 1; 189 | int nameX = length - 25; 190 | /// | Copying: 12345678.123 191 | 192 | wmemset((wchar_t*)statusText, L' ', bufferSize); 193 | wmemcpy_s((wchar_t*)statusText, bufferSize, L" Panther2K is installing Windows...", 36); 194 | 195 | if (fileName) 196 | { 197 | wchar_t buffer[24]; 198 | fileName = PathFindFileName(fileName); 199 | swprintf_s(buffer, L"│ Copying: %.12s", fileName + (lstrlenW(fileName) - 12)); 200 | wmemcpy_s((wchar_t*)statusText + nameX, bufferSize - nameX, buffer, 24); 201 | } 202 | else 203 | { 204 | ((wchar_t*)statusText)[36] = L'\x0'; 205 | } 206 | 207 | ((wchar_t*)statusText)[length] = L'\x0'; 208 | _ASSERT(lstrlenW(statusText) <= length); 209 | Redraw(); 210 | } 211 | 212 | void WimApplyPage::ApplyImage() 213 | { 214 | DWORD bytesCopied; 215 | wchar_t fileBuffer[1024]; 216 | ULONGLONG ticksBefore = GetTickCount64(); 217 | 218 | DWORD dwThreadId = GetCurrentThreadId(); 219 | CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)WimApplyThread, &dwThreadId, 0, 0); 220 | WimMessageLoop(); 221 | 222 | ULONGLONG ticksAfter = GetTickCount64(); 223 | ULONGLONG ticksSpent = ticksAfter - ticksBefore; 224 | 225 | swprintf_s(fileBuffer, L"The installation has finished.\nInstallation time: %02llum:%02llus\nResult: 0x%08X\n", (ticksSpent / 1000) / 60, (ticksSpent / 1000) % 60, hResult); 226 | WriteToFile(fileBuffer); 227 | } 228 | 229 | void WimApplyPage::Init() 230 | { 231 | wchar_t* displayName = WindowsSetup::WimImageInfos[WindowsSetup::WimImageIndex - 1].DisplayName; 232 | int length = lstrlenW(displayName); 233 | wchar_t* textBuffer = (wchar_t*)safeMalloc(WindowsSetup::GetLogger(), length * sizeof(wchar_t) + 14); 234 | memcpy(textBuffer, displayName, length * sizeof(wchar_t)); 235 | memcpy(textBuffer + length, L" Setup", 14); 236 | text = textBuffer; 237 | statusText = (wchar_t*)safeMalloc(WindowsSetup::GetLogger(), sizeof(wchar_t) * (console->GetSize().cx + 1)); 238 | memcpy(((wchar_t*)statusText), L" Panther2K is installing Windows...", 37 * sizeof(wchar_t)); 239 | } 240 | 241 | void WimApplyPage::Drawer() 242 | { 243 | SIZE consoleSize = console->GetSize(); 244 | 245 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 246 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 247 | 248 | console->DrawTextCenter(L"Please wait while Setup copies files to the Windows installation folders. This might take several minutes to complete.", consoleSize.cx / 3 * 2, 6); 249 | 250 | int boxWidth = consoleSize.cx - 12; 251 | int boxHeight = 7; 252 | int boxX = 6; 253 | int boxY = consoleSize.cy / 2 - 1; 254 | DrawBox(boxX, boxY, boxWidth, boxHeight, true); 255 | console->SetPosition(boxX + 2, boxY + 1); 256 | console->Write(L"Setup is copying files..."); 257 | boxX += 6; 258 | boxY += 3; 259 | boxWidth -= 12; 260 | boxHeight -= 4; 261 | DrawBox(boxX, boxY, boxWidth, boxHeight, false); 262 | } 263 | 264 | void WimApplyPage::Redrawer() 265 | { 266 | console->SetBackgroundColor(WindowsSetup::BackgroundColor); 267 | console->SetForegroundColor(WindowsSetup::ForegroundColor); 268 | 269 | SIZE consoleSize = console->GetSize(); 270 | int boxWidth = consoleSize.cx - 12; 271 | int boxX = 6; 272 | int boxY = consoleSize.cy / 2 - 1; 273 | 274 | wchar_t buffer[5]; 275 | swprintf(buffer, 5, L"%i%%", progress); 276 | console->SetPosition(boxX + ((boxWidth / 2) - (4 / 2)), boxY + 2); 277 | console->Write(buffer); 278 | 279 | boxX += 6; 280 | boxY += 3; 281 | boxWidth -= 12; 282 | 283 | console->SetPosition(boxX + 1, boxY + 1); 284 | int progWidth = boxWidth - 2; 285 | int interpolatedProgress = progress * progWidth / 100; 286 | console->SetForegroundColor(WindowsSetup::ProgressBarColor); 287 | for (int i = 0; i < interpolatedProgress; i++) 288 | console->Write(WindowsSetup::UseCp437 ? L"\xDB" : L"█"); 289 | for (int i = interpolatedProgress; i < progWidth; i++) 290 | console->Write(L" "); 291 | } 292 | 293 | bool WimApplyPage::KeyHandler(WPARAM wParam) 294 | { 295 | return true; 296 | } 297 | -------------------------------------------------------------------------------- /P2KConsole/P2KConsole.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {a3dd51ce-63ab-4189-9d8a-3111288a3463} 25 | LibPanther 26 | 10.0 27 | LibPanther 28 | 29 | 30 | 31 | StaticLibrary 32 | true 33 | v143 34 | Unicode 35 | 36 | 37 | StaticLibrary 38 | false 39 | v143 40 | true 41 | Unicode 42 | 43 | 44 | StaticLibrary 45 | true 46 | v143 47 | Unicode 48 | 49 | 50 | StaticLibrary 51 | false 52 | v143 53 | true 54 | Unicode 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | $(ProjectDir)bin\$(Platform)\$(Configuration)\ 77 | $(ProjectDir)obj\$(Platform)\$(Configuration)\ 78 | 79 | 80 | false 81 | $(ProjectDir)bin\$(Platform)\$(Configuration)\ 82 | $(ProjectDir)obj\$(Platform)\$(Configuration)\ 83 | 84 | 85 | true 86 | $(ProjectDir)bin\$(Platform)\$(Configuration)\ 87 | $(ProjectDir)obj\$(Platform)\$(Configuration)\ 88 | 89 | 90 | false 91 | $(ProjectDir)bin\$(Platform)\$(Configuration)\ 92 | $(ProjectDir)obj\$(Platform)\$(Configuration)\ 93 | 94 | 95 | 96 | Level3 97 | true 98 | WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) 99 | true 100 | Use 101 | pch.h 102 | MultiThreadedDebug 103 | 104 | 105 | 106 | 107 | true 108 | 109 | 110 | 111 | 112 | Level3 113 | true 114 | true 115 | true 116 | WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) 117 | true 118 | Use 119 | pch.h 120 | MultiThreaded 121 | 122 | 123 | 124 | 125 | true 126 | true 127 | true 128 | 129 | 130 | 131 | 132 | Level3 133 | true 134 | _DEBUG;_LIB;%(PreprocessorDefinitions) 135 | true 136 | Use 137 | pch.h 138 | MultiThreadedDebug 139 | 140 | 141 | 142 | 143 | true 144 | 145 | 146 | 147 | 148 | Level3 149 | true 150 | true 151 | true 152 | NDEBUG;_LIB;%(PreprocessorDefinitions) 153 | true 154 | Use 155 | pch.h 156 | MultiThreaded 157 | 158 | 159 | 160 | 161 | true 162 | true 163 | true 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | true 172 | true 173 | true 174 | true 175 | 176 | 177 | true 178 | true 179 | true 180 | true 181 | 182 | 183 | true 184 | true 185 | true 186 | true 187 | 188 | 189 | true 190 | true 191 | 192 | 193 | true 194 | 195 | 196 | true 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | Create 209 | Create 210 | Create 211 | Create 212 | 213 | 214 | 215 | 216 | 217 | 218 | -------------------------------------------------------------------------------- /WinParted/CoreFunctions/DllExports.cpp: -------------------------------------------------------------------------------- 1 | #include "PartitionManager.h" 2 | #include 3 | #include 4 | 5 | // TODO: Make all exports return HRESULT codes 6 | 7 | EXTERN_C BOOL WINAPI _CRT_INIT(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved); 8 | extern "C" void _stdcall InitializeCRT() 9 | { 10 | HINSTANCE instance = GetModuleHandleA("WinParted.exe"); 11 | _CRT_INIT(instance, DLL_PROCESS_ATTACH, NULL); 12 | }; 13 | 14 | extern "C" int _stdcall RunWinParted(Console* console, LibPanther::Logger* logger) 15 | { 16 | PartitionManager::SetLogger(logger); 17 | int result = PartitionManager::RunWinParted(console); 18 | return result; 19 | }; 20 | 21 | // TODO: Cleanup this mess 22 | // TODO: Merge GPT and MBR into a single function with a flag 23 | // TODO: Move partition layout information to Panther2K 24 | extern "C" HRESULT _stdcall ApplyP2KLayoutToDiskGPT(Console* console, LibPanther::Logger* logger, int diskNumber, bool letters, wchar_t*** mountPath, wchar_t*** volumeList) 25 | { 26 | HRESULT ret; 27 | HRESULT hResult; 28 | int volIndex = 0; 29 | int totalPartitions = 0; 30 | long structSize = 0; 31 | WP_PART_LAYOUT* layout = nullptr; 32 | 33 | PartitionManager::ShowNoInfoDialogs = true; 34 | PartitionManager::SetConsole(console); 35 | PartitionManager::SetLogger(logger); 36 | 37 | // Show loading screen 38 | PartitionManager::CurrentPage = new Page(); 39 | PartitionManager::CurrentPage->Initialize(console); 40 | PartitionManager::CurrentPage->Update(); 41 | 42 | if (PartitionManager::ShowMessagePage(L"Warning: All data on the drive will be lost and a new partition table will be written. Would you like to continue?", MessagePageType::YesNo, MessagePageUI::Warning) != MessagePageResult::Yes) 43 | { 44 | ret = ERROR_CANCELLED; 45 | goto exit; 46 | } 47 | 48 | PartitionManager::PopulateDiskInformation(); 49 | PartitionManager::CurrentDisk.DiskNumber = -1; 50 | for (int i = 0; i < PartitionManager::DiskInformationTableSize; i++) 51 | if (PartitionManager::DiskInformationTable[i].DiskNumber == diskNumber) 52 | PartitionManager::CurrentDisk = PartitionManager::DiskInformationTable[diskNumber]; 53 | if (PartitionManager::CurrentDisk.DiskNumber == -1) 54 | { 55 | ret = ERROR_FILE_NOT_FOUND; 56 | goto exit; 57 | } 58 | 59 | wchar_t rootCwdPath[MAX_PATH]; 60 | if (_wgetcwd(rootCwdPath, MAX_PATH) == NULL) 61 | { 62 | ret = ERROR_PATH_NOT_FOUND; 63 | goto exit; 64 | } 65 | 66 | PathStripToRootW(rootCwdPath); 67 | 68 | for (int i = 0; i < 3; i++) 69 | { 70 | wcscpy_s((*mountPath)[i], MAX_PATH, rootCwdPath); 71 | } 72 | 73 | if (letters) 74 | { 75 | int mountIndex = 0; 76 | DWORD drives = GetLogicalDrives(); 77 | const wchar_t* letters = L"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 78 | for (int i = 25; i >= 0 && mountIndex < 3; i--) 79 | { 80 | if (drives ^ 0b10000000000000000000000000 81 | && letters[i] != L'X' 82 | && letters[i] != L'A' 83 | && letters[i] != L'B') 84 | { 85 | (*mountPath)[mountIndex][0] = letters[i]; 86 | (*mountPath)[mountIndex++][1] = L'\0'; 87 | } 88 | drives <<= 1; 89 | } 90 | 91 | if (mountIndex != 3) 92 | { 93 | ret = ERROR_BUSY; 94 | goto exit; 95 | } 96 | } 97 | else 98 | { 99 | wcscat_s((*mountPath)[0], MAX_PATH, L"$Panther2K\\Sys\\"); 100 | wcscat_s((*mountPath)[1], MAX_PATH, L"$Panther2K\\Win\\"); 101 | wcscat_s((*mountPath)[2], MAX_PATH, L"$Panther2K\\Rec\\"); 102 | 103 | for (int i = 0; i < 3; i++) 104 | { 105 | hResult = SHCreateDirectoryExW(NULL, (*mountPath)[i], NULL); 106 | if (hResult != ERROR_SUCCESS && hResult != ERROR_ALREADY_EXISTS) 107 | { 108 | ret = hResult; 109 | goto exit; 110 | } 111 | } 112 | } 113 | 114 | // TODO: Move this to Panther2K 115 | totalPartitions = 4; 116 | structSize = (sizeof(WP_PART_LAYOUT) + ((totalPartitions - 1) * sizeof(WP_PART_DESCRIPTION))); 117 | layout = (WP_PART_LAYOUT*)safeMalloc(logger, structSize); 118 | ZeroMemory(layout, structSize); 119 | layout->PartitionCount = totalPartitions; 120 | 121 | layout->Partitions[0].PartitionNumber = 1; 122 | layout->Partitions[0].PartitionType = 0x0700; 123 | if (PartitionManager::CurrentDisk.SectorSize == 4096) 124 | wcscpy_s(layout->Partitions[0].PartitionSize, L"300M"); 125 | else 126 | wcscpy_s(layout->Partitions[0].PartitionSize, L"150M"); 127 | wcscpy_s(layout->Partitions[0].FileSystem, L"FAT32"); 128 | layout->Partitions[0].MountPoint = (*mountPath)[0]; 129 | 130 | layout->Partitions[1].PartitionNumber = 2; 131 | layout->Partitions[1].PartitionType = 0x0C01; 132 | wcscpy_s(layout->Partitions[1].PartitionSize, L"16M"); 133 | wcscpy_s(layout->Partitions[1].FileSystem, L"RAW"); 134 | 135 | layout->Partitions[2].PartitionNumber = 1; 136 | layout->Partitions[2].PartitionType = 0x0700; 137 | wcscpy_s(layout->Partitions[2].PartitionSize, L"100%"); 138 | wcscpy_s(layout->Partitions[2].FileSystem, L"NTFS"); 139 | layout->Partitions[2].MountPoint = (*mountPath)[1]; 140 | 141 | layout->Partitions[3].PartitionNumber = 1; 142 | layout->Partitions[3].PartitionType = 0x0700; 143 | wcscpy_s(layout->Partitions[3].PartitionSize, L"500M"); 144 | wcscpy_s(layout->Partitions[3].FileSystem, L"NTFS"); 145 | layout->Partitions[3].MountPoint = (*mountPath)[2]; 146 | 147 | ret = PartitionManager::ApplyPartitionLayoutGPT(layout); 148 | for (int i = 0; i < 4; i++) 149 | { 150 | if (i == 1) continue; 151 | PartitionManager::LoadPartition(&PartitionManager::CurrentDiskPartitions[i]); 152 | lstrcpyW((*volumeList)[volIndex++], PartitionManager::CurrentPartition.VolumeInformation.VolumeFile); 153 | } 154 | free(layout); 155 | exit: 156 | PartitionManager::ShowNoInfoDialogs = false; 157 | return ret; 158 | } 159 | 160 | extern "C" HRESULT _stdcall ApplyP2KLayoutToDiskMBR(Console* console, LibPanther::Logger* logger, int diskNumber, bool letters, wchar_t*** mountPath, wchar_t*** volumeList) 161 | { 162 | HRESULT ret; 163 | HRESULT hResult; 164 | int volIndex = 0; 165 | int totalPartitions = 0; 166 | long structSize = 0; 167 | WP_PART_LAYOUT* layout = nullptr; 168 | 169 | PartitionManager::ShowNoInfoDialogs = true; 170 | PartitionManager::SetConsole(console); 171 | PartitionManager::SetLogger(logger); 172 | 173 | // Show loading screen 174 | PartitionManager::CurrentPage = new Page(); 175 | PartitionManager::CurrentPage->Initialize(console); 176 | PartitionManager::CurrentPage->Update(); 177 | 178 | if (PartitionManager::ShowMessagePage(L"Warning: All data on the drive will be lost and a new partition table will be written. Would you like to continue?", MessagePageType::YesNo, MessagePageUI::Warning) != MessagePageResult::Yes) 179 | { 180 | ret = ERROR_CANCELLED; 181 | goto exit; 182 | } 183 | 184 | PartitionManager::PopulateDiskInformation(); 185 | PartitionManager::CurrentDisk.DiskNumber = -1; 186 | for (int i = 0; i < PartitionManager::DiskInformationTableSize; i++) 187 | if (PartitionManager::DiskInformationTable[i].DiskNumber == diskNumber) 188 | PartitionManager::CurrentDisk = PartitionManager::DiskInformationTable[diskNumber]; 189 | if (PartitionManager::CurrentDisk.DiskNumber == -1) 190 | { 191 | ret = ERROR_FILE_NOT_FOUND; 192 | goto exit; 193 | } 194 | 195 | wchar_t rootCwdPath[MAX_PATH]; 196 | if (_wgetcwd(rootCwdPath, MAX_PATH) == NULL) 197 | { 198 | ret = ERROR_PATH_NOT_FOUND; 199 | goto exit; 200 | } 201 | 202 | PathStripToRootW(rootCwdPath); 203 | 204 | for (int i = 0; i < 3; i++) 205 | { 206 | wcscpy_s((*mountPath)[i], MAX_PATH, rootCwdPath); 207 | } 208 | 209 | if (letters) 210 | { 211 | int mountIndex = 0; 212 | DWORD drives = GetLogicalDrives(); 213 | const wchar_t* letters = L"ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 214 | for (int i = 25; i >= 0 && mountIndex < 3; i--) 215 | { 216 | if (drives ^ 0b10000000000000000000000000 217 | && letters[i] != L'X' 218 | && letters[i] != L'A' 219 | && letters[i] != L'B') 220 | { 221 | (*mountPath)[mountIndex][0] = letters[i]; 222 | (*mountPath)[mountIndex++][1] = L'\0'; 223 | } 224 | drives <<= 1; 225 | } 226 | 227 | if (mountIndex != 3) 228 | { 229 | ret = ERROR_BUSY; 230 | goto exit; 231 | } 232 | } 233 | else 234 | { 235 | wcscat_s((*mountPath)[0], MAX_PATH, L"$Panther2K\\Sys\\"); 236 | wcscat_s((*mountPath)[1], MAX_PATH, L"$Panther2K\\Win\\"); 237 | wcscat_s((*mountPath)[2], MAX_PATH, L"$Panther2K\\Rec\\"); 238 | 239 | for (int i = 0; i < 3; i++) 240 | { 241 | hResult = SHCreateDirectoryExW(NULL, (*mountPath)[i], NULL); 242 | if (hResult != ERROR_SUCCESS && hResult != ERROR_ALREADY_EXISTS) 243 | { 244 | ret = hResult; 245 | goto exit; 246 | } 247 | } 248 | } 249 | 250 | // TODO: Move this to Panther2K 251 | totalPartitions = 3; 252 | structSize = (sizeof(WP_PART_LAYOUT) + ((totalPartitions - 1) * sizeof(WP_PART_DESCRIPTION))); 253 | layout = (WP_PART_LAYOUT*)safeMalloc(logger, structSize); 254 | ZeroMemory(layout, structSize); 255 | layout->PartitionCount = totalPartitions; 256 | 257 | layout->Partitions[0].PartitionNumber = 1; 258 | layout->Partitions[0].PartitionType = 0x0780; 259 | if (PartitionManager::CurrentDisk.SectorSize == 4096) 260 | wcscpy_s(layout->Partitions[0].PartitionSize, L"500M"); 261 | else 262 | wcscpy_s(layout->Partitions[0].PartitionSize, L"150M"); 263 | wcscpy_s(layout->Partitions[0].FileSystem, L"NTFS"); 264 | layout->Partitions[0].MountPoint = (*mountPath)[0]; 265 | 266 | layout->Partitions[1].PartitionNumber = 2; 267 | layout->Partitions[1].PartitionType = 0x0700; 268 | wcscpy_s(layout->Partitions[1].PartitionSize, L"100%"); 269 | wcscpy_s(layout->Partitions[1].FileSystem, L"NTFS"); 270 | layout->Partitions[1].MountPoint = (*mountPath)[1]; 271 | 272 | layout->Partitions[2].PartitionNumber = 3; 273 | layout->Partitions[2].PartitionType = 0x0700; 274 | wcscpy_s(layout->Partitions[2].PartitionSize, L"500M"); 275 | wcscpy_s(layout->Partitions[2].FileSystem, L"NTFS"); 276 | layout->Partitions[2].MountPoint = (*mountPath)[2]; 277 | 278 | ret = PartitionManager::ApplyPartitionLayoutMBR(layout); 279 | volIndex = 0; 280 | for (int i = 0; i < 3; i++) 281 | { 282 | PartitionManager::LoadPartition(&PartitionManager::CurrentDiskPartitions[i]); 283 | lstrcpyW((*volumeList)[volIndex++], PartitionManager::CurrentPartition.VolumeInformation.VolumeFile); 284 | } 285 | free(layout); 286 | 287 | exit: 288 | PartitionManager::ShowNoInfoDialogs = false; 289 | return ret; 290 | } 291 | 292 | bool LoadPartitionFromOffset(int diskNumber, unsigned long long partOffset) 293 | { 294 | PartitionManager::PopulateDiskInformation(); 295 | if (!PartitionManager::LoadDisk(&PartitionManager::DiskInformationTable[diskNumber], false)) return false; 296 | 297 | for (int i = 0; i < PartitionManager::CurrentDiskPartitionCount; i++) 298 | { 299 | if (PartitionManager::CurrentDiskPartitions[i].StartLBA.ULL * PartitionManager::CurrentDisk.SectorSize == partOffset) 300 | { 301 | if (!PartitionManager::LoadPartition(&PartitionManager::CurrentDiskPartitions[i])) 302 | return false; 303 | return true; 304 | } 305 | } 306 | return false; 307 | } 308 | 309 | extern "C" HRESULT _stdcall SetPartType(Console* console, LibPanther::Logger* logger, int diskNumber, unsigned long long partOffset, short partType) 310 | { 311 | PartitionManager::SetConsole(console); 312 | PartitionManager::SetLogger(logger); 313 | PartitionManager::ShowNoInfoDialogs = true; 314 | HRESULT returnValue = ERROR_INVALID_HANDLE; 315 | 316 | PartitionManager::CurrentPage = new Page(); 317 | PartitionManager::CurrentPage->Initialize(console); 318 | PartitionManager::CurrentPage->Update(); 319 | 320 | if (!LoadPartitionFromOffset(diskNumber, partOffset)) goto retFalse; 321 | if (!PartitionManager::SetCurrentPartitionType(partType)) goto retFalse; 322 | if (!PartitionManager::SavePartitionTableToDisk()) goto retFalse; 323 | returnValue = ERROR_SUCCESS; 324 | 325 | retFalse: 326 | PartitionManager::ShowNoInfoDialogs = false; 327 | return returnValue; 328 | } 329 | 330 | extern "C" HRESULT _stdcall MountPartition(Console * console, LibPanther::Logger * logger, int diskNumber, unsigned long long partOffset, const wchar_t* mountPoint) 331 | { 332 | PartitionManager::SetConsole(console); 333 | PartitionManager::SetLogger(logger); 334 | PartitionManager::ShowNoInfoDialogs = true; 335 | HRESULT result = ERROR_BAD_UNIT; 336 | 337 | if (!LoadPartitionFromOffset(diskNumber, partOffset)) goto retFalse; 338 | result = PartitionManager::MountPartition(&PartitionManager::CurrentPartition, mountPoint); 339 | 340 | retFalse: 341 | PartitionManager::ShowNoInfoDialogs = false; 342 | return result; 343 | } --------------------------------------------------------------------------------