2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
6 #include <aros/debug.h>
7 #include <aros/symbolsets.h>
8 #include <devices/trackdisk.h>
9 #include <exec/errors.h>
10 #include <proto/exec.h>
11 #include <proto/hostlib.h>
13 #include "hostdisk_host.h"
14 #include "hostdisk_device.h"
16 static ULONG
error(ULONG winerr
)
20 case ERROR_INVALID_PARAMETER
:
21 return IOERR_BADADDRESS
;
23 case ERROR_WRITE_PROTECT
:
24 return TDERR_WriteProt
;
26 /* case ERROR_NO_DISK:
27 return TDERR_DiskChanged;*/
30 return TDERR_NotSpecified
;
34 ULONG
Host_Open(struct unit
*Unit
)
40 attrs
= Unit
->hdskBase
->iface
->GetFileAttributes(Unit
->filename
);
41 Unit
->file
= Unit
->hdskBase
->iface
->CreateFile(Unit
->filename
, GENERIC_READ
|GENERIC_WRITE
, FILE_SHARE_READ
|FILE_SHARE_WRITE
,
42 NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
45 if (Unit
->file
== (APTR
)-1)
46 return TDERR_NotSpecified
;
49 * GetFileAttributes() on a device returns FILE_ATTRIBUTE_READONLY flag set,
50 * however we still can open the device for writing.
51 if (attrs & FILE_ATTRIBUTE_READONLY)
52 Unit->flags |= UNIT_READONLY; */
53 if (attrs
& FILE_ATTRIBUTE_DEVICE
)
54 Unit
->flags
|= UNIT_DEVICE
;
56 D(bug("hostdisk: Unit flags 0x%02X\n", Unit
->flags
));
60 void Host_Close(struct unit
*Unit
)
63 Unit
->hdskBase
->iface
->CloseHandle(Unit
->file
);
67 LONG
Host_Read(struct unit
*Unit
, APTR buf
, ULONG size
, ULONG
*ioerr
)
74 ret
= Unit
->hdskBase
->iface
->ReadFile(Unit
->file
, buf
, size
, &resSize
, NULL
);
75 err
= Unit
->hdskBase
->iface
->GetLastError();
80 DB2(bug("hostdisk: Host_Read(0x%p, 0x%08X): Success\n", buf
, size
));
84 D(bug("hostdisk: Host_Read(0x%p, 0x%08X): Windows error %u\n", buf
, size
, err
));
90 LONG
Host_Write(struct unit
*Unit
, APTR buf
, ULONG size
, ULONG
*ioerr
)
97 ret
= Unit
->hdskBase
->iface
->WriteFile(Unit
->file
, buf
, size
, &resSize
, NULL
);
98 err
= Unit
->hdskBase
->iface
->GetLastError();
108 ULONG
Host_Seek(struct unit
*Unit
, ULONG pos
)
113 ret
= Unit
->hdskBase
->iface
->SetFilePointer(Unit
->file
, pos
, NULL
, FILE_BEGIN
);
119 return TDERR_SeekError
;
122 ULONG
Host_Seek64(struct unit
*Unit
, ULONG pos
, ULONG pos_hi
)
127 ret
= Unit
->hdskBase
->iface
->SetFilePointer(Unit
->file
, pos
, &pos_hi
, FILE_BEGIN
);
133 return TDERR_SeekError
;
136 ULONG
Host_GetGeometry(struct unit
*Unit
, struct DriveGeometry
*dg
)
142 if (Unit
->flags
& UNIT_DEVICE
)
145 len
= Unit
->hdskBase
->iface
->DeviceIoControl(Unit
->file
, IOCTL_DISK_GET_DRIVE_GEOMETRY
, NULL
, 0,
146 &geom
, sizeof(geom
), &ret
, NULL
);
147 err
= Unit
->hdskBase
->iface
->GetLastError();
150 D(bug("hostdisk: IOCTL_DISK_GET_DRIVE_GEOMETRY result: %d\n", len
));
153 dg
->dg_SectorSize
= geom
.BytesPerSector
;
154 dg
->dg_Heads
= geom
.TracksPerCylinder
;
155 dg
->dg_TrackSectors
= geom
.SectorsPerTrack
;
156 dg
->dg_Cylinders
= geom
.Cylinders
;
157 dg
->dg_CylSectors
= dg
->dg_TrackSectors
* dg
->dg_Heads
;
158 dg
->dg_TotalSectors
= dg
->dg_CylSectors
* dg
->dg_Cylinders
;
160 D(bug("hostdisk: Sector size : %u\n", dg
->dg_SectorSize
));
161 D(bug("hostdisk: Heads : %u\n", dg
->dg_Heads
));
162 D(bug("hostdisk: Sectors per track: %u\n", dg
->dg_TrackSectors
));
163 D(bug("hostdisk: Cylinders : %u\n", dg
->dg_Cylinders
));
173 len
= Unit
->hdskBase
->iface
->GetFileSize(Unit
->file
, &len64
);
174 err
= Unit
->hdskBase
->iface
->GetLastError();
177 D(bug("hostdisk: Image file length: %d\n", len
));
180 dg
->dg_TotalSectors
= (len
>> 9) | (len64
<< 23); /* This relies on the fact that SectorSize == 512) */
181 dg
->dg_Cylinders
= dg
->dg_TotalSectors
; /* LBA, CylSectors == 1 */
187 D(bug("hostdisk: Host_GetGeometry(): Windows error %u\n", err
));
191 int Host_ProbeGeometry(struct HostDiskBase
*hdskBase
, char *name
, struct DriveGeometry
*dg
)
193 /* TODO: Implement this */
198 static const char *KernelSymbols
[] = {
204 "GetFileAttributesA",
211 static int Host_Init(struct HostDiskBase
*hdskBase
)
215 hdskBase
->KernelHandle
= HostLib_Open("kernel32.dll", NULL
);
216 if (!hdskBase
->KernelHandle
)
219 hdskBase
->iface
= (struct HostInterface
*)HostLib_GetInterface(hdskBase
->KernelHandle
, KernelSymbols
, &r
);
220 if ((!hdskBase
->iface
) || r
)
223 hdskBase
->DiskDevice
= "\\\\.\\PhysicalDrive%ld";
228 ADD2INITLIB(Host_Init
, 0)