source: trunk/src/kernel32/osliblvm.cpp@ 8397

Last change on this file since 8397 was 8397, checked in by sandervl, 23 years ago

volume api updates (LVM)

File size: 22.4 KB
Line 
1/* $Id: osliblvm.cpp,v 1.1 2002-05-09 13:55:34 sandervl Exp $ */
2
3/*
4 * OS/2 LVM (Logical Volume Management) functions
5 *
6 * Copyright 2002 Sander van Leeuwen
7 *
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 */
11#define INCL_DOSPROCESS
12#define INCL_DOSSEMAPHORES
13#define INCL_DOSQUEUES
14#define INCL_DOSMODULEMGR
15#define INCL_DOSEXCEPTIONS
16#define INCL_DOSERRORS
17#include <os2wrap.h>
18#include <stdlib.h>
19#include <string.h>
20#include <dbglog.h>
21#include <win32type.h>
22#include <winconst.h>
23#include <win\winioctl.h>
24#include "osliblvm.h"
25
26
27#define DBG_LOCALLOG DBG_osliblvm
28#include "dbglocal.h"
29
30static void (* SYSTEM pfnOpen_LVM_Engine)( BOOLEAN Ignore_CHS, CARDINAL32 * Error_Code );
31static void (* SYSTEM pfnClose_LVM_Engine) ( void );
32static Drive_Control_Array (* SYSTEM pfnGet_Drive_Control_Data)( CARDINAL32 * Error_Code );
33static Drive_Information_Record (* SYSTEM pfnGet_Drive_Status)( ULONG Drive_Handle, CARDINAL32 * Error_Code );
34static Partition_Information_Array (* SYSTEM pfnGet_Partitions)( ULONG Handle, CARDINAL32 * Error_Code );
35static ULONG (* SYSTEM pfnGet_Partition_Handle)( CARDINAL32 Serial_Number, CARDINAL32 * Error_Code );
36static Partition_Information_Record (* SYSTEM pfnGet_Partition_Information)( ULONG Partition_Handle, CARDINAL32 * Error_Code );
37static Volume_Control_Array (* SYSTEM pfnGet_Volume_Control_Data)( CARDINAL32 * Error_Code );
38static Volume_Information_Record (* SYSTEM pfnGet_Volume_Information)( ULONG Volume_Handle, CARDINAL32 * Error_Code );
39static void (* SYSTEM pfnFree_Engine_Memory)( ULONG Object );
40static void (* SYSTEM pfnRead_Sectors) ( CARDINAL32 Drive_Number,
41 LBA Starting_Sector,
42 CARDINAL32 Sectors_To_Read,
43 ULONG Buffer,
44 CARDINAL32 * Error);
45static void (* SYSTEM pfnWrite_Sectors) ( CARDINAL32 Drive_Number,
46 LBA Starting_Sector,
47 CARDINAL32 Sectors_To_Write,
48 ULONG Buffer,
49 CARDINAL32 * Error);
50
51static HMODULE hModLVM = 0;
52static BOOL fLVMOpened = FALSE;
53
54//******************************************************************************
55//******************************************************************************
56static void Open_LVM_Engine( BOOLEAN Ignore_CHS, CARDINAL32 * Error_Code )
57{
58 USHORT sel;
59
60 sel = RestoreOS2FS();
61 pfnOpen_LVM_Engine(Ignore_CHS, Error_Code);
62 SetFS(sel);
63 return;
64}
65//******************************************************************************
66//******************************************************************************
67static void Close_LVM_Engine ( void )
68{
69 USHORT sel;
70
71 sel = RestoreOS2FS();
72 pfnClose_LVM_Engine();
73 SetFS(sel);
74 return;
75}
76//******************************************************************************
77//******************************************************************************
78static Drive_Control_Array Get_Drive_Control_Data( CARDINAL32 * Error_Code )
79{
80 Drive_Control_Array ret;
81 USHORT sel;
82
83 sel = RestoreOS2FS();
84 ret = pfnGet_Drive_Control_Data(Error_Code);
85 SetFS(sel);
86 return ret;
87}
88//******************************************************************************
89//******************************************************************************
90static Drive_Information_Record Get_Drive_Status( ULONG Drive_Handle, CARDINAL32 * Error_Code )
91{
92 Drive_Information_Record ret;
93 USHORT sel;
94
95 sel = RestoreOS2FS();
96 ret = pfnGet_Drive_Status(Drive_Handle, Error_Code);
97 SetFS(sel);
98 return ret;
99}
100//******************************************************************************
101//******************************************************************************
102static Partition_Information_Array Get_Partitions( ULONG Handle, CARDINAL32 * Error_Code )
103{
104 Partition_Information_Array ret;
105 USHORT sel;
106
107 sel = RestoreOS2FS();
108 ret = pfnGet_Partitions(Handle, Error_Code);
109 SetFS(sel);
110 return ret;
111}
112//******************************************************************************
113//******************************************************************************
114static ULONG Get_Partition_Handle( CARDINAL32 Serial_Number, CARDINAL32 * Error_Code )
115{
116 ULONG ret;
117 USHORT sel;
118
119 sel = RestoreOS2FS();
120 ret = pfnGet_Partition_Handle(Serial_Number, Error_Code);
121 SetFS(sel);
122 return ret;
123}
124//******************************************************************************
125//******************************************************************************
126static Partition_Information_Record Get_Partition_Information( ULONG Partition_Handle, CARDINAL32 * Error_Code )
127{
128 Partition_Information_Record ret;
129 USHORT sel;
130
131 sel = RestoreOS2FS();
132 ret = pfnGet_Partition_Information(Partition_Handle, Error_Code);
133 SetFS(sel);
134 return ret;
135}
136//******************************************************************************
137//******************************************************************************
138static Volume_Control_Array Get_Volume_Control_Data( CARDINAL32 * Error_Code )
139{
140 Volume_Control_Array ret;
141 USHORT sel;
142
143 sel = RestoreOS2FS();
144 ret = pfnGet_Volume_Control_Data(Error_Code);
145 SetFS(sel);
146 return ret;
147}
148//******************************************************************************
149//******************************************************************************
150static Volume_Information_Record Get_Volume_Information( ULONG Volume_Handle, CARDINAL32 * Error_Code )
151{
152 Volume_Information_Record ret;
153 USHORT sel;
154
155 sel = RestoreOS2FS();
156 ret = pfnGet_Volume_Information(Volume_Handle, Error_Code);
157 SetFS(sel);
158 return ret;
159}
160//******************************************************************************
161//******************************************************************************
162static void Free_Engine_Memory( ULONG Object )
163{
164 USHORT sel;
165
166 sel = RestoreOS2FS();
167 pfnFree_Engine_Memory(Object);
168 SetFS(sel);
169 return;
170}
171//******************************************************************************
172//******************************************************************************
173static void Read_Sectors ( CARDINAL32 Drive_Number,
174 LBA Starting_Sector,
175 CARDINAL32 Sectors_To_Read,
176 ULONG Buffer,
177 CARDINAL32 * Error)
178{
179 USHORT sel;
180
181 sel = RestoreOS2FS();
182 pfnRead_Sectors(Drive_Number, Starting_Sector, Sectors_To_Read, Buffer, Error);
183 SetFS(sel);
184 return;
185}
186//******************************************************************************
187//******************************************************************************
188static void Write_Sectors ( CARDINAL32 Drive_Number,
189 LBA Starting_Sector,
190 CARDINAL32 Sectors_To_Write,
191 ULONG Buffer,
192 CARDINAL32 * Error)
193{
194 USHORT sel;
195
196 sel = RestoreOS2FS();
197 pfnWrite_Sectors(Drive_Number, Starting_Sector, Sectors_To_Write, Buffer, Error);
198 SetFS(sel);
199 return;
200}
201//******************************************************************************
202//******************************************************************************
203BOOL OSLibLVMInit()
204{
205 APIRET rc;
206 CHAR szModuleFailure[CCHMAXPATH];
207
208 rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), "LVM.DLL", (HMODULE *)&hModLVM);
209 if(rc) {
210 return FALSE;
211 }
212 rc = DosQueryProcAddr(hModLVM, 0, "Open_LVM_Engine", (PFN *)&pfnOpen_LVM_Engine);
213 if(rc) goto fail;
214 rc = DosQueryProcAddr(hModLVM, 0, "Close_LVM_Engine", (PFN *)&pfnClose_LVM_Engine);
215 if(rc) goto fail;
216 rc = DosQueryProcAddr(hModLVM, 0, "Get_Drive_Control_Data", (PFN *)&pfnGet_Drive_Control_Data);
217 if(rc) goto fail;
218 rc = DosQueryProcAddr(hModLVM, 0, "Get_Drive_Status", (PFN *)&pfnGet_Drive_Status);
219 if(rc) goto fail;
220 rc = DosQueryProcAddr(hModLVM, 0, "Get_Partitions", (PFN *)&pfnGet_Partitions);
221 if(rc) goto fail;
222 rc = DosQueryProcAddr(hModLVM, 0, "Get_Partition_Handle", (PFN *)&pfnGet_Partition_Handle);
223 if(rc) goto fail;
224 rc = DosQueryProcAddr(hModLVM, 0, "Get_Partition_Information", (PFN *)&pfnGet_Partition_Information);
225 if(rc) goto fail;
226 rc = DosQueryProcAddr(hModLVM, 0, "Get_Volume_Control_Data", (PFN *)&pfnGet_Volume_Control_Data);
227 if(rc) goto fail;
228 rc = DosQueryProcAddr(hModLVM, 0, "Get_Volume_Information", (PFN *)&pfnGet_Volume_Information);
229 if(rc) goto fail;
230 rc = DosQueryProcAddr(hModLVM, 0, "Free_Engine_Memory", (PFN *)&pfnFree_Engine_Memory);
231 if(rc) goto fail;
232 rc = DosQueryProcAddr(hModLVM, 0, "Read_Sectors", (PFN *)&pfnRead_Sectors);
233 if(rc) goto fail;
234 rc = DosQueryProcAddr(hModLVM, 0, "Write_Sectors", (PFN *)&pfnWrite_Sectors);
235 if(rc) goto fail;
236
237 return TRUE;
238
239fail:
240 if(hModLVM) {
241 DosFreeModule(hModLVM);
242 hModLVM = 0;
243 }
244 return FALSE;
245}
246//******************************************************************************
247//******************************************************************************
248void OSLibLVMExit()
249{
250 if(fLVMOpened) {
251 Close_LVM_Engine();
252 }
253 if(hModLVM) {
254 DosFreeModule(hModLVM);
255 hModLVM = 0;
256 }
257}
258//******************************************************************************
259//******************************************************************************
260HANDLE OSLibLVMQueryVolumeControlData()
261{
262 Volume_Control_Array *volctrl;
263 CARDINAL32 lasterror;
264
265 if(!hModLVM) {
266 dprintf(("LVM dll not loaded -> fail"));
267 return 0;
268 }
269
270 if(!fLVMOpened) {
271 Open_LVM_Engine(FALSE, &lasterror);
272 if(lasterror != LVM_ENGINE_NO_ERROR) {
273 DebugInt3();
274 return 0;
275 }
276 dprintf(("LVM engine opened"));
277 fLVMOpened = TRUE;
278 }
279
280 volctrl = (Volume_Control_Array *)malloc(sizeof(Volume_Control_Array));
281 if(volctrl == NULL) {
282 DebugInt3();
283 return 0;
284 }
285 *volctrl = Get_Volume_Control_Data(&lasterror);
286 if(lasterror != LVM_ENGINE_NO_ERROR) {
287 DebugInt3();
288 return 0;
289 }
290 return (HANDLE)volctrl;
291}
292//******************************************************************************
293//******************************************************************************
294void OSLibLVMFreeVolumeControlData(HANDLE hVolumeControlData)
295{
296 Volume_Control_Array *volctrl = (Volume_Control_Array *)hVolumeControlData;
297
298 if(volctrl == NULL) {
299 DebugInt3();
300 return;
301 }
302 Free_Engine_Memory((ULONG)volctrl->Volume_Control_Data);
303 free(volctrl);
304}
305//******************************************************************************
306//******************************************************************************
307BOOL OSLibLVMQueryVolumeName(HANDLE hVolumeControlData, ULONG volindex,
308 LPSTR lpszVolumeName, DWORD cchBufferLength)
309{
310 Volume_Control_Array *volctrl = (Volume_Control_Array *)hVolumeControlData;
311 Volume_Information_Record volinfo;
312 CARDINAL32 lasterror;
313
314 if(volctrl == NULL) {
315 DebugInt3();
316 return FALSE;
317 }
318 if(volindex >= volctrl->Count) {
319 return FALSE; //no more volumes
320 }
321 volinfo = Get_Volume_Information(volctrl->Volume_Control_Data[volindex].Volume_Handle, &lasterror);
322 if(lasterror != LVM_ENGINE_NO_ERROR) {
323 DebugInt3();
324 return FALSE;
325 }
326 strncpy(lpszVolumeName, volinfo.Volume_Name, min(sizeof(volinfo.Volume_Name), cchBufferLength)-1);
327 return TRUE;
328}
329//******************************************************************************
330//******************************************************************************
331static Volume_Information_Record OSLibLVMFindVolumeFromDriveLetter(ULONG driveLetter,
332 Volume_Control_Record *pVolRec,
333 CARDINAL32 *lasterror)
334{
335 Volume_Control_Array *volctrl;
336 Volume_Information_Record volinfo;
337
338 volctrl = (Volume_Control_Array *) OSLibLVMQueryVolumeControlData();
339 if(volctrl == NULL) {
340 DebugInt3();
341 return volinfo;
342 }
343 for(int i=0;i<volctrl->Count;i++) {
344 volinfo = Get_Volume_Information(volctrl->Volume_Control_Data[i].Volume_Handle, lasterror);
345 if(*lasterror != LVM_ENGINE_NO_ERROR) {
346 goto fail;
347 }
348 if(volinfo.Current_Drive_Letter == (char) ('A' + driveLetter)) {
349 break;
350 }
351 }
352 if(i == volctrl->Count) goto fail;
353
354 if(pVolRec) {
355 *pVolRec = volctrl->Volume_Control_Data[i];
356 }
357 OSLibLVMFreeVolumeControlData((HANDLE)volctrl);
358 *lasterror = LVM_ENGINE_NO_ERROR;
359 return volinfo;
360
361fail:
362 DebugInt3();
363 OSLibLVMFreeVolumeControlData((HANDLE)volctrl);
364 *lasterror = LVM_ENGINE_NO_DRIVES_FOUND;
365 return volinfo;
366}
367//******************************************************************************
368//******************************************************************************
369static Volume_Information_Record OSLibLVMFindVolumeFromName(LPSTR pszVolName,
370 Volume_Control_Record *pVolRec,
371 CARDINAL32 *lasterror)
372{
373 Volume_Control_Array *volctrl;
374 Volume_Information_Record volinfo;
375
376 volctrl = (Volume_Control_Array *) OSLibLVMQueryVolumeControlData();
377 if(volctrl == NULL) {
378 DebugInt3();
379 return volinfo;
380 }
381 for(int i=0;i<volctrl->Count;i++) {
382 volinfo = Get_Volume_Information(volctrl->Volume_Control_Data[i].Volume_Handle, lasterror);
383 if(*lasterror != LVM_ENGINE_NO_ERROR) {
384 goto fail;
385 }
386 if(!strcmp(volinfo.Volume_Name, pszVolName)) {
387 break;
388 }
389 }
390 if(i == volctrl->Count) goto fail;
391
392 if(pVolRec) {
393 *pVolRec = volctrl->Volume_Control_Data[i];
394 }
395 OSLibLVMFreeVolumeControlData((HANDLE)volctrl);
396 *lasterror = LVM_ENGINE_NO_ERROR;
397 return volinfo;
398
399fail:
400 DebugInt3();
401 OSLibLVMFreeVolumeControlData((HANDLE)volctrl);
402 *lasterror = LVM_ENGINE_NO_DRIVES_FOUND;
403 return volinfo;
404}
405//******************************************************************************
406//******************************************************************************
407BOOL OSLibLVMGetPartitionInfo(ULONG driveLetter, PPARTITION_INFORMATION pPartition)
408{
409 Volume_Information_Record volinfo;
410 Volume_Control_Record volctrl;
411 Partition_Information_Array partctrl;
412 CARDINAL32 lasterror;
413
414 volinfo = OSLibLVMFindVolumeFromDriveLetter(driveLetter, &volctrl, &lasterror);
415 if(lasterror != LVM_ENGINE_NO_ERROR) {
416 DebugInt3();
417 return FALSE;
418 }
419
420 //We will not return information about LVM volumes (too dangerous as
421 //they contain extra information in the volume and can be spanned)
422 if(volinfo.Compatibility_Volume == FALSE) {
423 return FALSE;
424 }
425
426 partctrl = Get_Partitions(volctrl.Volume_Handle, &lasterror);
427 if(lasterror != LVM_ENGINE_NO_ERROR) {
428 return FALSE;
429 }
430
431 pPartition->StartingOffset.u.HighPart = partctrl.Partition_Array[0].Partition_Start >> 23;
432 pPartition->StartingOffset.u.LowPart = partctrl.Partition_Array[0].Partition_Start << 9;
433 pPartition->PartitionLength.u.HighPart= partctrl.Partition_Array[0].Usable_Partition_Size >> 23;
434 pPartition->PartitionLength.u.LowPart = partctrl.Partition_Array[0].Usable_Partition_Size << 9;
435 pPartition->HiddenSectors = partctrl.Partition_Array[0].True_Partition_Size - partctrl.Partition_Array[0].Usable_Partition_Size;
436 pPartition->PartitionNumber = 0; //todo
437 pPartition->PartitionType = partctrl.Partition_Array[0].OS_Flag;
438 pPartition->BootIndicator = volinfo.Bootable;
439 pPartition->RecognizedPartition = TRUE;
440 pPartition->RewritePartition = 0;
441
442 Free_Engine_Memory((ULONG)partctrl.Partition_Array);
443 return TRUE;
444}
445//******************************************************************************
446//******************************************************************************
447BOOL OSLibLVMGetVolumeExtents(ULONG driveLetter, PVOLUME_DISK_EXTENTS pVolExtent)
448{
449 Volume_Information_Record volinfo;
450 Volume_Control_Record volctrl;
451 Partition_Information_Array partctrl;
452 CARDINAL32 lasterror;
453
454 volinfo = OSLibLVMFindVolumeFromDriveLetter(driveLetter, &volctrl, &lasterror);
455 if(lasterror != LVM_ENGINE_NO_ERROR) {
456 DebugInt3();
457 return FALSE;
458 }
459 //We will not return information about LVM volumes (too dangerous as
460 //they contain extra information in the volume and can be spanned)
461 if(volinfo.Compatibility_Volume == FALSE) {
462 return FALSE;
463 }
464
465 partctrl = Get_Partitions(volctrl.Volume_Handle, &lasterror);
466 if(lasterror != LVM_ENGINE_NO_ERROR) {
467 return FALSE;
468 }
469
470 pVolExtent->NumberOfDiskExtents = 1;
471 pVolExtent->Extents[0].DiskNumber = 0;
472 pVolExtent->Extents[0].StartingOffset.u.HighPart = partctrl.Partition_Array[0].Partition_Start >> 23;;
473 pVolExtent->Extents[0].StartingOffset.u.LowPart = partctrl.Partition_Array[0].Partition_Start << 9;
474 pVolExtent->Extents[0].ExtentLength.u.HighPart = partctrl.Partition_Array[0].Usable_Partition_Size >> 23;
475 pVolExtent->Extents[0].ExtentLength.u.LowPart = partctrl.Partition_Array[0].Usable_Partition_Size << 9;
476
477 Free_Engine_Memory((ULONG)partctrl.Partition_Array);
478 return TRUE;
479}
480//******************************************************************************
481//******************************************************************************
482ULONG OSLibLVMGetDriveType(LPCSTR lpszVolume)
483{
484 Volume_Information_Record volinfo;
485 Volume_Control_Record volctrl;
486 ULONG drivetype;
487 CARDINAL32 lasterror;
488
489 volinfo = OSLibLVMFindVolumeFromName((char *)lpszVolume, &volctrl, &lasterror);
490 if(lasterror != LVM_ENGINE_NO_ERROR) {
491 DebugInt3();
492 return DRIVE_NO_ROOT_DIR_W; //return value checked in NT4, SP6 (GetDriveType(""), GetDriveType("4");
493 }
494
495 switch(volctrl.Device_Type) {
496 case LVM_HARD_DRIVE:
497 drivetype = DRIVE_FIXED_W;
498 break;
499 case NON_LVM_CDROM:
500 drivetype = DRIVE_CDROM_W;
501 break;
502 case NETWORK_DRIVE:
503 drivetype = DRIVE_REMOTE_W;
504 break;
505 case LVM_PRM:
506 drivetype = DRIVE_REMOVABLE_W;
507 break;
508 default:
509 return DRIVE_NO_ROOT_DIR_W; //return value checked in NT4, SP6 (GetDriveType(""), GetDriveType("4");
510 }
511 return drivetype;
512}
513//******************************************************************************
514//******************************************************************************
515CHAR OSLibLVMQueryDriveFromVolumeName(LPCSTR lpszVolume)
516{
517 Volume_Information_Record volinfo;
518 ULONG drivetype;
519 CARDINAL32 lasterror;
520
521 volinfo = OSLibLVMFindVolumeFromName((char *)lpszVolume, NULL, &lasterror);
522 if(lasterror != LVM_ENGINE_NO_ERROR) {
523 DebugInt3();
524 return 0;
525 }
526 return volinfo.Current_Drive_Letter;
527}
528//******************************************************************************
529//******************************************************************************
530DWORD OSLibLVMQueryVolumeFS(LPSTR lpszVolume, LPSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize)
531{
532 Volume_Information_Record volinfo;
533 CARDINAL32 lasterror;
534
535 volinfo = OSLibLVMFindVolumeFromName(lpszVolume, NULL, &lasterror);
536 if(lasterror != LVM_ENGINE_NO_ERROR) {
537 DebugInt3();
538 return ERROR_FILE_NOT_FOUND_W;
539 }
540 strncpy(lpFileSystemNameBuffer, volinfo.File_System_Name, nFileSystemNameSize-1);
541 return ERROR_SUCCESS_W;
542}
543//******************************************************************************
544//******************************************************************************
545DWORD OSLibLVMQueryVolumeSerialAndName(LPSTR lpszVolume, LPDWORD lpVolumeSerialNumber,
546 LPSTR lpVolumeNameBuffer, DWORD nVolumeNameSize)
547{
548 Volume_Information_Record volinfo;
549 Volume_Control_Record volctrl;
550 CARDINAL32 lasterror;
551 int i;
552
553 volinfo = OSLibLVMFindVolumeFromName(lpszVolume, &volctrl, &lasterror);
554 if(lasterror != LVM_ENGINE_NO_ERROR) {
555 DebugInt3();
556 return ERROR_FILE_NOT_FOUND_W;
557 }
558
559 if(lpVolumeSerialNumber) {
560 *lpVolumeSerialNumber = volctrl.Volume_Serial_Number;
561 }
562 if(lpVolumeNameBuffer)
563 {
564 strncpy(lpVolumeNameBuffer, volinfo.Volume_Name, nVolumeNameSize-1);
565 }
566 return ERROR_SUCCESS_W;
567}
568//******************************************************************************
569//******************************************************************************
570BOOL OSLibLVMGetVolumeNameForVolumeMountPoint(LPCSTR lpszVolumeMountPoint,
571 LPSTR lpszVolumeName,
572 DWORD cchBufferLength)
573{
574 int drive;
575
576 //We only support drive letters as mountpoint names
577 if('A' <= *lpszVolumeMountPoint && *lpszVolumeMountPoint <= 'Z') {
578 drive = *lpszVolumeMountPoint - 'A' + 1;
579 }
580 else
581 if('a' <= *lpszVolumeMountPoint && *lpszVolumeMountPoint <= 'z') {
582 drive = *lpszVolumeMountPoint - 'a' + 1;
583 }
584 else {
585 return FALSE;
586 }
587 if(lpszVolumeMountPoint[1] != ':') {
588 return FALSE;
589 }
590
591 Volume_Information_Record volinfo;
592 CARDINAL32 lasterror;
593
594 volinfo = OSLibLVMFindVolumeFromDriveLetter(drive, NULL, &lasterror);
595 if(lasterror != LVM_ENGINE_NO_ERROR) {
596 DebugInt3();
597 return FALSE;
598 }
599
600 strncpy(lpszVolumeName, volinfo.Volume_Name, cchBufferLength-1);
601 return TRUE;
602}
603//******************************************************************************
604//******************************************************************************
605
Note: See TracBrowser for help on using the repository browser.