source: trunk/src/kernel32/hmdisk.cpp@ 5786

Last change on this file since 5786 was 5786, checked in by sandervl, 24 years ago

fix for media not inserted

File size: 13.0 KB
Line 
1/* $Id: hmdisk.cpp,v 1.7 2001-05-23 17:00:44 sandervl Exp $ */
2
3/*
4 * Win32 Disk API functions for OS/2
5 *
6 * Copyright 2000 Sander van Leeuwen
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#include <os2win.h>
13#include <string.h>
14
15#include <misc.h>
16#include "hmdisk.h"
17#include "oslibdos.h"
18#include <win\winioctl.h>
19#include <win\ntddscsi.h>
20#include <win\wnaspi32.h>
21#include <win\aspi.h>
22
23#define DBG_LOCALLOG DBG_hmdisk
24#include "dbglocal.h"
25
26HMDeviceDiskClass::HMDeviceDiskClass(LPCSTR lpDeviceName) : HMDeviceKernelObjectClass(lpDeviceName)
27{
28 HMDeviceRegisterEx("\\\\.\\PHYSICALDRIVE", this, NULL);
29}
30
31/*****************************************************************************
32 * Name : HMDeviceDiskClass::FindDevice
33 * Purpose : Checks if lpDeviceName belongs to this device class
34 * Parameters: LPCSTR lpClassDevName
35 * LPCSTR lpDeviceName
36 * int namelength
37 * Variables :
38 * Result : checks if name is for a drive of physical disk
39 * Remark :
40 * Status :
41 *
42 * Author : SvL
43 *****************************************************************************/
44BOOL HMDeviceDiskClass::FindDevice(LPCSTR lpClassDevName, LPCSTR lpDeviceName, int namelength)
45{
46 //\\.\x: -> length 6
47 //\\.\PHYSICALDRIVEn -> length 18
48 if(namelength != 6 && namelength != 18) {
49 return FALSE;
50 }
51
52 //SvL: \\.\x: -> drive x (i.e. \\.\C:)
53 // \\.\PHYSICALDRIVEn -> drive n (n>=0)
54 if((strncmp(lpDeviceName, "\\\\.\\", 4) == 0) &&
55 namelength == 6 && lpDeviceName[5] == ':')
56 {
57 return TRUE;
58 }
59 if((strncmp(lpDeviceName, "\\\\.\\PHYSICALDRIVE", 17) == 0) && namelength == 18) {
60 return TRUE;
61 }
62 return FALSE;
63}
64//******************************************************************************
65//TODO: PHYSICALDRIVEn!!
66//******************************************************************************
67DWORD HMDeviceDiskClass::CreateFile (LPCSTR lpFileName,
68 PHMHANDLEDATA pHMHandleData,
69 PVOID lpSecurityAttributes,
70 PHMHANDLEDATA pHMHandleDataTemplate)
71{
72 HFILE hFile;
73 HFILE hTemplate;
74
75 dprintf2(("KERNEL32: HMDeviceDiskClass::CreateFile %s(%s,%08x,%08x,%08x)\n",
76 lpHMDeviceName,
77 lpFileName,
78 pHMHandleData,
79 lpSecurityAttributes,
80 pHMHandleDataTemplate));
81
82 //TODO: check in NT if CREATE_ALWAYS is allowed!!
83 if(pHMHandleData->dwCreation != OPEN_EXISTING) {
84 dprintf(("Invalid creation flags %x!!", pHMHandleData->dwCreation));
85 return ERROR_INVALID_PARAMETER;
86 }
87 if(strncmp(lpFileName, // "support" for local unc names
88 "\\\\.\\",
89 4) == 0)
90 {
91 lpFileName+=4;
92 }
93
94 //Disable error popus. NT allows an app to open a cdrom/dvd drive without a disk inside
95 //OS/2 fails in that case with error ERROR_NOT_READY
96 OSLibDosDisableHardError(TRUE);
97 hFile = OSLibDosCreateFile((LPSTR)lpFileName,
98 pHMHandleData->dwAccess,
99 pHMHandleData->dwShare,
100 (LPSECURITY_ATTRIBUTES)lpSecurityAttributes,
101 pHMHandleData->dwCreation,
102 pHMHandleData->dwFlags,
103 hTemplate);
104 OSLibDosDisableHardError(FALSE);
105
106 if (hFile != INVALID_HANDLE_ERROR || GetLastError() == ERROR_NOT_READY)
107 {
108 if(hFile == INVALID_HANDLE_ERROR) {
109 SetLastError(NO_ERROR);
110 pHMHandleData->hHMHandle = 0; //handle lookup fails if this is set to -1
111 }
112 else pHMHandleData->hHMHandle = hFile;
113
114 pHMHandleData->dwUserData = GetDriveTypeA(lpFileName);
115 return (NO_ERROR);
116 }
117 else {
118 dprintf(("CreateFile failed; error %d", GetLastError()));
119 return(GetLastError());
120 }
121}
122//******************************************************************************
123//******************************************************************************
124BOOL HMDeviceDiskClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
125{
126 if(pHMHandleData->hHMHandle) {
127 return OSLibDosClose(pHMHandleData->hHMHandle);
128 }
129 return TRUE;
130}
131//******************************************************************************
132//******************************************************************************
133BOOL HMDeviceDiskClass::DeviceIoControl(PHMHANDLEDATA pHMHandleData, DWORD dwIoControlCode,
134 LPVOID lpInBuffer, DWORD nInBufferSize,
135 LPVOID lpOutBuffer, DWORD nOutBufferSize,
136 LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped)
137{
138#ifdef DEBUG
139 char *msg = NULL;
140
141 switch(dwIoControlCode)
142 {
143 case FSCTL_DELETE_REPARSE_POINT:
144 msg = "FSCTL_DELETE_REPARSE_POINT";
145 break;
146 case FSCTL_DISMOUNT_VOLUME:
147 msg = "FSCTL_DISMOUNT_VOLUME";
148 break;
149 case FSCTL_GET_COMPRESSION:
150 msg = "FSCTL_GET_COMPRESSION";
151 break;
152 case FSCTL_GET_REPARSE_POINT:
153 msg = "FSCTL_GET_REPARSE_POINT";
154 break;
155 case FSCTL_LOCK_VOLUME:
156 msg = "FSCTL_LOCK_VOLUME";
157 break;
158 case FSCTL_QUERY_ALLOCATED_RANGES:
159 msg = "FSCTL_QUERY_ALLOCATED_RANGES";
160 break;
161 case FSCTL_SET_COMPRESSION:
162 msg = "FSCTL_SET_COMPRESSION";
163 break;
164 case FSCTL_SET_REPARSE_POINT:
165 msg = "FSCTL_SET_REPARSE_POINT";
166 break;
167 case FSCTL_SET_SPARSE:
168 msg = "FSCTL_SET_SPARSE";
169 break;
170 case FSCTL_SET_ZERO_DATA:
171 msg = "FSCTL_SET_ZERO_DATA";
172 break;
173 case FSCTL_UNLOCK_VOLUME:
174 msg = "FSCTL_UNLOCK_VOLUME";
175 break;
176 case IOCTL_DISK_CHECK_VERIFY:
177 msg = "IOCTL_DISK_CHECK_VERIFY";
178 break;
179 case IOCTL_DISK_EJECT_MEDIA:
180 msg = "IOCTL_DISK_EJECT_MEDIA";
181 break;
182 case IOCTL_DISK_FORMAT_TRACKS:
183 msg = "IOCTL_DISK_FORMAT_TRACKS";
184 break;
185 case IOCTL_DISK_GET_DRIVE_GEOMETRY:
186 msg = "IOCTL_DISK_GET_DRIVE_GEOMETRY";
187 break;
188 case IOCTL_DISK_GET_DRIVE_LAYOUT:
189 msg = "IOCTL_DISK_GET_DRIVE_LAYOUT";
190 break;
191 case IOCTL_DISK_GET_MEDIA_TYPES:
192 msg = "IOCTL_DISK_GET_MEDIA_TYPES";
193 break;
194 case IOCTL_DISK_GET_PARTITION_INFO:
195 msg = "IOCTL_DISK_GET_PARTITION_INFO";
196 break;
197 case IOCTL_DISK_LOAD_MEDIA:
198 msg = "IOCTL_DISK_LOAD_MEDIA";
199 break;
200 case IOCTL_DISK_MEDIA_REMOVAL:
201 msg = "IOCTL_DISK_MEDIA_REMOVAL";
202 break;
203 case IOCTL_DISK_PERFORMANCE:
204 msg = "IOCTL_DISK_PERFORMANCE";
205 break;
206 case IOCTL_DISK_REASSIGN_BLOCKS:
207 msg = "IOCTL_DISK_REASSIGN_BLOCKS";
208 break;
209 case IOCTL_DISK_SET_DRIVE_LAYOUT:
210 msg = "IOCTL_DISK_SET_DRIVE_LAYOUT";
211 break;
212 case IOCTL_DISK_SET_PARTITION_INFO:
213 msg = "IOCTL_DISK_SET_PARTITION_INFO";
214 break;
215 case IOCTL_DISK_VERIFY:
216 msg = "IOCTL_DISK_VERIFY";
217 break;
218 case IOCTL_SERIAL_LSRMST_INSERT:
219 msg = "IOCTL_SERIAL_LSRMST_INSERT";
220 break;
221 case IOCTL_STORAGE_CHECK_VERIFY:
222 msg = "IOCTL_STORAGE_CHECK_VERIFY";
223 break;
224 case IOCTL_STORAGE_EJECT_MEDIA:
225 msg = "IOCTL_STORAGE_EJECT_MEDIA";
226 break;
227 case IOCTL_STORAGE_GET_MEDIA_TYPES:
228 msg = "IOCTL_STORAGE_GET_MEDIA_TYPES";
229 break;
230 case IOCTL_STORAGE_LOAD_MEDIA:
231 msg = "IOCTL_STORAGE_LOAD_MEDIA";
232 break;
233 case IOCTL_STORAGE_MEDIA_REMOVAL:
234 msg = "IOCTL_STORAGE_MEDIA_REMOVAL";
235 break;
236 case IOCTL_SCSI_PASS_THROUGH:
237 msg = "IOCTL_SCSI_PASS_THROUGH";
238 break;
239 case IOCTL_SCSI_MINIPORT:
240 msg = "IOCTL_SCSI_MINIPORT";
241 break;
242 case IOCTL_SCSI_GET_INQUIRY_DATA:
243 msg = "IOCTL_SCSI_GET_INQUIRY_DATA";
244 break;
245 case IOCTL_SCSI_GET_CAPABILITIES:
246 msg = "IOCTL_SCSI_GET_CAPABILITIES";
247 break;
248 case IOCTL_SCSI_PASS_THROUGH_DIRECT:
249 msg = "IOCTL_SCSI_PASS_THROUGH_DIRECT";
250 break;
251 case IOCTL_SCSI_GET_ADDRESS:
252 msg = "IOCTL_SCSI_GET_ADDRESS";
253 break;
254 case IOCTL_SCSI_RESCAN_BUS:
255 msg = "IOCTL_SCSI_RESCAN_BUS";
256 break;
257 case IOCTL_SCSI_GET_DUMP_POINTERS:
258 msg = "IOCTL_SCSI_GET_DUMP_POINTERS";
259 break;
260 case IOCTL_SCSI_FREE_DUMP_POINTERS:
261 msg = "IOCTL_SCSI_FREE_DUMP_POINTERS";
262 break;
263 case IOCTL_IDE_PASS_THROUGH:
264 msg = "IOCTL_IDE_PASS_THROUGH";
265 break;
266 }
267 if(msg) {
268 dprintf(("HMDeviceDiskClass::DeviceIoControl %s", msg));
269 }
270#endif
271
272 switch(dwIoControlCode)
273 {
274 case FSCTL_DELETE_REPARSE_POINT:
275 case FSCTL_DISMOUNT_VOLUME:
276 case FSCTL_GET_COMPRESSION:
277 case FSCTL_GET_REPARSE_POINT:
278 case FSCTL_LOCK_VOLUME:
279 case FSCTL_QUERY_ALLOCATED_RANGES:
280 case FSCTL_SET_COMPRESSION:
281 case FSCTL_SET_REPARSE_POINT:
282 case FSCTL_SET_SPARSE:
283 case FSCTL_SET_ZERO_DATA:
284 case FSCTL_UNLOCK_VOLUME:
285 break;
286
287 case IOCTL_DISK_CHECK_VERIFY:
288 case IOCTL_DISK_EJECT_MEDIA:
289 case IOCTL_DISK_FORMAT_TRACKS:
290 case IOCTL_DISK_GET_DRIVE_GEOMETRY:
291 case IOCTL_DISK_GET_DRIVE_LAYOUT:
292 case IOCTL_DISK_GET_MEDIA_TYPES:
293 case IOCTL_DISK_GET_PARTITION_INFO:
294 case IOCTL_DISK_LOAD_MEDIA:
295 case IOCTL_DISK_MEDIA_REMOVAL:
296 case IOCTL_DISK_PERFORMANCE:
297 case IOCTL_DISK_REASSIGN_BLOCKS:
298 case IOCTL_DISK_SET_DRIVE_LAYOUT:
299 case IOCTL_DISK_SET_PARTITION_INFO:
300 case IOCTL_DISK_VERIFY:
301 case IOCTL_SERIAL_LSRMST_INSERT:
302 break;
303
304 case IOCTL_STORAGE_CHECK_VERIFY:
305 if(lpBytesReturned) {
306 lpBytesReturned = 0;
307 }
308 //TODO: check if disk has been inserted or removed
309 if(pHMHandleData->hHMHandle == 0) {
310 SetLastError(ERROR_NOT_READY);
311 return FALSE;
312 }
313 SetLastError(NO_ERROR);
314 return TRUE;
315
316 case IOCTL_STORAGE_EJECT_MEDIA:
317 case IOCTL_STORAGE_GET_MEDIA_TYPES:
318 case IOCTL_STORAGE_LOAD_MEDIA:
319 case IOCTL_STORAGE_MEDIA_REMOVAL:
320 break;
321 case IOCTL_SCSI_PASS_THROUGH:
322 case IOCTL_SCSI_MINIPORT:
323 case IOCTL_SCSI_GET_INQUIRY_DATA:
324 case IOCTL_SCSI_GET_CAPABILITIES:
325 case IOCTL_SCSI_PASS_THROUGH_DIRECT:
326 break;
327
328 case IOCTL_SCSI_GET_ADDRESS:
329 {
330 HINSTANCE hInstAspi;
331 DWORD (WIN32API *GetASPI32SupportInfo)();
332 DWORD (CDECL *SendASPI32Command)(LPSRB lpSRB);
333 DWORD numAdapters, rc;
334 SRB srb;
335 int i, j, k;
336
337 if(!lpOutBuffer || nOutBufferSize < 8) {
338 SetLastError(ERROR_INSUFFICIENT_BUFFER); //todo: right error?
339 return(FALSE);
340 }
341 SCSI_ADDRESS *addr = (SCSI_ADDRESS *)lpOutBuffer;
342 addr->Length = sizeof(SCSI_ADDRESS);
343 addr->PortNumber = 0;
344 addr->PathId = 0;
345 hInstAspi = LoadLibraryA("WNASPI32.DLL");
346 if(hInstAspi == NULL) {
347 SetLastError(ERROR_INVALID_PARAMETER); //todo
348 return FALSE;
349 }
350 *(FARPROC *)&GetASPI32SupportInfo = GetProcAddress(hInstAspi, "GetASPI32SupportInfo");
351 *(FARPROC *)&SendASPI32Command = GetProcAddress(hInstAspi, "SendASPI32Command");
352 numAdapters = GetASPI32SupportInfo();
353 if(LOBYTE(numAdapters) == 0) goto failure;
354
355 memset(&srb, 0, sizeof(srb));
356 srb.common.SRB_Cmd = SC_HA_INQUIRY;
357 rc = SendASPI32Command(&srb);
358
359 for(i=0;i<LOBYTE(numAdapters);i++) {
360 for(j=0;j<8;j++) {
361 for(k=0;k<16;k++) {
362 memset(&srb, 0, sizeof(srb));
363 srb.common.SRB_Cmd = SC_GET_DEV_TYPE;
364 srb.devtype.SRB_HaId = i;
365 srb.devtype.SRB_Target = j;
366 srb.devtype.SRB_Lun = k;
367 rc = SendASPI32Command(&srb);
368 if(rc == SS_COMP) {
369 if(srb.devtype.SRB_DeviceType == SS_DEVTYPE_CDROM &&
370 pHMHandleData->dwUserData == DRIVE_CDROM)
371 {
372 goto done;
373 }
374 }
375 }
376 }
377 }
378done:
379 if(rc == SS_COMP) {
380 addr->TargetId = j;
381 addr->Lun = k;
382 SetLastError(ERROR_SUCCESS);
383 }
384 else SetLastError(ERROR_FILE_NOT_FOUND); //todo
385 FreeLibrary(hInstAspi);
386 return TRUE;
387failure:
388 FreeLibrary(hInstAspi);
389 SetLastError(ERROR_INVALID_PARAMETER); //todo
390 return FALSE;
391 }
392
393 case IOCTL_SCSI_RESCAN_BUS:
394 case IOCTL_SCSI_GET_DUMP_POINTERS:
395 case IOCTL_SCSI_FREE_DUMP_POINTERS:
396 case IOCTL_IDE_PASS_THROUGH:
397 break;
398
399 }
400 dprintf(("HMDeviceDiskClass::DeviceIoControl: unimplemented dwIoControlCode=%08lx\n", dwIoControlCode));
401 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
402 return FALSE;
403}
404//******************************************************************************
405//******************************************************************************
Note: See TracBrowser for help on using the repository browser.