mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
216 lines
5.8 KiB
C++
216 lines
5.8 KiB
C++
|
|
|
|
/* Determines if this drive-letter currently has a disk inserted */
|
|
int CheckRM (const TCHAR *DriveName)
|
|
{
|
|
TCHAR filename[MAX_DPATH];
|
|
DWORD dwHold;
|
|
BOOL result = FALSE;
|
|
|
|
_stprintf (filename, _T("\\\\?\\%s"), DriveName);
|
|
dwHold = GetFileAttributes (filename);
|
|
if(dwHold != 0xFFFFFFFF)
|
|
result = TRUE;
|
|
return result;
|
|
}
|
|
|
|
/* This function makes sure the volume-name being requested is not already in use, or any of the following
|
|
illegal values: */
|
|
static const TCHAR *illegal_volumenames[] = { _T("SYS"), _T("DEVS"), _T("LIBS"), _T("FONTS"), _T("C"), _T("L"), _T("S") };
|
|
|
|
static int valid_volumename (struct uaedev_mount_info *mountinfo, const TCHAR *volumename, int fullcheck)
|
|
{
|
|
int i, result = 1, illegal_count = sizeof (illegal_volumenames) / sizeof(TCHAR*);
|
|
for (i = 0; i < illegal_count; i++) {
|
|
if(_tcscmp (volumename, illegal_volumenames[i]) == 0) {
|
|
result = 0;
|
|
break;
|
|
}
|
|
}
|
|
/* if result is still good, we've passed the illegal names check, and must check for duplicates now */
|
|
if(result && fullcheck) {
|
|
for (i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
|
|
if (mountinfo->ui[i].open && mountinfo->ui[i].volname && _tcsicmp (mountinfo->ui[i].volname, volumename) == 0) {
|
|
result = 0;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/* Returns 1 if an actual volume-name was found, 2 if no volume-name (so uses some defaults) */
|
|
int target_get_volume_name (struct uaedev_mount_info *mtinf, struct uaedev_config_info *ci, bool inserted, bool fullcheck, int cnt)
|
|
{
|
|
int result = 2;
|
|
int drivetype;
|
|
|
|
drivetype = GetDriveType (ci->rootdir);
|
|
if (inserted) {
|
|
if (GetVolumeInformation (ci->rootdir, ci->volname, sizeof ci->volname / sizeof (TCHAR), NULL, NULL, NULL, NULL, 0)) {
|
|
if (ci->volname[0] && valid_volumename(mtinf, ci->volname, fullcheck)) {
|
|
result = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(result == 2) {
|
|
switch(drivetype)
|
|
{
|
|
case DRIVE_FIXED:
|
|
_stprintf (ci->volname, _T("WinDH_%c"), ci->rootdir[0]);
|
|
break;
|
|
case DRIVE_CDROM:
|
|
_stprintf (ci->volname, _T("WinCD_%c"), ci->rootdir[0]);
|
|
break;
|
|
case DRIVE_REMOVABLE:
|
|
_stprintf (ci->volname, _T("WinRMV_%c"), ci->rootdir[0]);
|
|
break;
|
|
case DRIVE_REMOTE:
|
|
_stprintf (ci->volname, _T("WinNET_%c"), ci->rootdir[0]);
|
|
break;
|
|
case DRIVE_RAMDISK:
|
|
_stprintf (ci->volname, _T("WinRAM_%c"), ci->rootdir[0]);
|
|
break;
|
|
case DRIVE_UNKNOWN:
|
|
case DRIVE_NO_ROOT_DIR:
|
|
default:
|
|
result = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (cnt >= 0) {
|
|
switch (drivetype)
|
|
{
|
|
case DRIVE_REMOTE:
|
|
_stprintf(ci->devname, _T("NDH%d"), cnt);
|
|
break;
|
|
case DRIVE_CDROM:
|
|
_stprintf(ci->devname, _T("CDH%d"), cnt);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static int getidfromhandle (HANDLE h)
|
|
{
|
|
int drvnum = -1;
|
|
DWORD written, outsize;
|
|
VOLUME_DISK_EXTENTS *vde;
|
|
|
|
outsize = sizeof (VOLUME_DISK_EXTENTS) + sizeof (DISK_EXTENT) * 32;
|
|
vde = (VOLUME_DISK_EXTENTS*)xmalloc (uae_u8, outsize);
|
|
if (DeviceIoControl (h, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, vde, outsize, &written, NULL)) {
|
|
if (vde->NumberOfDiskExtents > 0)
|
|
drvnum = vde->Extents[0].DiskNumber;
|
|
}
|
|
xfree (vde);
|
|
return drvnum;
|
|
}
|
|
|
|
HANDLE hdf_get_real_handle(struct hardfilehandle *h);
|
|
|
|
static int hfdcheck (TCHAR drive)
|
|
{
|
|
HANDLE h;
|
|
TCHAR tmp[16];
|
|
int disknum;
|
|
|
|
_stprintf (tmp, _T("\\\\.\\%c:"), drive);
|
|
h = CreateFile (tmp, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
if (h == INVALID_HANDLE_VALUE)
|
|
return 0;
|
|
disknum = getidfromhandle (h);
|
|
CloseHandle (h);
|
|
#if 0
|
|
for (int i = 0; i < MAX_FILESYSTEM_UNITS; i++) {
|
|
struct hardfiledata *hfd = get_hardfile_data (i);
|
|
int reopen = 0;
|
|
if (!hfd || !(hfd->flags & HFD_FLAGS_REALDRIVE) || !hfd->handle_valid)
|
|
continue;
|
|
HANDLE h2 = hdf_get_real_handle(hfd->handle);
|
|
if (h2) {
|
|
if (getidfromhandle (h2) == disknum)
|
|
return 1;
|
|
}
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
void filesys_addexternals (void)
|
|
{
|
|
int drive, drivetype;
|
|
UINT errormode;
|
|
DWORD dwDriveMask;
|
|
int drvnum = 0;
|
|
int cnt = 0;
|
|
|
|
if (!currprefs.win32_automount_cddrives && !currprefs.win32_automount_netdrives
|
|
&& !currprefs.win32_automount_drives && !currprefs.win32_automount_removabledrives)
|
|
return;
|
|
errormode = SetErrorMode (SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
|
|
dwDriveMask = GetLogicalDrives ();
|
|
dwDriveMask >>= 2; // Skip A and B drives...
|
|
|
|
for(drive = 'C'; drive <= 'Z'; ++drive) {
|
|
struct uaedev_config_info ci = { 0 };
|
|
_stprintf (ci.rootdir, _T("%c:\\"), drive);
|
|
/* Is this drive-letter valid (it used to check for media in drive) */
|
|
if(dwDriveMask & 1) {
|
|
bool inserted = CheckRM (ci.rootdir) != 0; /* Is there a disk inserted? */
|
|
int nok = FALSE;
|
|
int rw = 1;
|
|
|
|
drivetype = GetDriveType (ci.rootdir);
|
|
if (inserted && drivetype != DRIVE_NO_ROOT_DIR && drivetype != DRIVE_UNKNOWN) {
|
|
if (hfdcheck (drive)) {
|
|
write_log (_T("Drive %c:\\ ignored, was configured as a harddrive\n"), drive);
|
|
continue;
|
|
}
|
|
}
|
|
for (;;) {
|
|
if (!inserted) {
|
|
nok = TRUE;
|
|
break;
|
|
}
|
|
if (drivetype == DRIVE_REMOTE && currprefs.win32_automount_netdrives)
|
|
break;
|
|
if (drivetype == DRIVE_FIXED && currprefs.win32_automount_drives)
|
|
break;
|
|
if (drivetype == DRIVE_REMOVABLE && currprefs.win32_automount_removabledrives)
|
|
break;
|
|
nok = TRUE;
|
|
break;
|
|
}
|
|
if (nok)
|
|
continue;
|
|
if (inserted) {
|
|
target_get_volume_name (&mountinfo, &ci, inserted, true, cnt++);
|
|
if (!ci.volname[0])
|
|
_stprintf (ci.volname, _T("WinUNK_%c"), drive);
|
|
}
|
|
if (drivetype == DRIVE_REMOTE)
|
|
_tcscat (ci.rootdir, _T("."));
|
|
else
|
|
_tcscat (ci.rootdir, _T(".."));
|
|
#if 0
|
|
if (currprefs.win32_automount_drives > 1) {
|
|
devname[0] = drive;
|
|
devname[1] = 0;
|
|
}
|
|
#endif
|
|
ci.readonly = !rw;
|
|
ci.bootpri = -20 - drvnum;
|
|
//write_log (_T("Drive type %d: '%s' '%s'\n"), drivetype, volumepath, volumename);
|
|
add_filesys_unit (&ci, true);
|
|
drvnum++;
|
|
} /* if drivemask */
|
|
dwDriveMask >>= 1;
|
|
}
|
|
SetErrorMode (errormode);
|
|
}
|