PageRenderTime 73ms CodeModel.GetById 41ms RepoModel.GetById 1ms app.codeStats 0ms

/Installer_EFI_gui/Installer_EFI_gui.cpp

https://gitlab.com/Red54/WindSLIC
C++ | 544 lines | 452 code | 19 blank | 73 comment | 130 complexity | 58c5b4cc917546074725bbdb2f937f1c MD5 | raw file
  1. //
  2. /* This program is free software. It comes without any warranty, to
  3. * the extent permitted by applicable law. You can redistribute it
  4. * and/or modify it under the terms of the Do What The Fuck You Want
  5. * To Public License, Version 2, as published by Sam Hocevar. See
  6. * http://sam.zoy.org/wtfpl/COPYING for more details. */
  7. //
  8. #include "stdafx.h"
  9. #include "Installer_EFI_gui.h"
  10. using namespace std;
  11. #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls'\
  12. ""version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
  13. #define MAX_LOADSTRING 100
  14. #define MAX_SLPSTRING 32
  15. //
  16. // Global Variables:
  17. HINSTANCE hInst; // current instance
  18. TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
  19. TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
  20. HWND hWndButton1;
  21. HWND hWndButton2;
  22. HWND hWndCombobox;
  23. HWND hWndMain;
  24. HCURSOR hCursor;
  25. BOOL bBusy = FALSE;
  26. //
  27. // Forward declarations of functions included in this code module:
  28. ATOM MyRegisterClass(HINSTANCE hInstance);
  29. BOOL InitInstance(HINSTANCE, int);
  30. LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
  31. int APIENTRY _tWinMain(HINSTANCE hInstance,
  32. HINSTANCE hPrevInstance,
  33. LPTSTR lpCmdLine,
  34. int nCmdShow)
  35. {
  36. UNREFERENCED_PARAMETER(hPrevInstance);
  37. UNREFERENCED_PARAMETER(lpCmdLine);
  38. // TODO: Place code here.
  39. MSG msg;
  40. //HACCEL hAccelTable;
  41. // Initialize global strings
  42. LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
  43. LoadString(hInstance, IDC_WINDSLICEFIINSTALLER, szWindowClass, MAX_LOADSTRING);
  44. MyRegisterClass(hInstance);
  45. // Perform application initialization:
  46. if (!InitInstance (hInstance, nCmdShow))
  47. {
  48. return FALSE;
  49. }
  50. // Main message loop:
  51. while (GetMessage(&msg, NULL, 0, 0))
  52. {
  53. if(msg.hwnd == hWndButton1) {
  54. switch (msg.message) {
  55. case WM_LBUTTONUP:
  56. ThreadStart();
  57. CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Install, 0, 0, 0);
  58. break;
  59. }
  60. }
  61. if(msg.hwnd == hWndButton2) {
  62. switch (msg.message) {
  63. case WM_LBUTTONUP:
  64. ThreadStart();
  65. CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)Uninstall, 0, 0, 0);
  66. break;
  67. }
  68. }
  69. DispatchMessage(&msg);
  70. }
  71. return (int) msg.wParam;
  72. }
  73. //
  74. // FUNCTION: MyRegisterClass()
  75. //
  76. // PURPOSE: Registers the window class.
  77. //
  78. // COMMENTS:
  79. //
  80. // This function and its usage are only necessary if you want this code
  81. // to be compatible with Win32 systems prior to the 'RegisterClassEx'
  82. // function that was added to Windows 95. It is important to call this function
  83. // so that the application will get 'well formed' small icons associated
  84. // with it.
  85. //
  86. ATOM MyRegisterClass(HINSTANCE hInstance)
  87. {
  88. WNDCLASSEX wcex;
  89. wcex.cbSize = sizeof(WNDCLASSEX);
  90. wcex.style = CS_HREDRAW | CS_VREDRAW;
  91. wcex.lpfnWndProc = WndProc;
  92. wcex.cbClsExtra = 0;
  93. wcex.cbWndExtra = 0;
  94. wcex.hInstance = hInstance;
  95. wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_LARGE));
  96. wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
  97. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW);
  98. wcex.lpszMenuName = NULL;
  99. wcex.lpszClassName = szWindowClass;
  100. wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
  101. return RegisterClassEx(&wcex);
  102. }
  103. //
  104. // FUNCTION: InitInstance(HINSTANCE, int)
  105. //
  106. // PURPOSE: Saves instance handle and creates main window
  107. //
  108. // COMMENTS:
  109. //
  110. // In this function, we save the instance handle in a global variable and
  111. // create and display the main program window.
  112. //
  113. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
  114. {
  115. hInst = hInstance; // Store instance handle in our global variable
  116. hWndMain = CreateWindow(szWindowClass, szTitle, WS_BORDER|WS_SYSMENU,
  117. CW_USEDEFAULT, CW_USEDEFAULT, 200, 145, NULL, NULL, hInstance, NULL);
  118. if (!hWndMain)
  119. {
  120. return FALSE;
  121. }
  122. ShowWindow(hWndMain, nCmdShow);
  123. UpdateWindow(hWndMain);
  124. return TRUE;
  125. }
  126. //
  127. // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
  128. //
  129. // PURPOSE: Processes messages for the main window.
  130. //
  131. // WM_COMMAND - process the application menu
  132. // WM_PAINT - Paint the main window
  133. // WM_DESTROY - post a quit message and return
  134. //
  135. //
  136. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  137. {
  138. //int wmId, wmEvent;
  139. PAINTSTRUCT ps;
  140. HDC hdc;
  141. switch (message)
  142. {
  143. case WM_CLOSE:
  144. if (bBusy)
  145. {
  146. return 0;
  147. }
  148. PostQuitMessage(0);
  149. break;
  150. case WM_SETCURSOR:
  151. if(bBusy) {
  152. return TRUE;
  153. }
  154. else {
  155. hCursor = LoadCursor(NULL, IDC_ARROW);
  156. if (hCursor) {
  157. SetCursor(hCursor);
  158. }
  159. return TRUE;
  160. }
  161. case WM_CREATE:
  162. {
  163. hWndButton1 = CreateWindow(L"button", L"Install",
  164. WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
  165. 10, 80, 80, 25,
  166. hWnd, (HMENU) 1, NULL, NULL);
  167. //
  168. hWndButton2 = CreateWindow(L"button", L"Uninstall",
  169. WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,
  170. 104, 80, 80, 25,
  171. hWnd, (HMENU) 2, NULL, NULL);
  172. //
  173. hWndCombobox = CreateWindow(L"combobox", L"SLIC",
  174. WS_VISIBLE | WS_CHILD | CBS_DROPDOWNLIST | CBS_SORT,
  175. 10, 20, 174, 25,
  176. hWnd, (HMENU) 3, NULL, NULL);
  177. //
  178. HFONT hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
  179. SendMessage( hWndMain, WM_SETFONT, (WPARAM)hFont, TRUE );
  180. SendMessage( hWndButton1, WM_SETFONT, (WPARAM)hFont, TRUE );
  181. SendMessage( hWndButton2, WM_SETFONT, (WPARAM)hFont, TRUE );
  182. SendMessage( hWndCombobox, WM_SETFONT, (WPARAM)hFont, TRUE );
  183. PopulateCombobox(hWndCombobox);
  184. if (!isEfi() || !Test() || !InitLib(TRUE)) {
  185. EnableWindow(hWndButton1, FALSE);
  186. EnableWindow(hWndButton2, FALSE);
  187. EnableWindow(hWndCombobox, FALSE);
  188. }
  189. break;
  190. }
  191. case WM_PAINT:
  192. hdc = BeginPaint(hWnd, &ps);
  193. // TODO: Add any drawing code here...
  194. EndPaint(hWnd, &ps);
  195. break;
  196. case WM_DESTROY:
  197. PostQuitMessage(0);
  198. break;
  199. default:
  200. return DefWindowProc(hWnd, message, wParam, lParam);
  201. }
  202. return 0;
  203. }
  204. //
  205. int
  206. Install (VOID)
  207. {
  208. ofstream outfile;
  209. int ret = 1;
  210. UCHAR Key[16] = {};
  211. wchar_t EntryName[24] = {};
  212. wchar_t Description[] = L"WindSLIC\0";
  213. wchar_t Injector[] = L"Injector\0";
  214. wchar_t BootFile[] = L"\\BOOTX64.EFI\0";
  215. wchar_t ResourceType[] = L"RAW\0";
  216. ULONG BootEntryLength = 0;
  217. HRSRC hResource;
  218. HGLOBAL hgResource;
  219. size_t WindSlicSize;
  220. size_t SlicSize;
  221. ULONG EntryId;
  222. CHAR* SLPString;
  223. UINT32 SLPLength = 0;
  224. UINT32 ScanBegin = 0;
  225. UINT32 ScanEnd = 0;
  226. UCHAR* WindSlicBuffer;
  227. UCHAR* SlicBuffer;
  228. UCHAR* BootEntry;
  229. LPTSTR ResourceName;
  230. wchar_t* UId = NULL;
  231. wchar_t* DosDevice = NULL;
  232. wchar_t* Directory = NULL;
  233. wchar_t* OldDirectory = NULL;
  234. wchar_t* FilePath = NULL;
  235. wchar_t* BootEntryPath = NULL;
  236. //
  237. try {
  238. DosDevice = new wchar_t[8];
  239. Directory = new wchar_t[MAX_PATH];
  240. OldDirectory = new wchar_t[MAX_PATH];
  241. FilePath = new wchar_t[MAX_PATH];
  242. BootEntryPath = new wchar_t[MAX_PATH];
  243. UId = new wchar_t[sizeof(GUID) * 2 + 4]();
  244. if(!InitLib(TRUE)) {
  245. throw bad_alloc();
  246. }
  247. GetFreeLetter (DosDevice);
  248. if(UniqueId(&UId) == ERROR_OUTOFMEMORY) {
  249. throw bad_alloc();
  250. }
  251. wsprintf(Directory, L"%s\\EFI\\%s\0", DosDevice, UId);
  252. wsprintf(OldDirectory, L"%s\\EFI\\WINDSLIC\0", DosDevice);
  253. wsprintf(FilePath, L"%s%s\0", Directory, BootFile);
  254. wsprintf(BootEntryPath, L"\\EFI\\%s%s\0", UId, BootFile);
  255. // get modify firmware variable privilage.
  256. AcquirePrivilage();
  257. // install WindSLIC to ESP.
  258. MountEsp(DosDevice);
  259. DeleteRecursive(OldDirectory);
  260. while (DeleteRecursive(Directory) != 0) {
  261. Sleep(100);
  262. }
  263. if (CreateDirectory(Directory, NULL)) {
  264. // get WindSLIC resource.
  265. hResource = FindResource(NULL, MAKEINTRESOURCE(130), ResourceType);
  266. WindSlicSize = SizeofResource(NULL, hResource);
  267. hgResource = LoadResource(NULL, hResource);
  268. WindSlicBuffer = new UCHAR[WindSlicSize];
  269. memcpy(WindSlicBuffer, LockResource(hgResource), WindSlicSize);
  270. // get SLIC resource.
  271. switch (SendMessage(hWndCombobox, CB_GETCURSEL, 0, 0)) {
  272. case 0:
  273. ResourceName = MAKEINTRESOURCE(131);
  274. SLPString = "AcerSystem\0";
  275. ScanBegin = 0x0F0000;
  276. ScanEnd = 0x0FFFFF;
  277. break;
  278. case 1:
  279. ResourceName = MAKEINTRESOURCE(132);
  280. SLPString = "alienware\0";
  281. ScanBegin = 0x0F0000;
  282. ScanEnd = 0x0FFFFF;
  283. break;
  284. case 2:
  285. ResourceName = MAKEINTRESOURCE(133);
  286. SLPString = "ASUS_FLASH\0";
  287. ScanBegin = 0x0FC000;
  288. ScanEnd = 0x0FFFFF;
  289. break;
  290. case 3:
  291. ResourceName = MAKEINTRESOURCE(134);
  292. SLPString = "GIGABYTE\0";
  293. ScanBegin = 0x0F0000;
  294. ScanEnd = 0x0FFFFF;
  295. break;
  296. }
  297. hResource = FindResource(NULL, ResourceName, L"RAW");
  298. SLPLength = strlen(SLPString);
  299. SlicSize = SizeofResource(NULL, hResource);
  300. SlicBuffer = new UCHAR[SlicSize];
  301. hgResource = LoadResource(NULL, hResource);
  302. memcpy(SlicBuffer,LockResource(hgResource), SlicSize);
  303. // generate encryption key.
  304. srand((UINT)time(0));
  305. for (UINT i = 0; i < sizeof(Key); i++) {
  306. Key[i] = (UCHAR)(rand() % 0x5D) + 0x21;
  307. }
  308. // encrypt SLIC.
  309. UINT pos = sizeof(Key)-1;
  310. for(UINT i = 0; i < SlicSize; i++) {
  311. SlicBuffer[i] ^= Key[pos];
  312. pos--;
  313. if (pos == -1) {
  314. pos = sizeof(Key)-1;
  315. }
  316. }
  317. // encrypt key.
  318. for (UINT i = 0; i < sizeof(Key); i++) {
  319. Key[i] ^= 0xFF;
  320. }
  321. // copy encrypted data.
  322. for (UINT i = 0; i < WindSlicSize - 6; i++) {
  323. BOOL slic = FALSE;
  324. BOOL key = FALSE;
  325. BOOL slp = FALSE;
  326. BOOL slplen = FALSE;
  327. BOOL begin = FALSE;
  328. BOOL end = FALSE;
  329. //
  330. if (WindSlicBuffer[i] == 0x53 && WindSlicBuffer[i+1] == 0x4C
  331. && WindSlicBuffer[i+2] == 0x50 && WindSlicBuffer[i+3] == 0x53
  332. && WindSlicBuffer[i+4] == 0x54 && WindSlicBuffer[i+5] == 0x52) {
  333. memset(&WindSlicBuffer[i], 0, MAX_SLPSTRING);
  334. memcpy(&WindSlicBuffer[i], SLPString, SLPLength);
  335. slp = TRUE;
  336. }
  337. if (WindSlicBuffer[i] == 0x4B && WindSlicBuffer[i+1] == 0x45
  338. && WindSlicBuffer[i+2] == 0x59 && WindSlicBuffer[i+3] == 0x4B
  339. && WindSlicBuffer[i+4] == 0x45 && WindSlicBuffer[i+5] == 0x59) {
  340. memcpy(&WindSlicBuffer[i], Key, sizeof(Key));
  341. key = TRUE;
  342. }
  343. if (WindSlicBuffer[i] == 0x53 && WindSlicBuffer[i+1] == 0x4C
  344. && WindSlicBuffer[i+2] == 0x49 && WindSlicBuffer[i+3] == 0x43
  345. && WindSlicBuffer[i+4] == 0x76 && WindSlicBuffer[i+5] == 0x01) {
  346. memcpy(&WindSlicBuffer[i], SlicBuffer, SlicSize);
  347. slic = TRUE;
  348. }
  349. if (WindSlicBuffer[i] == 0x41 && WindSlicBuffer[i+1] == 0x41
  350. && WindSlicBuffer[i+2] == 0x41 && WindSlicBuffer[i+3] == 0x41) {
  351. memcpy(&WindSlicBuffer[i], &SLPLength, sizeof(UINT32));
  352. slplen = TRUE;
  353. }
  354. if (WindSlicBuffer[i] == 0x42 && WindSlicBuffer[i+1] == 0x42
  355. && WindSlicBuffer[i+2] == 0x42 && WindSlicBuffer[i+3] == 0x42) {
  356. memcpy(&WindSlicBuffer[i], &ScanBegin, sizeof(UINT32));
  357. begin = TRUE;
  358. }
  359. if (WindSlicBuffer[i] == 0x43 && WindSlicBuffer[i+1] == 0x43
  360. && WindSlicBuffer[i+2] == 0x43 && WindSlicBuffer[i+3] == 0x43) {
  361. memcpy(&WindSlicBuffer[i], &ScanEnd, sizeof(UINT32));
  362. end = TRUE;
  363. }
  364. if (key && slic && slp && end && begin && slplen) {
  365. break;
  366. }
  367. }
  368. outfile.open(FilePath, ios_base::binary);
  369. if (outfile.is_open()) {
  370. outfile.write((char*) WindSlicBuffer, WindSlicSize);
  371. outfile.close();
  372. }
  373. delete[] WindSlicBuffer;
  374. delete[] SlicBuffer;
  375. }
  376. else {
  377. EfiDeleteDescription(Description);
  378. EfiDeleteDescription(Injector);
  379. EfiBootmgrAddFirst();
  380. goto exit;
  381. }
  382. // remove any WindSLIC boot entries.
  383. EfiDeleteDescription(Description);
  384. EfiDeleteDescription(Injector);
  385. EfiBootmgrAddFirst();
  386. // add WindSLIC boot entry.
  387. EntryId = EfiFreeBootEntry();
  388. if (EntryId == -1) {
  389. }
  390. else {
  391. wsprintf(EntryName, L"Boot%04d", EntryId);
  392. if(EfiCreateBootEntry(NULL, &BootEntryLength, Description, BootEntryPath) == ERROR_OUTOFMEMORY) {
  393. throw bad_alloc();
  394. }
  395. BootEntry = new UCHAR[BootEntryLength];
  396. switch(EfiCreateBootEntry(BootEntry, &BootEntryLength, Description, BootEntryPath)) {
  397. case ERROR_SUCCESS:
  398. SetFirmwareEnvironmentVariable(EntryName, EfiGuid, BootEntry, BootEntryLength);
  399. EfiBootOrderAddFirst(EntryId);
  400. break;
  401. case ERROR_OUTOFMEMORY:
  402. throw bad_alloc();
  403. break;
  404. }
  405. ret = ERROR_SUCCESS;
  406. delete[] BootEntry;
  407. }
  408. exit:
  409. UnmountEsp(DosDevice);
  410. delete[] UId;
  411. delete[] BootEntryPath;
  412. delete[] FilePath;
  413. delete[] Directory;
  414. delete[] OldDirectory;
  415. delete[] DosDevice;
  416. ThreadFinished();
  417. InitLib(FALSE);
  418. return ret;
  419. }
  420. catch (bad_alloc) {
  421. if(NULL != UId) {delete[] UId;}
  422. if(NULL != BootEntryPath) {delete[] BootEntryPath;}
  423. if(NULL != FilePath) {delete[] FilePath;}
  424. if(NULL != Directory) {delete[] Directory;}
  425. if(NULL != OldDirectory) {delete[] OldDirectory;}
  426. if(NULL != DosDevice) {delete[] DosDevice;}
  427. ThreadFinished();
  428. InitLib(FALSE);
  429. return ERROR_OUTOFMEMORY;
  430. }
  431. }
  432. //
  433. int
  434. Uninstall (VOID)
  435. {
  436. wchar_t* UId = NULL;
  437. wchar_t* DosDevice = NULL;
  438. wchar_t* Directory = NULL;
  439. wchar_t* OldDirectory = NULL;
  440. wchar_t Description[] = L"WindSLIC\0";
  441. wchar_t Injector[] = L"Injector\0";
  442. try {
  443. DosDevice = new wchar_t[8];
  444. Directory = new wchar_t[MAX_PATH];
  445. OldDirectory = new wchar_t[MAX_PATH];
  446. UId = new wchar_t[sizeof(GUID) * 2 + 4]();
  447. if(!InitLib(TRUE)) {
  448. throw bad_alloc();
  449. }
  450. GetFreeLetter (DosDevice);
  451. if(UniqueId(&UId) == ERROR_OUTOFMEMORY) {
  452. throw bad_alloc();
  453. }
  454. wsprintf(Directory, L"%s\\EFI\\%s\0", DosDevice, UId);
  455. wsprintf(OldDirectory, L"%s\\EFI\\WINDSLIC\0", DosDevice);
  456. MountEsp(DosDevice);
  457. DeleteRecursive(OldDirectory);
  458. while (DeleteRecursive(Directory) != 0) {
  459. Sleep(100);
  460. }
  461. AcquirePrivilage();
  462. EfiDeleteDescription(Description);
  463. EfiDeleteDescription(Injector);
  464. EfiBootmgrAddFirst();
  465. UnmountEsp(DosDevice);
  466. delete[] UId;
  467. delete[] Directory;
  468. delete[] OldDirectory;
  469. delete[] DosDevice;
  470. ThreadFinished();
  471. InitLib(FALSE);
  472. return ERROR_SUCCESS;
  473. }
  474. catch (bad_alloc) {
  475. if(NULL != UId) {delete[] UId;}
  476. if(NULL != Directory) {delete[] Directory;}
  477. if(NULL != OldDirectory) {delete[] OldDirectory;}
  478. if(NULL != DosDevice) {delete[] DosDevice;}
  479. ThreadFinished();
  480. InitLib(FALSE);
  481. return ERROR_OUTOFMEMORY;
  482. }
  483. }
  484. //
  485. VOID
  486. PopulateCombobox(HWND hComboBox)
  487. {
  488. wchar_t* pSlic[] = {L"Acer", L"Alienware", L"Asus", L"Gigabyte"};
  489. for (UINT i = 0; i < 4; i++) {
  490. SendMessage(hComboBox, CB_ADDSTRING, 0, (LPARAM)pSlic[i]);
  491. }
  492. SendMessage(hComboBox, CB_SETCURSEL, 0, 0);
  493. }
  494. //
  495. VOID
  496. BumpMouse()
  497. {
  498. POINT point;
  499. GetCursorPos(&point);
  500. SetCursorPos(point.x, point.y);
  501. }
  502. //
  503. VOID
  504. ThreadFinished(VOID)
  505. {
  506. bBusy = FALSE;
  507. EnableWindow(hWndButton1, TRUE);
  508. EnableWindow(hWndButton2, TRUE);
  509. EnableWindow(hWndCombobox, TRUE);
  510. BumpMouse();
  511. }
  512. //
  513. VOID
  514. ThreadStart(VOID)
  515. {
  516. bBusy = TRUE;
  517. hCursor = LoadCursor(NULL, IDC_WAIT);
  518. if (hCursor) {
  519. SetCursor(hCursor);
  520. }
  521. EnableWindow(hWndButton1, FALSE);
  522. EnableWindow(hWndButton2, FALSE);
  523. EnableWindow(hWndCombobox, FALSE);
  524. }
  525. //