+\r
+STATIC BOOL IsPowershellExist(void)\r
+{\r
+ BOOL ret;\r
+\r
+ if (!IsWindows8OrGreater())\r
+ {\r
+ Log("This is before Windows8 powershell disk not supported.");\r
+ return FALSE;\r
+ }\r
+\r
+ ret = IsFileExist("C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe");\r
+ if (!ret)\r
+ {\r
+ Log("powershell.exe not exist");\r
+ }\r
+\r
+ return ret;\r
+}\r
+\r
+int PSHELL_GetPartitionNumber(int PhyDrive, UINT64 Offset)\r
+{\r
+ int partnum = -1;\r
+ DWORD i = 0;\r
+ DWORD BufLen = 0;\r
+ DWORD dwBytes = 0;\r
+ BOOL bRet;\r
+ HANDLE hDrive;\r
+ LONGLONG PartStart;\r
+ DRIVE_LAYOUT_INFORMATION_EX *pDriveLayout = NULL;\r
+\r
+ Log("PSHELL_GetPartitionNumber PhyDrive:%d Offset:%llu", PhyDrive, Offset);\r
+\r
+ hDrive = GetPhysicalHandle(PhyDrive, FALSE, FALSE, FALSE);\r
+ if (hDrive == INVALID_HANDLE_VALUE)\r
+ {\r
+ return -1;\r
+ }\r
+\r
+ BufLen = (DWORD)(sizeof(PARTITION_INFORMATION_EX)* 256);\r
+\r
+ pDriveLayout = malloc(BufLen);\r
+ if (!pDriveLayout)\r
+ {\r
+ goto out;\r
+ }\r
+ memset(pDriveLayout, 0, BufLen);\r
+\r
+ bRet = DeviceIoControl(hDrive,\r
+ IOCTL_DISK_GET_DRIVE_LAYOUT_EX, NULL,\r
+ 0,\r
+ pDriveLayout,\r
+ BufLen,\r
+ &dwBytes,\r
+ NULL);\r
+ if (!bRet)\r
+ {\r
+ Log("Failed to ioctrl get drive layout ex %u", LASTERR);\r
+ goto out;\r
+ }\r
+\r
+ Log("PhyDrive:%d PartitionStyle=%s PartitionCount=%u", PhyDrive,\r
+ (pDriveLayout->PartitionStyle == PARTITION_STYLE_MBR) ? "MBR" : "GPT", pDriveLayout->PartitionCount);\r
+\r
+ for (i = 0; i < pDriveLayout->PartitionCount; i++)\r
+ {\r
+ PartStart = pDriveLayout->PartitionEntry[i].StartingOffset.QuadPart;\r
+ if (PartStart == (LONGLONG)Offset)\r
+ {\r
+ Log("[*] [%d] PartitionNumber=%u Offset=%lld Length=%lld ",\r
+ i,\r
+ pDriveLayout->PartitionEntry[i].PartitionNumber,\r
+ pDriveLayout->PartitionEntry[i].StartingOffset.QuadPart,\r
+ pDriveLayout->PartitionEntry[i].PartitionLength.QuadPart\r
+ );\r
+ partnum = (int)pDriveLayout->PartitionEntry[i].PartitionNumber;\r
+ }\r
+ else\r
+ {\r
+ Log("[ ] [%d] PartitionNumber=%u Offset=%lld Length=%lld ",\r
+ i,\r
+ pDriveLayout->PartitionEntry[i].PartitionNumber,\r
+ pDriveLayout->PartitionEntry[i].StartingOffset.QuadPart,\r
+ pDriveLayout->PartitionEntry[i].PartitionLength.QuadPart\r
+ );\r
+ }\r
+ }\r
+\r
+out:\r
+\r
+ CHECK_CLOSE_HANDLE(hDrive);\r
+ CHECK_FREE(pDriveLayout);\r
+\r
+ return partnum;\r
+}\r
+\r
+\r
+STATIC BOOL PSHELL_CommProc(const char *Cmd)\r
+{\r
+ CHAR CmdBuf[4096];\r
+ STARTUPINFOA Si;\r
+ PROCESS_INFORMATION Pi;\r
+\r
+ if (!IsPowershellExist())\r
+ {\r
+ return FALSE;\r
+ }\r
+\r
+ GetStartupInfoA(&Si);\r
+ Si.dwFlags |= STARTF_USESHOWWINDOW;\r
+ Si.wShowWindow = SW_HIDE;\r
+\r
+ sprintf_s(CmdBuf, sizeof(CmdBuf), "C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\powershell.exe -Command \"&{ %s }\"", Cmd);\r
+\r
+ Log("CreateProcess <%s>", CmdBuf);\r
+ CreateProcessA(NULL, CmdBuf, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);\r
+\r
+ Log("Wair process ...");\r
+ WaitForSingleObject(Pi.hProcess, INFINITE);\r
+ Log("Process finished...");\r
+\r
+ CHECK_CLOSE_HANDLE(Pi.hProcess);\r
+ CHECK_CLOSE_HANDLE(Pi.hThread);\r
+\r
+ return TRUE;\r
+}\r
+\r
+\r
+BOOL PSHELL_CleanDisk(int DriveIndex)\r
+{\r
+ BOOL ret;\r
+ CHAR CmdBuf[512];\r
+\r
+ sprintf_s(CmdBuf, sizeof(CmdBuf), "Clear-Disk -Number %d -RemoveData -RemoveOEM -Confirm:$false", DriveIndex);\r
+ ret = PSHELL_CommProc(CmdBuf);\r
+ Log("CleanDiskByPowershell<%d> ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
+\r
+ return ret;\r
+}\r
+\r
+\r
+BOOL PSHELL_DeleteVtoyEFIPartition(int DriveIndex, UINT64 EfiPartOffset)\r
+{\r
+ int Part;\r
+ BOOL ret;\r
+ CHAR CmdBuf[512];\r
+\r
+ Part = PSHELL_GetPartitionNumber(DriveIndex, EfiPartOffset);\r
+ if (Part < 0)\r
+ {\r
+ ret = FALSE;\r
+ }\r
+ else\r
+ {\r
+ sprintf_s(CmdBuf, sizeof(CmdBuf), "Remove-Partition -DiskNumber %d -PartitionNumber %d -Confirm:$false", DriveIndex, Part);\r
+ ret = PSHELL_CommProc(CmdBuf);\r
+ }\r
+ \r
+ Log("PSHELL_DeleteVtoyEFIPartition<%d> ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
+ return ret;\r
+}\r
+\r
+\r
+BOOL PSHELL_ChangeVtoyEFI2ESP(int DriveIndex, UINT64 Offset)\r
+{\r
+ int Part;\r
+ BOOL ret;\r
+ CHAR CmdBuf[512];\r
+\r
+ Part = PSHELL_GetPartitionNumber(DriveIndex, Offset);\r
+ if (Part < 0)\r
+ {\r
+ ret = FALSE;\r
+ }\r
+ else\r
+ {\r
+ sprintf_s(CmdBuf, sizeof(CmdBuf), "Set-Partition -DiskNumber %d -PartitionNumber %d -gpttype '{C12A7328-F81F-11D2-BA4B-00A0C93EC93B}' -Confirm:$false", DriveIndex, Part);\r
+ ret = PSHELL_CommProc(CmdBuf);\r
+ }\r
+\r
+ Log("PSHELL_ChangeVtoyEFI2ESP<%d> ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
+ return ret;\r
+}\r
+\r
+\r
+BOOL PSHELL_ChangeVtoyEFI2Basic(int DriveIndex, UINT64 Offset)\r
+{\r
+ int Part;\r
+ BOOL ret;\r
+ CHAR CmdBuf[512];\r
+\r
+ Part = PSHELL_GetPartitionNumber(DriveIndex, Offset);\r
+ if (Part < 0)\r
+ {\r
+ ret = FALSE;\r
+ }\r
+ else\r
+ {\r
+ sprintf_s(CmdBuf, sizeof(CmdBuf), "Set-Partition -DiskNumber %d -PartitionNumber %d -gpttype '{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}' -Confirm:$false", DriveIndex, Part);\r
+ ret = PSHELL_CommProc(CmdBuf);\r
+ }\r
+ \r
+ Log("PSHELL_ChangeVtoyEFI2Basic<%d> ret:%d (%s)", DriveIndex, ret, ret ? "SUCCESS" : "FAIL");\r
+ return ret;\r
+}\r
+\r
+BOOL PSHELL_ShrinkVolume(int DriveIndex, const char* VolumeGuid, CHAR DriveLetter, UINT64 OldBytes, UINT64 ReduceBytes)\r
+{\r
+ int Part;\r
+ BOOL ret;\r
+ CHAR CmdBuf[512];\r
+\r
+ (void)VolumeGuid;\r
+\r
+ Part = PSHELL_GetPartitionNumber(DriveIndex, SIZE_1MB);\r
+ if (Part < 0)\r
+ {\r
+ ret = FALSE;\r
+ }\r
+ else\r
+ {\r
+ sprintf_s(CmdBuf, sizeof(CmdBuf), "Resize-Partition -DiskNumber %d -PartitionNumber %d -Size %llu -Confirm:$false", \r
+ DriveIndex, Part, OldBytes - ReduceBytes);\r
+ ret = PSHELL_CommProc(CmdBuf);\r
+ }\r
+\r
+ Log("PSHELL_ShrinkVolume<%d> %C: ret:%d (%s)", DriveIndex, DriveLetter, ret, ret ? "SUCCESS" : "FAIL");\r
+ return ret;\r
+}\r