Documented GVF_SAVE_VAR alongside other flags, and removed a query/doubt
[AROS.git] / arch / all-mingw32 / devs / hostdisk / hostdisk_host.c
bloba106dbc0890384870c92c4c15d03c7c1ebe9d797
1 /*
2 Copyright © 1995-2014, The AROS Development Team. All rights reserved.
3 $Id$
4 */
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)
18 switch(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;*/
29 default:
30 return TDERR_NotSpecified;
34 ULONG Host_Open(struct unit *Unit)
36 ULONG attrs;
39 Forbid();
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);
43 Permit();
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));
57 return 0;
60 void Host_Close(struct unit *Unit)
62 Forbid();
63 Unit->hdskBase->iface->CloseHandle(Unit->file);
64 Permit();
67 LONG Host_Read(struct unit *Unit, APTR buf, ULONG size, ULONG *ioerr)
69 ULONG resSize;
70 ULONG ret;
71 ULONG err;
73 Forbid();
74 ret = Unit->hdskBase->iface->ReadFile(Unit->file, buf, size, &resSize, NULL);
75 err = Unit->hdskBase->iface->GetLastError();
76 Permit();
78 if (ret)
80 DB2(bug("hostdisk: Host_Read(0x%p, 0x%08X): Success\n", buf, size));
81 return resSize;
84 D(bug("hostdisk: Host_Read(0x%p, 0x%08X): Windows error %u\n", buf, size, err));
86 *ioerr = error(err);
87 return -1;
90 LONG Host_Write(struct unit *Unit, APTR buf, ULONG size, ULONG *ioerr)
92 ULONG resSize;
93 ULONG ret;
94 ULONG err;
96 Forbid();
97 ret = Unit->hdskBase->iface->WriteFile(Unit->file, buf, size, &resSize, NULL);
98 err = Unit->hdskBase->iface->GetLastError();
99 Permit();
101 if (ret)
102 return resSize;
104 *ioerr = error(err);
105 return -1;
108 ULONG Host_Seek(struct unit *Unit, ULONG pos)
110 ULONG ret;
112 Forbid();
113 ret = Unit->hdskBase->iface->SetFilePointer(Unit->file, pos, NULL, FILE_BEGIN);
114 Permit();
116 if (ret != -1)
117 return 0;
119 return TDERR_SeekError;
122 ULONG Host_Seek64(struct unit *Unit, ULONG pos, ULONG pos_hi)
124 ULONG ret;
126 Forbid();
127 ret = Unit->hdskBase->iface->SetFilePointer(Unit->file, pos, &pos_hi, FILE_BEGIN);
128 Permit();
130 if (ret != -1)
131 return 0;
133 return TDERR_SeekError;
136 ULONG Host_GetGeometry(struct unit *Unit, struct DriveGeometry *dg)
138 ULONG len, err;
139 DISK_GEOMETRY geom;
140 ULONG ret;
142 if (Unit->flags & UNIT_DEVICE)
144 Forbid();
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();
148 Permit();
150 D(bug("hostdisk: IOCTL_DISK_GET_DRIVE_GEOMETRY result: %d\n", len));
151 if (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));
165 return 0;
168 else
170 ULONG len64 = 0;
172 Forbid();
173 len = Unit->hdskBase->iface->GetFileSize(Unit->file, &len64);
174 err = Unit->hdskBase->iface->GetLastError();
175 Permit();
177 D(bug("hostdisk: Image file length: %d\n", len));
178 if (len != -1)
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 */
183 return 0;
187 D(bug("hostdisk: Host_GetGeometry(): Windows error %u\n", err));
188 return error(err);
191 int Host_ProbeGeometry(struct HostDiskBase *hdskBase, char *name, struct DriveGeometry *dg)
193 /* TODO: Implement this */
194 return -1;
198 static const char *KernelSymbols[] = {
199 "CreateFileA",
200 "CloseHandle",
201 "ReadFile",
202 "WriteFile",
203 "SetFilePointer",
204 "GetFileAttributesA",
205 "GetFileSize",
206 "DeviceIoControl",
207 "GetLastError",
208 NULL
211 static int Host_Init(struct HostDiskBase *hdskBase)
213 ULONG r;
215 hdskBase->KernelHandle = HostLib_Open("kernel32.dll", NULL);
216 if (!hdskBase->KernelHandle)
217 return FALSE;
219 hdskBase->iface = (struct HostInterface *)HostLib_GetInterface(hdskBase->KernelHandle, KernelSymbols, &r);
220 if ((!hdskBase->iface) || r)
221 return FALSE;
223 hdskBase->DiskDevice = "\\\\.\\PhysicalDrive%ld";
225 return TRUE;
228 ADD2INITLIB(Host_Init, 0)