+ if (Status != ERROR_SUCCESS)\r
+ {\r
+ return 1;\r
+ }\r
+\r
+ Log("OpenVirtualDisk success");\r
+\r
+ Status = VentoyAttachVirtualDisk(Handle, IsoPath);\r
+ if (Status != ERROR_SUCCESS)\r
+ {\r
+ Log("Failed to attach virtual disk ErrorCode:%u", Status);\r
+ CloseHandle(Handle);\r
+ return 1;\r
+ }\r
+\r
+ Log("VentoyAttachVirtualDisk success");\r
+\r
+ CloseHandle(Handle);\r
+ return 0;\r
+}\r
+\r
+\r
+static HANDLE g_FatPhyDrive;\r
+static UINT64 g_Part2StartSec;\r
+\r
+static int CopyFileFromFatDisk(const CHAR* SrcFile, const CHAR *DstFile)\r
+{\r
+ int rc = 1;\r
+ int size = 0;\r
+ char *buf = NULL;\r
+ void *flfile = NULL;\r
+\r
+ Log("CopyFileFromFatDisk (%s)==>(%s)", SrcFile, DstFile);\r
+\r
+ flfile = fl_fopen(SrcFile, "rb");\r
+ if (flfile)\r
+ {\r
+ fl_fseek(flfile, 0, SEEK_END);\r
+ size = (int)fl_ftell(flfile);\r
+ fl_fseek(flfile, 0, SEEK_SET);\r
+\r
+ buf = (char *)malloc(size);\r
+ if (buf)\r
+ {\r
+ fl_fread(buf, 1, size, flfile);\r
+\r
+ rc = 0;\r
+ SaveBuffer2File(DstFile, buf, size);\r
+ free(buf);\r
+ }\r
+\r
+ fl_fclose(flfile);\r
+ }\r
+\r
+ return rc;\r
+}\r
+\r
+static int VentoyFatDiskRead(uint32 Sector, uint8 *Buffer, uint32 SectorCount)\r
+{\r
+ DWORD dwSize;\r
+ BOOL bRet;\r
+ DWORD ReadSize;\r
+ LARGE_INTEGER liCurrentPosition;\r
+\r
+ liCurrentPosition.QuadPart = Sector + g_Part2StartSec;\r
+ liCurrentPosition.QuadPart *= 512;\r
+ SetFilePointerEx(g_FatPhyDrive, liCurrentPosition, &liCurrentPosition, FILE_BEGIN);\r
+\r
+ ReadSize = (DWORD)(SectorCount * 512);\r
+\r
+ bRet = ReadFile(g_FatPhyDrive, Buffer, ReadSize, &dwSize, NULL);\r
+ if (bRet == FALSE || dwSize != ReadSize)\r
+ {\r
+ Log("ReadFile error bRet:%u WriteSize:%u dwSize:%u ErrCode:%u", bRet, ReadSize, dwSize, GetLastError());\r
+ }\r
+\r
+ return 1;\r
+}\r
+\r
+static BOOL Is2K10PE(void)\r
+{\r
+ BOOL bRet = FALSE;\r
+ FILE *fp = NULL;\r
+ CHAR szLine[1024];\r
+\r
+ fopen_s(&fp, "X:\\Windows\\System32\\PECMD.INI", "r");\r
+ if (!fp)\r
+ {\r
+ return FALSE;\r
+ }\r
+\r
+ memset(szLine, 0, sizeof(szLine));\r
+ while (fgets(szLine, sizeof(szLine) - 1, fp))\r
+ {\r
+ if (strstr(szLine, "2k10\\"))\r
+ {\r
+ bRet = TRUE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ fclose(fp);\r
+ return bRet;\r
+}\r
+\r
+static CHAR GetIMDiskMountLogicalDrive(void)\r
+{\r
+ CHAR Letter = 'Y';\r
+ DWORD Drives;\r
+ DWORD Mask = 0x1000000;\r
+\r
+ // fixed use M as mountpoint for 2K10 PE\r
+ if (Is2K10PE())\r
+ {\r
+ Log("Use M: for 2K10 PE");\r
+ return 'M';\r
+ }\r
+\r
+ Drives = GetLogicalDrives();\r
+ Log("Drives=0x%x", Drives);\r
+ \r
+ while (Mask)\r
+ {\r
+ if ((Drives & Mask) == 0)\r
+ {\r
+ break;\r
+ }\r
+\r
+ Letter--;\r
+ Mask >>= 1;\r
+ }\r
+\r
+ return Letter;\r
+}\r
+\r
+UINT64 GetVentoyEfiPartStartSector(HANDLE hDrive)\r
+{\r
+ BOOL bRet;\r
+ DWORD dwSize; \r
+ MBR_HEAD MBR; \r
+ VTOY_GPT_INFO *pGpt = NULL;\r
+ UINT64 StartSector = 0;\r
+\r
+ SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
+\r
+ bRet = ReadFile(hDrive, &MBR, sizeof(MBR), &dwSize, NULL);\r
+ Log("Read MBR Ret:%u Size:%u code:%u", bRet, dwSize, LASTERR);\r
+\r
+ if ((!bRet) || (dwSize != sizeof(MBR)))\r
+ {\r
+ 0;\r
+ }\r
+\r
+ if (MBR.PartTbl[0].FsFlag == 0xEE)\r
+ {\r
+ Log("GPT partition style");\r
+\r
+ pGpt = malloc(sizeof(VTOY_GPT_INFO));\r
+ if (!pGpt)\r
+ {\r
+ return 0;\r
+ }\r
+\r
+ SetFilePointer(hDrive, 0, NULL, FILE_BEGIN);\r
+ bRet = ReadFile(hDrive, pGpt, sizeof(VTOY_GPT_INFO), &dwSize, NULL); \r
+ if ((!bRet) || (dwSize != sizeof(VTOY_GPT_INFO)))\r
+ {\r
+ Log("Failed to read gpt info %d %u %d", bRet, dwSize, LASTERR);\r
+ return 0;\r
+ }\r
+\r
+ StartSector = pGpt->PartTbl[1].StartLBA;\r
+ free(pGpt);\r
+ }\r
+ else\r
+ {\r
+ Log("MBR partition style");\r
+ StartSector = MBR.PartTbl[1].StartSectorId;\r
+ }\r
+\r
+ Log("GetVentoyEfiPart StartSector: %llu", StartSector);\r
+ return StartSector;\r
+}\r
+\r
+static int VentoyRunImdisk(const char *IsoPath, const char *imdiskexe)\r
+{\r
+ CHAR Letter;\r
+ CHAR Cmdline[512];\r
+ WCHAR CmdlineW[512];\r
+ PROCESS_INFORMATION Pi;\r
+\r
+ Log("VentoyRunImdisk <%s> <%s>", IsoPath, imdiskexe);\r
+\r
+ Letter = GetIMDiskMountLogicalDrive();\r
+ sprintf_s(Cmdline, sizeof(Cmdline), "%s -a -o ro -f \"%s\" -m %C:", imdiskexe, IsoPath, Letter);\r
+ Log("mount iso to %C: use imdisk cmd <%s>", Letter, Cmdline);\r
+\r
+ if (IsUTF8Encode(IsoPath))\r
+ {\r
+ STARTUPINFOW Si;\r
+ GetStartupInfoW(&Si);\r
+ Si.dwFlags |= STARTF_USESHOWWINDOW;\r
+ Si.wShowWindow = SW_HIDE;\r
+\r
+ Utf8ToUtf16(Cmdline, CmdlineW);\r
+ CreateProcessW(NULL, CmdlineW, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);\r
+\r
+ Log("This is UTF8 encoding");\r
+ }\r
+ else\r
+ {\r
+ STARTUPINFOA Si;\r
+ GetStartupInfoA(&Si);\r
+ Si.dwFlags |= STARTF_USESHOWWINDOW;\r
+ Si.wShowWindow = SW_HIDE;\r
+\r
+ CreateProcessA(NULL, Cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &Si, &Pi);\r
+\r
+ Log("This is ANSI encoding");\r
+ }\r
+\r
+ Log("Wait for imdisk process ...");\r
+ WaitForSingleObject(Pi.hProcess, INFINITE);\r
+ Log("imdisk process finished");\r
+\r
+ return 0;\r
+}\r
+\r
+int VentoyMountISOByImdisk(const char *IsoPath, DWORD PhyDrive)\r
+{\r
+ int rc = 1;\r
+ BOOL bRet;\r
+ DWORD dwBytes;\r
+ HANDLE hDrive;\r
+ CHAR PhyPath[MAX_PATH];\r
+ GET_LENGTH_INFORMATION LengthInfo;\r
+\r
+ Log("VentoyMountISOByImdisk %s", IsoPath);\r
+\r
+ if (IsFileExist("X:\\Windows\\System32\\imdisk.exe"))\r
+ {\r
+ Log("imdisk.exe exist, use it directly...");\r
+ VentoyRunImdisk(IsoPath, "imdisk.exe");\r
+ return 0;\r
+ }\r
+\r
+ sprintf_s(PhyPath, sizeof(PhyPath), "\\\\.\\PhysicalDrive%d", PhyDrive);\r
+ hDrive = CreateFileA(PhyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);\r
+ if (hDrive == INVALID_HANDLE_VALUE)\r
+ {\r
+ Log("Could not open the disk<%s>, error:%u", PhyPath, GetLastError());\r
+ goto End;\r
+ }\r
+\r
+ bRet = DeviceIoControl(hDrive, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &LengthInfo, sizeof(LengthInfo), &dwBytes, NULL);\r
+ if (!bRet)\r