]>
glassweightruler.freedombox.rocks Git - Ventoy.git/blob - Ventoy2Disk/Ventoy2Disk/Ventoy2Disk.c
1 /******************************************************************************
4 * Copyright (c) 2020, longpanda <admin@ventoy.net>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 3 of the
9 * License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see <http://www.gnu.org/licenses/>.
24 #include "Ventoy2Disk.h"
26 PHY_DRIVE_INFO
*g_PhyDriveList
= NULL
;
27 DWORD g_PhyDriveCount
= 0;
28 static int g_FilterRemovable
= 1;
29 static int g_FilterUSB
= 1;
30 int g_ForceOperation
= 1;
32 int ParseCmdLineOption(LPSTR lpCmdLine
)
35 char cfgfile
[MAX_PATH
];
37 if (lpCmdLine
&& lpCmdLine
[0])
39 Log("CmdLine:<%s>", lpCmdLine
);
42 for (i
= 0; i
< __argc
; i
++)
44 if (strncmp(__argv
[i
], "-R", 2) == 0)
46 g_FilterRemovable
= 0;
48 else if (strncmp(__argv
[i
], "-U", 2) == 0)
52 else if (strncmp(__argv
[i
], "-F", 2) == 0)
58 GetCurrentDirectoryA(sizeof(cfgfile
), cfgfile
);
59 strcat_s(cfgfile
, sizeof(cfgfile
), "\\Ventoy2Disk.ini");
61 if (0 == GetPrivateProfileIntA("Filter", "Removable", 1, cfgfile
))
63 g_FilterRemovable
= 0;
66 if (0 == GetPrivateProfileIntA("Filter", "USB", 1, cfgfile
))
71 if (1 == GetPrivateProfileIntA("Operation", "Force", 0, cfgfile
))
76 Log("Control Flag: %d %d %d", g_FilterRemovable
, g_FilterUSB
, g_ForceOperation
);
81 static BOOL
IsVentoyPhyDrive(int PhyDrive
, UINT64 SizeBytes
)
88 UINT32 PartStartSector
;
89 UINT32 PartSectorCount
;
90 CHAR PhyDrivePath
[128];
92 safe_sprintf(PhyDrivePath
, "\\\\.\\PhysicalDrive%d", PhyDrive
);
93 hDrive
= CreateFileA(PhyDrivePath
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
94 Log("Create file Handle:%p %s status:%u", hDrive
, PhyDrivePath
, LASTERR
);
96 if (hDrive
== INVALID_HANDLE_VALUE
)
101 bRet
= ReadFile(hDrive
, &MBR
, sizeof(MBR
), &dwSize
, NULL
);
102 CHECK_CLOSE_HANDLE(hDrive
);
104 Log("Read MBR Ret:%u Size:%u code:%u", bRet
, dwSize
, LASTERR
);
106 if ((!bRet
) || (dwSize
!= sizeof(MBR
)))
111 if (MBR
.Byte55
!= 0x55 || MBR
.ByteAA
!= 0xAA)
113 Log("Byte55 ByteAA not match 0x%x 0x%x", MBR
.Byte55
, MBR
.ByteAA
);
117 for (i
= 0; i
< 4; i
++)
119 Log("=========== Partition Table %d ============", i
+ 1);
120 Log("PartTbl.Active = 0x%x", MBR
.PartTbl
[i
].Active
);
121 Log("PartTbl.FsFlag = 0x%x", MBR
.PartTbl
[i
].FsFlag
);
122 Log("PartTbl.StartSectorId = %u", MBR
.PartTbl
[i
].StartSectorId
);
123 Log("PartTbl.SectorCount = %u", MBR
.PartTbl
[i
].SectorCount
);
124 Log("PartTbl.StartHead = %u", MBR
.PartTbl
[i
].StartHead
);
125 Log("PartTbl.StartSector = %u", MBR
.PartTbl
[i
].StartSector
);
126 Log("PartTbl.StartCylinder = %u", MBR
.PartTbl
[i
].StartCylinder
);
127 Log("PartTbl.EndHead = %u", MBR
.PartTbl
[i
].EndHead
);
128 Log("PartTbl.EndSector = %u", MBR
.PartTbl
[i
].EndSector
);
129 Log("PartTbl.EndCylinder = %u", MBR
.PartTbl
[i
].EndCylinder
);
132 if (MBR
.PartTbl
[2].SectorCount
> 0 || MBR
.PartTbl
[3].SectorCount
> 0)
134 Log("Part3 Part4 are not empty");
138 PartStartSector
= 2048;
139 PartSectorCount
= (UINT32
)((SizeBytes
- VENTOY_EFI_PART_SIZE
- SIZE_1MB
) / 512);
141 if (MBR
.PartTbl
[0].FsFlag
!= 0x07 ||
142 MBR
.PartTbl
[0].StartSectorId
!= PartStartSector
||
143 MBR
.PartTbl
[0].SectorCount
!= PartSectorCount
)
145 Log("Part1 not match %u %u", PartStartSector
, PartSectorCount
);
149 PartStartSector
= (UINT32
)((SizeBytes
- VENTOY_EFI_PART_SIZE
) / 512);
150 PartSectorCount
= VENTOY_EFI_PART_SIZE
/ 512;
152 if (MBR
.PartTbl
[1].Active
!= 0x80 ||
153 MBR
.PartTbl
[1].FsFlag
!= 0xEF ||
154 MBR
.PartTbl
[1].StartSectorId
!= PartStartSector
||
155 MBR
.PartTbl
[1].SectorCount
!= PartSectorCount
)
157 Log("Part2 not match %u %u", PartStartSector
, PartSectorCount
);
161 Log("PhysicalDrive%d is ventoy disk", PhyDrive
);
166 static int FilterPhysicalDrive(PHY_DRIVE_INFO
*pDriveList
, DWORD DriveCount
)
173 PHY_DRIVE_INFO
*CurDrive
;
174 int LogLetter
[VENTOY_MAX_PHY_DRIVE
];
175 int PhyDriveId
[VENTOY_MAX_PHY_DRIVE
];
177 for (LogDrive
= GetLogicalDrives(); LogDrive
> 0; LogDrive
>>= 1)
181 LogLetter
[LetterCount
] = Letter
;
182 PhyDriveId
[LetterCount
] = GetPhyDriveByLogicalDrive(Letter
);
184 Log("Logical Drive:%C ===> PhyDrive:%d", LogLetter
[LetterCount
], PhyDriveId
[LetterCount
]);
191 for (i
= 0; i
< DriveCount
; i
++)
193 CurDrive
= pDriveList
+ i
;
196 CurDrive
->FirstDriveLetter
= -1;
199 if (CurDrive
->SizeInBytes
> 2199023255552ULL)
201 Log("<%s %s> is filtered for too big for MBR.", CurDrive
->VendorId
, CurDrive
->ProductId
);
205 if (g_FilterRemovable
&& (!CurDrive
->RemovableMedia
))
207 Log("<%s %s> is filtered for not removable.", CurDrive
->VendorId
, CurDrive
->ProductId
);
211 if (g_FilterUSB
&& CurDrive
->BusType
!= BusTypeUsb
)
213 Log("<%s %s> is filtered for not USB type.", CurDrive
->VendorId
, CurDrive
->ProductId
);
219 for (Letter
= 0; Letter
< LetterCount
; Letter
++)
221 if (PhyDriveId
[Letter
] == CurDrive
->PhyDrive
)
223 CurDrive
->FirstDriveLetter
= LogLetter
[Letter
];
228 if (IsVentoyPhyDrive(CurDrive
->PhyDrive
, CurDrive
->SizeInBytes
))
230 GetVentoyVerInPhyDrive(CurDrive
, CurDrive
->VentoyVersion
, sizeof(CurDrive
->VentoyVersion
));
235 for (i
= 0; i
< DriveCount
; i
++)
237 CurDrive
= pDriveList
+ i
;
238 if (CurDrive
->Id
< 0)
240 CurDrive
->PhyDrive
= 0x00FFFFFF;
247 PHY_DRIVE_INFO
* GetPhyDriveInfoById(int Id
)
250 for (i
= 0; i
< g_PhyDriveCount
; i
++)
252 if (g_PhyDriveList
[i
].Id
>= 0 && g_PhyDriveList
[i
].Id
== Id
)
254 return g_PhyDriveList
+ i
;
261 int Ventoy2DiskInit(void)
263 g_PhyDriveList
= (PHY_DRIVE_INFO
*)malloc(sizeof(PHY_DRIVE_INFO
)* VENTOY_MAX_PHY_DRIVE
);
264 if (NULL
== g_PhyDriveList
)
266 Log("Failed to alloc phy drive memory");
269 memset(g_PhyDriveList
, 0, sizeof(PHY_DRIVE_INFO
)* VENTOY_MAX_PHY_DRIVE
);
271 GetAllPhysicalDriveInfo(g_PhyDriveList
, &g_PhyDriveCount
);
272 FilterPhysicalDrive(g_PhyDriveList
, g_PhyDriveCount
);
277 int Ventoy2DiskDestroy(void)
279 free(g_PhyDriveList
);