1 | /* $Id: osliblvm.cpp,v 1.5 2003-01-20 10:46:27 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 |
|
---|
30 | static void (* SYSTEM pfnOpen_LVM_Engine)( BOOLEAN Ignore_CHS, CARDINAL32 * Error_Code );
|
---|
31 | static void (* SYSTEM pfnClose_LVM_Engine) ( void );
|
---|
32 | static Drive_Control_Array (* SYSTEM pfnGet_Drive_Control_Data)( CARDINAL32 * Error_Code );
|
---|
33 | static Drive_Information_Record (* SYSTEM pfnGet_Drive_Status)( ULONG Drive_Handle, CARDINAL32 * Error_Code );
|
---|
34 | static Partition_Information_Array (* SYSTEM pfnGet_Partitions)( ULONG Handle, CARDINAL32 * Error_Code );
|
---|
35 | static ULONG (* SYSTEM pfnGet_Partition_Handle)( CARDINAL32 Serial_Number, CARDINAL32 * Error_Code );
|
---|
36 | static Partition_Information_Record (* SYSTEM pfnGet_Partition_Information)( ULONG Partition_Handle, CARDINAL32 * Error_Code );
|
---|
37 | static Volume_Control_Array (* SYSTEM pfnGet_Volume_Control_Data)( CARDINAL32 * Error_Code );
|
---|
38 | static Volume_Information_Record (* SYSTEM pfnGet_Volume_Information)( ULONG Volume_Handle, CARDINAL32 * Error_Code );
|
---|
39 | static void (* SYSTEM pfnFree_Engine_Memory)( ULONG Object );
|
---|
40 | static void (* SYSTEM pfnRead_Sectors) ( CARDINAL32 Drive_Number,
|
---|
41 | LBA Starting_Sector,
|
---|
42 | CARDINAL32 Sectors_To_Read,
|
---|
43 | ULONG Buffer,
|
---|
44 | CARDINAL32 * Error);
|
---|
45 | static void (* SYSTEM pfnWrite_Sectors) ( CARDINAL32 Drive_Number,
|
---|
46 | LBA Starting_Sector,
|
---|
47 | CARDINAL32 Sectors_To_Write,
|
---|
48 | ULONG Buffer,
|
---|
49 | CARDINAL32 * Error);
|
---|
50 |
|
---|
51 | static HMODULE hModLVM = 0;
|
---|
52 | static BOOL fLVMOpened = FALSE;
|
---|
53 |
|
---|
54 | static void Close_LVM_Engine ( void );
|
---|
55 |
|
---|
56 | //******************************************************************************
|
---|
57 | //******************************************************************************
|
---|
58 | static BOOL OSLibLVMInit()
|
---|
59 | {
|
---|
60 | APIRET rc;
|
---|
61 | CHAR szModuleFailure[CCHMAXPATH];
|
---|
62 |
|
---|
63 | rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), "LVM", (HMODULE *)&hModLVM);
|
---|
64 | if(rc) {
|
---|
65 | return FALSE;
|
---|
66 | }
|
---|
67 | rc = DosQueryProcAddr(hModLVM, 0, "Open_LVM_Engine", (PFN *)&pfnOpen_LVM_Engine);
|
---|
68 | if(rc) goto fail;
|
---|
69 | rc = DosQueryProcAddr(hModLVM, 0, "Close_LVM_Engine", (PFN *)&pfnClose_LVM_Engine);
|
---|
70 | if(rc) goto fail;
|
---|
71 | rc = DosQueryProcAddr(hModLVM, 0, "Get_Drive_Control_Data", (PFN *)&pfnGet_Drive_Control_Data);
|
---|
72 | if(rc) goto fail;
|
---|
73 | rc = DosQueryProcAddr(hModLVM, 0, "Get_Drive_Status", (PFN *)&pfnGet_Drive_Status);
|
---|
74 | if(rc) goto fail;
|
---|
75 | rc = DosQueryProcAddr(hModLVM, 0, "Get_Partitions", (PFN *)&pfnGet_Partitions);
|
---|
76 | if(rc) goto fail;
|
---|
77 | rc = DosQueryProcAddr(hModLVM, 0, "Get_Partition_Handle", (PFN *)&pfnGet_Partition_Handle);
|
---|
78 | if(rc) goto fail;
|
---|
79 | rc = DosQueryProcAddr(hModLVM, 0, "Get_Partition_Information", (PFN *)&pfnGet_Partition_Information);
|
---|
80 | if(rc) goto fail;
|
---|
81 | rc = DosQueryProcAddr(hModLVM, 0, "Get_Volume_Control_Data", (PFN *)&pfnGet_Volume_Control_Data);
|
---|
82 | if(rc) goto fail;
|
---|
83 | rc = DosQueryProcAddr(hModLVM, 0, "Get_Volume_Information", (PFN *)&pfnGet_Volume_Information);
|
---|
84 | if(rc) goto fail;
|
---|
85 | rc = DosQueryProcAddr(hModLVM, 0, "Free_Engine_Memory", (PFN *)&pfnFree_Engine_Memory);
|
---|
86 | if(rc) goto fail;
|
---|
87 | rc = DosQueryProcAddr(hModLVM, 0, "Read_Sectors", (PFN *)&pfnRead_Sectors);
|
---|
88 | if(rc) goto fail;
|
---|
89 | rc = DosQueryProcAddr(hModLVM, 0, "Write_Sectors", (PFN *)&pfnWrite_Sectors);
|
---|
90 | if(rc) goto fail;
|
---|
91 |
|
---|
92 | return TRUE;
|
---|
93 |
|
---|
94 | fail:
|
---|
95 | if(hModLVM) {
|
---|
96 | DosFreeModule(hModLVM);
|
---|
97 | hModLVM = 0;
|
---|
98 | }
|
---|
99 | return FALSE;
|
---|
100 | }
|
---|
101 | //******************************************************************************
|
---|
102 | //******************************************************************************
|
---|
103 | void OSLibLVMExit()
|
---|
104 | {
|
---|
105 | if(fLVMOpened) {
|
---|
106 | Close_LVM_Engine();
|
---|
107 | }
|
---|
108 | if(hModLVM) {
|
---|
109 | DosFreeModule(hModLVM);
|
---|
110 | hModLVM = 0;
|
---|
111 | }
|
---|
112 | }
|
---|
113 | //******************************************************************************
|
---|
114 | //******************************************************************************
|
---|
115 | static void Open_LVM_Engine( BOOLEAN Ignore_CHS, CARDINAL32 * Error_Code )
|
---|
116 | {
|
---|
117 | USHORT sel;
|
---|
118 |
|
---|
119 | //Load LVM dll
|
---|
120 | OSLibLVMInit();
|
---|
121 |
|
---|
122 | sel = RestoreOS2FS();
|
---|
123 | pfnOpen_LVM_Engine(Ignore_CHS, Error_Code);
|
---|
124 | SetFS(sel);
|
---|
125 | return;
|
---|
126 | }
|
---|
127 | //******************************************************************************
|
---|
128 | //******************************************************************************
|
---|
129 | static void Close_LVM_Engine ( void )
|
---|
130 | {
|
---|
131 | USHORT sel;
|
---|
132 |
|
---|
133 | sel = RestoreOS2FS();
|
---|
134 | pfnClose_LVM_Engine();
|
---|
135 | SetFS(sel);
|
---|
136 | return;
|
---|
137 | }
|
---|
138 | //******************************************************************************
|
---|
139 | //******************************************************************************
|
---|
140 | static Drive_Control_Array Get_Drive_Control_Data( CARDINAL32 * Error_Code )
|
---|
141 | {
|
---|
142 | Drive_Control_Array ret;
|
---|
143 | USHORT sel;
|
---|
144 |
|
---|
145 | sel = RestoreOS2FS();
|
---|
146 | ret = pfnGet_Drive_Control_Data(Error_Code);
|
---|
147 | SetFS(sel);
|
---|
148 | return ret;
|
---|
149 | }
|
---|
150 | //******************************************************************************
|
---|
151 | //******************************************************************************
|
---|
152 | static Drive_Information_Record Get_Drive_Status( ULONG Drive_Handle, CARDINAL32 * Error_Code )
|
---|
153 | {
|
---|
154 | Drive_Information_Record ret;
|
---|
155 | USHORT sel;
|
---|
156 |
|
---|
157 | sel = RestoreOS2FS();
|
---|
158 | ret = pfnGet_Drive_Status(Drive_Handle, Error_Code);
|
---|
159 | SetFS(sel);
|
---|
160 | return ret;
|
---|
161 | }
|
---|
162 | //******************************************************************************
|
---|
163 | //******************************************************************************
|
---|
164 | static Partition_Information_Array Get_Partitions( ULONG Handle, CARDINAL32 * Error_Code )
|
---|
165 | {
|
---|
166 | Partition_Information_Array ret;
|
---|
167 | USHORT sel;
|
---|
168 |
|
---|
169 | sel = RestoreOS2FS();
|
---|
170 | ret = pfnGet_Partitions(Handle, Error_Code);
|
---|
171 | SetFS(sel);
|
---|
172 | return ret;
|
---|
173 | }
|
---|
174 | //******************************************************************************
|
---|
175 | //******************************************************************************
|
---|
176 | static ULONG Get_Partition_Handle( CARDINAL32 Serial_Number, CARDINAL32 * Error_Code )
|
---|
177 | {
|
---|
178 | ULONG ret;
|
---|
179 | USHORT sel;
|
---|
180 |
|
---|
181 | sel = RestoreOS2FS();
|
---|
182 | ret = pfnGet_Partition_Handle(Serial_Number, Error_Code);
|
---|
183 | SetFS(sel);
|
---|
184 | return ret;
|
---|
185 | }
|
---|
186 | //******************************************************************************
|
---|
187 | //******************************************************************************
|
---|
188 | static Partition_Information_Record Get_Partition_Information( ULONG Partition_Handle, CARDINAL32 * Error_Code )
|
---|
189 | {
|
---|
190 | Partition_Information_Record ret;
|
---|
191 | USHORT sel;
|
---|
192 |
|
---|
193 | sel = RestoreOS2FS();
|
---|
194 | ret = pfnGet_Partition_Information(Partition_Handle, Error_Code);
|
---|
195 | SetFS(sel);
|
---|
196 | return ret;
|
---|
197 | }
|
---|
198 | //******************************************************************************
|
---|
199 | //******************************************************************************
|
---|
200 | static Volume_Control_Array Get_Volume_Control_Data( CARDINAL32 * Error_Code )
|
---|
201 | {
|
---|
202 | Volume_Control_Array ret;
|
---|
203 | USHORT sel;
|
---|
204 |
|
---|
205 | sel = RestoreOS2FS();
|
---|
206 | ret = pfnGet_Volume_Control_Data(Error_Code);
|
---|
207 | SetFS(sel);
|
---|
208 | return ret;
|
---|
209 | }
|
---|
210 | //******************************************************************************
|
---|
211 | //******************************************************************************
|
---|
212 | static Volume_Information_Record Get_Volume_Information( ULONG Volume_Handle, CARDINAL32 * Error_Code )
|
---|
213 | {
|
---|
214 | Volume_Information_Record ret;
|
---|
215 | USHORT sel;
|
---|
216 |
|
---|
217 | sel = RestoreOS2FS();
|
---|
218 | ret = pfnGet_Volume_Information(Volume_Handle, Error_Code);
|
---|
219 | SetFS(sel);
|
---|
220 | return ret;
|
---|
221 | }
|
---|
222 | //******************************************************************************
|
---|
223 | //******************************************************************************
|
---|
224 | static void Free_Engine_Memory( ULONG Object )
|
---|
225 | {
|
---|
226 | USHORT sel;
|
---|
227 |
|
---|
228 | sel = RestoreOS2FS();
|
---|
229 | pfnFree_Engine_Memory(Object);
|
---|
230 | SetFS(sel);
|
---|
231 | return;
|
---|
232 | }
|
---|
233 | //******************************************************************************
|
---|
234 | //******************************************************************************
|
---|
235 | static void Read_Sectors ( CARDINAL32 Drive_Number,
|
---|
236 | LBA Starting_Sector,
|
---|
237 | CARDINAL32 Sectors_To_Read,
|
---|
238 | ULONG Buffer,
|
---|
239 | CARDINAL32 * Error)
|
---|
240 | {
|
---|
241 | USHORT sel;
|
---|
242 |
|
---|
243 | sel = RestoreOS2FS();
|
---|
244 | pfnRead_Sectors(Drive_Number, Starting_Sector, Sectors_To_Read, Buffer, Error);
|
---|
245 | SetFS(sel);
|
---|
246 | return;
|
---|
247 | }
|
---|
248 | //******************************************************************************
|
---|
249 | //******************************************************************************
|
---|
250 | static void Write_Sectors ( CARDINAL32 Drive_Number,
|
---|
251 | LBA Starting_Sector,
|
---|
252 | CARDINAL32 Sectors_To_Write,
|
---|
253 | ULONG Buffer,
|
---|
254 | CARDINAL32 * Error)
|
---|
255 | {
|
---|
256 | USHORT sel;
|
---|
257 |
|
---|
258 | sel = RestoreOS2FS();
|
---|
259 | pfnWrite_Sectors(Drive_Number, Starting_Sector, Sectors_To_Write, Buffer, Error);
|
---|
260 | SetFS(sel);
|
---|
261 | return;
|
---|
262 | }
|
---|
263 | //******************************************************************************
|
---|
264 | //******************************************************************************
|
---|
265 | HANDLE OSLibLVMQueryVolumeControlData()
|
---|
266 | {
|
---|
267 | Volume_Control_Array *volctrl;
|
---|
268 | CARDINAL32 lasterror;
|
---|
269 |
|
---|
270 | if(!hModLVM) {
|
---|
271 | dprintf(("LVM dll not loaded -> fail"));
|
---|
272 | return 0;
|
---|
273 | }
|
---|
274 |
|
---|
275 | if(!fLVMOpened) {
|
---|
276 | Open_LVM_Engine(FALSE, &lasterror);
|
---|
277 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
278 | DebugInt3();
|
---|
279 | return 0;
|
---|
280 | }
|
---|
281 | dprintf(("LVM engine opened"));
|
---|
282 | fLVMOpened = TRUE;
|
---|
283 | }
|
---|
284 |
|
---|
285 | volctrl = (Volume_Control_Array *)malloc(sizeof(Volume_Control_Array));
|
---|
286 | if(volctrl == NULL) {
|
---|
287 | DebugInt3();
|
---|
288 | return 0;
|
---|
289 | }
|
---|
290 | *volctrl = Get_Volume_Control_Data(&lasterror);
|
---|
291 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
292 | DebugInt3();
|
---|
293 | return 0;
|
---|
294 | }
|
---|
295 | return (HANDLE)volctrl;
|
---|
296 | }
|
---|
297 | //******************************************************************************
|
---|
298 | //******************************************************************************
|
---|
299 | void OSLibLVMFreeVolumeControlData(HANDLE hVolumeControlData)
|
---|
300 | {
|
---|
301 | Volume_Control_Array *volctrl = (Volume_Control_Array *)hVolumeControlData;
|
---|
302 |
|
---|
303 | if(volctrl == NULL) {
|
---|
304 | DebugInt3();
|
---|
305 | return;
|
---|
306 | }
|
---|
307 | Free_Engine_Memory((ULONG)volctrl->Volume_Control_Data);
|
---|
308 | free(volctrl);
|
---|
309 | }
|
---|
310 | //******************************************************************************
|
---|
311 | //******************************************************************************
|
---|
312 | BOOL OSLibLVMQueryVolumeName(HANDLE hVolumeControlData, ULONG *pVolIndex,
|
---|
313 | LPSTR lpszVolumeName, DWORD cchBufferLength)
|
---|
314 | {
|
---|
315 | Volume_Control_Array *volctrl = (Volume_Control_Array *)hVolumeControlData;
|
---|
316 | Volume_Information_Record volinfo;
|
---|
317 | CARDINAL32 lasterror;
|
---|
318 |
|
---|
319 | if(volctrl == NULL) {
|
---|
320 | DebugInt3();
|
---|
321 | return FALSE;
|
---|
322 | }
|
---|
323 | if(*pVolIndex >= volctrl->Count) {
|
---|
324 | return FALSE; //no more volumes
|
---|
325 | }
|
---|
326 | while(*pVolIndex < volctrl->Count) {
|
---|
327 | volinfo = Get_Volume_Information(volctrl->Volume_Control_Data[*pVolIndex].Volume_Handle, &lasterror);
|
---|
328 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
329 | DebugInt3();
|
---|
330 | return FALSE;
|
---|
331 | }
|
---|
332 | //Don't report anything about LVM volumes until we support all those
|
---|
333 | //fancy features (like spanned volumes)
|
---|
334 | if(volinfo.Compatibility_Volume == TRUE) break;
|
---|
335 | dprintf(("Ignoring LVM volume %s", volinfo.Volume_Name));
|
---|
336 | (*pVolIndex)++;
|
---|
337 | }
|
---|
338 | if(*pVolIndex >= volctrl->Count) {
|
---|
339 | return FALSE; //no more volumes
|
---|
340 | }
|
---|
341 | strncpy(lpszVolumeName, volinfo.Volume_Name, min(sizeof(volinfo.Volume_Name), cchBufferLength)-1);
|
---|
342 | return TRUE;
|
---|
343 | }
|
---|
344 | //******************************************************************************
|
---|
345 | //******************************************************************************
|
---|
346 | static Volume_Information_Record OSLibLVMFindVolumeByDriveLetter(ULONG driveLetter,
|
---|
347 | Volume_Control_Record *pVolRec,
|
---|
348 | CARDINAL32 *lasterror)
|
---|
349 | {
|
---|
350 | Volume_Control_Array *volctrl;
|
---|
351 | Volume_Information_Record volinfo;
|
---|
352 |
|
---|
353 | volctrl = (Volume_Control_Array *) OSLibLVMQueryVolumeControlData();
|
---|
354 | if(volctrl == NULL) {
|
---|
355 | DebugInt3();
|
---|
356 | return volinfo;
|
---|
357 | }
|
---|
358 | int i;
|
---|
359 | for(i=0;i<volctrl->Count;i++) {
|
---|
360 | volinfo = Get_Volume_Information(volctrl->Volume_Control_Data[i].Volume_Handle, lasterror);
|
---|
361 | if(*lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
362 | goto fail;
|
---|
363 | }
|
---|
364 | if(volinfo.Current_Drive_Letter == (char) ('A' + driveLetter)) {
|
---|
365 | break;
|
---|
366 | }
|
---|
367 | }
|
---|
368 | if(i == volctrl->Count) goto fail;
|
---|
369 |
|
---|
370 | if(pVolRec) {
|
---|
371 | *pVolRec = volctrl->Volume_Control_Data[i];
|
---|
372 | }
|
---|
373 | OSLibLVMFreeVolumeControlData((HANDLE)volctrl);
|
---|
374 | *lasterror = LVM_ENGINE_NO_ERROR;
|
---|
375 | return volinfo;
|
---|
376 |
|
---|
377 | fail:
|
---|
378 | DebugInt3();
|
---|
379 | OSLibLVMFreeVolumeControlData((HANDLE)volctrl);
|
---|
380 | *lasterror = LVM_ENGINE_NO_DRIVES_FOUND;
|
---|
381 | return volinfo;
|
---|
382 | }
|
---|
383 | //******************************************************************************
|
---|
384 | //******************************************************************************
|
---|
385 | static Volume_Information_Record OSLibLVMFindVolumeByName(LPSTR pszVolName,
|
---|
386 | Volume_Control_Record *pVolRec,
|
---|
387 | CARDINAL32 *lasterror)
|
---|
388 | {
|
---|
389 | Volume_Control_Array *volctrl;
|
---|
390 | Volume_Information_Record volinfo;
|
---|
391 |
|
---|
392 | volctrl = (Volume_Control_Array *) OSLibLVMQueryVolumeControlData();
|
---|
393 | if(volctrl == NULL) {
|
---|
394 | DebugInt3();
|
---|
395 | return volinfo;
|
---|
396 | }
|
---|
397 | int i;
|
---|
398 | for(i=0;i<volctrl->Count;i++) {
|
---|
399 | volinfo = Get_Volume_Information(volctrl->Volume_Control_Data[i].Volume_Handle, lasterror);
|
---|
400 | if(*lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
401 | goto fail;
|
---|
402 | }
|
---|
403 | if(!strcmp(volinfo.Volume_Name, pszVolName)) {
|
---|
404 | break;
|
---|
405 | }
|
---|
406 | }
|
---|
407 | if(i == volctrl->Count) goto fail;
|
---|
408 |
|
---|
409 | if(pVolRec) {
|
---|
410 | *pVolRec = volctrl->Volume_Control_Data[i];
|
---|
411 | }
|
---|
412 | OSLibLVMFreeVolumeControlData((HANDLE)volctrl);
|
---|
413 | *lasterror = LVM_ENGINE_NO_ERROR;
|
---|
414 | return volinfo;
|
---|
415 |
|
---|
416 | fail:
|
---|
417 | DebugInt3();
|
---|
418 | OSLibLVMFreeVolumeControlData((HANDLE)volctrl);
|
---|
419 | *lasterror = LVM_ENGINE_NO_DRIVES_FOUND;
|
---|
420 | return volinfo;
|
---|
421 | }
|
---|
422 | //******************************************************************************
|
---|
423 | //******************************************************************************
|
---|
424 | BOOL OSLibLVMGetPartitionInfo(ULONG driveLetter, LPSTR lpszVolumeName, PPARTITION_INFORMATION pPartition)
|
---|
425 | {
|
---|
426 | Volume_Information_Record volinfo;
|
---|
427 | Volume_Control_Record volctrl;
|
---|
428 | Partition_Information_Array partctrl;
|
---|
429 | CARDINAL32 lasterror;
|
---|
430 |
|
---|
431 | if(lpszVolumeName && lpszVolumeName[0]) {
|
---|
432 | volinfo = OSLibLVMFindVolumeByName(lpszVolumeName, &volctrl, &lasterror);
|
---|
433 | }
|
---|
434 | else volinfo = OSLibLVMFindVolumeByDriveLetter(driveLetter, &volctrl, &lasterror);
|
---|
435 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
436 | DebugInt3();
|
---|
437 | return FALSE;
|
---|
438 | }
|
---|
439 |
|
---|
440 | partctrl = Get_Partitions(volctrl.Volume_Handle, &lasterror);
|
---|
441 | if(lasterror != LVM_ENGINE_NO_ERROR || partctrl.Count == 0) {
|
---|
442 | return FALSE;
|
---|
443 | }
|
---|
444 |
|
---|
445 | pPartition->StartingOffset.u.HighPart = partctrl.Partition_Array[0].Partition_Start >> 23;
|
---|
446 | pPartition->StartingOffset.u.LowPart = partctrl.Partition_Array[0].Partition_Start << 9;
|
---|
447 | // pPartition->PartitionLength.u.HighPart= partctrl.Partition_Array[0].True_Partition_Size >> 23;
|
---|
448 | // pPartition->PartitionLength.u.LowPart = partctrl.Partition_Array[0].True_Partition_Size << 9;
|
---|
449 | // pPartition->HiddenSectors = 0;
|
---|
450 | pPartition->PartitionLength.u.HighPart= partctrl.Partition_Array[0].Usable_Partition_Size >> 23;
|
---|
451 | pPartition->PartitionLength.u.LowPart = partctrl.Partition_Array[0].Usable_Partition_Size << 9;
|
---|
452 | pPartition->HiddenSectors = partctrl.Partition_Array[0].True_Partition_Size - partctrl.Partition_Array[0].Usable_Partition_Size;
|
---|
453 | pPartition->PartitionNumber = 0; //todo
|
---|
454 | pPartition->PartitionType = partctrl.Partition_Array[0].OS_Flag;
|
---|
455 | pPartition->BootIndicator = volinfo.Bootable;
|
---|
456 | pPartition->RecognizedPartition = TRUE;
|
---|
457 | pPartition->RewritePartition = 0;
|
---|
458 |
|
---|
459 | Free_Engine_Memory((ULONG)partctrl.Partition_Array);
|
---|
460 | return TRUE;
|
---|
461 | }
|
---|
462 | //******************************************************************************
|
---|
463 | //******************************************************************************
|
---|
464 | BOOL OSLibLVMGetVolumeExtents(ULONG driveLetter, LPSTR lpszVolumeName, PVOLUME_DISK_EXTENTS pVolExtent,
|
---|
465 | BOOL *pfLVMVolume)
|
---|
466 | {
|
---|
467 | Volume_Information_Record volinfo;
|
---|
468 | Volume_Control_Record volctrl;
|
---|
469 | Drive_Control_Array diskinfo;
|
---|
470 | Partition_Information_Array partctrl;
|
---|
471 | CARDINAL32 lasterror;
|
---|
472 | BOOL ret = TRUE;
|
---|
473 |
|
---|
474 | if(lpszVolumeName && lpszVolumeName[0]) {
|
---|
475 | volinfo = OSLibLVMFindVolumeByName(lpszVolumeName, &volctrl, &lasterror);
|
---|
476 | }
|
---|
477 | else volinfo = OSLibLVMFindVolumeByDriveLetter(driveLetter, &volctrl, &lasterror);
|
---|
478 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
479 | DebugInt3();
|
---|
480 | return FALSE;
|
---|
481 | }
|
---|
482 |
|
---|
483 | partctrl = Get_Partitions(volctrl.Volume_Handle, &lasterror);
|
---|
484 | if(lasterror != LVM_ENGINE_NO_ERROR || partctrl.Count == 0) {
|
---|
485 | return FALSE;
|
---|
486 | }
|
---|
487 |
|
---|
488 | //TODO: spanned volumes
|
---|
489 | pVolExtent->NumberOfDiskExtents = 1;
|
---|
490 | pVolExtent->Extents[0].DiskNumber = 0;
|
---|
491 | pVolExtent->Extents[0].StartingOffset.u.HighPart = partctrl.Partition_Array[0].Partition_Start >> 23;;
|
---|
492 | pVolExtent->Extents[0].StartingOffset.u.LowPart = partctrl.Partition_Array[0].Partition_Start << 9;
|
---|
493 | // pVolExtent->Extents[0].ExtentLength.u.HighPart = partctrl.Partition_Array[0].True_Partition_Size >> 23;
|
---|
494 | // pVolExtent->Extents[0].ExtentLength.u.LowPart = partctrl.Partition_Array[0].True_Partition_Size << 9;
|
---|
495 | pVolExtent->Extents[0].ExtentLength.u.HighPart = partctrl.Partition_Array[0].Usable_Partition_Size >> 23;
|
---|
496 | pVolExtent->Extents[0].ExtentLength.u.LowPart = partctrl.Partition_Array[0].Usable_Partition_Size << 9;
|
---|
497 |
|
---|
498 | //find number of disk on which this volume is located
|
---|
499 | diskinfo = Get_Drive_Control_Data(&lasterror);
|
---|
500 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
501 | return FALSE;
|
---|
502 | }
|
---|
503 | int i;
|
---|
504 | for(i=0;i<diskinfo.Count;i++) {
|
---|
505 | if(diskinfo.Drive_Control_Data[i].Drive_Handle == partctrl.Partition_Array[0].Drive_Handle) {
|
---|
506 | //win32 base = 0, os2 base = 1
|
---|
507 | pVolExtent->Extents[0].DiskNumber = diskinfo.Drive_Control_Data[i].Drive_Number - 1;
|
---|
508 | #ifdef DEBUG
|
---|
509 | if(diskinfo.Drive_Control_Data[i].Drive_Number == 0) DebugInt3();
|
---|
510 | #endif
|
---|
511 | break;
|
---|
512 | }
|
---|
513 | }
|
---|
514 | if(i == diskinfo.Count) {
|
---|
515 | ret = FALSE;
|
---|
516 | }
|
---|
517 | dprintf(("pVolExtent->NumberOfDiskExtents %d", pVolExtent->NumberOfDiskExtents));
|
---|
518 | dprintf(("pVolExtent->Extents[0].DiskNumber %d", pVolExtent->Extents[0].DiskNumber));
|
---|
519 | dprintf(("pVolExtent->Extents[0].StartingOffset %08x%08x", pVolExtent->Extents[0].StartingOffset.u.HighPart, pVolExtent->Extents[0].StartingOffset.u.LowPart));
|
---|
520 | dprintf(("pVolExtent->Extents[0].ExtentLength %08x%08x", pVolExtent->Extents[0].ExtentLength.u.HighPart, pVolExtent->Extents[0].ExtentLength.u.LowPart));
|
---|
521 |
|
---|
522 | if(pfLVMVolume) {
|
---|
523 | *pfLVMVolume = (volinfo.Compatibility_Volume == FALSE);
|
---|
524 | }
|
---|
525 | Free_Engine_Memory((ULONG)diskinfo.Drive_Control_Data);
|
---|
526 | Free_Engine_Memory((ULONG)partctrl.Partition_Array);
|
---|
527 | return ret;
|
---|
528 | }
|
---|
529 | //******************************************************************************
|
---|
530 | //******************************************************************************
|
---|
531 | ULONG OSLibLVMGetDriveType(LPCSTR lpszVolume)
|
---|
532 | {
|
---|
533 | Volume_Information_Record volinfo;
|
---|
534 | Volume_Control_Record volctrl;
|
---|
535 | ULONG drivetype;
|
---|
536 | CARDINAL32 lasterror;
|
---|
537 |
|
---|
538 | volinfo = OSLibLVMFindVolumeByName((char *)lpszVolume, &volctrl, &lasterror);
|
---|
539 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
540 | DebugInt3();
|
---|
541 | return DRIVE_NO_ROOT_DIR_W; //return value checked in NT4, SP6 (GetDriveType(""), GetDriveType("4");
|
---|
542 | }
|
---|
543 |
|
---|
544 | switch(volctrl.Device_Type) {
|
---|
545 | case LVM_HARD_DRIVE:
|
---|
546 | drivetype = DRIVE_FIXED_W;
|
---|
547 | break;
|
---|
548 | case NON_LVM_CDROM:
|
---|
549 | drivetype = DRIVE_CDROM_W;
|
---|
550 | break;
|
---|
551 | case NETWORK_DRIVE:
|
---|
552 | drivetype = DRIVE_REMOTE_W;
|
---|
553 | break;
|
---|
554 | case LVM_PRM:
|
---|
555 | drivetype = DRIVE_REMOVABLE_W;
|
---|
556 | break;
|
---|
557 | default:
|
---|
558 | return DRIVE_NO_ROOT_DIR_W; //return value checked in NT4, SP6 (GetDriveType(""), GetDriveType("4");
|
---|
559 | }
|
---|
560 | return drivetype;
|
---|
561 | }
|
---|
562 | //******************************************************************************
|
---|
563 | // OSLibLVMQueryDriveFromVolumeName
|
---|
564 | //
|
---|
565 | // Returns:
|
---|
566 | // - drive letter corresponding to volume name
|
---|
567 | // - -1 if volume wasn't found
|
---|
568 | // - 0 if volume is present, but not mounted
|
---|
569 | //
|
---|
570 | //******************************************************************************
|
---|
571 | CHAR OSLibLVMQueryDriveFromVolumeName(LPCSTR lpszVolume)
|
---|
572 | {
|
---|
573 | Volume_Information_Record volinfo;
|
---|
574 | ULONG drivetype;
|
---|
575 | CARDINAL32 lasterror;
|
---|
576 |
|
---|
577 | volinfo = OSLibLVMFindVolumeByName((char *)lpszVolume, NULL, &lasterror);
|
---|
578 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
579 | DebugInt3();
|
---|
580 | return -1; //not found
|
---|
581 | }
|
---|
582 | return volinfo.Current_Drive_Letter;
|
---|
583 | }
|
---|
584 | //******************************************************************************
|
---|
585 | //******************************************************************************
|
---|
586 | DWORD OSLibLVMQueryVolumeFS(LPSTR lpszVolume, LPSTR lpFileSystemNameBuffer, DWORD nFileSystemNameSize)
|
---|
587 | {
|
---|
588 | Volume_Information_Record volinfo;
|
---|
589 | CARDINAL32 lasterror;
|
---|
590 |
|
---|
591 | volinfo = OSLibLVMFindVolumeByName(lpszVolume, NULL, &lasterror);
|
---|
592 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
593 | DebugInt3();
|
---|
594 | return ERROR_FILE_NOT_FOUND_W;
|
---|
595 | }
|
---|
596 | strncpy(lpFileSystemNameBuffer, volinfo.File_System_Name, nFileSystemNameSize-1);
|
---|
597 | return ERROR_SUCCESS_W;
|
---|
598 | }
|
---|
599 | //******************************************************************************
|
---|
600 | //******************************************************************************
|
---|
601 | DWORD OSLibLVMQueryVolumeSerialAndName(LPSTR lpszVolume, LPDWORD lpVolumeSerialNumber,
|
---|
602 | LPSTR lpVolumeNameBuffer, DWORD nVolumeNameSize)
|
---|
603 | {
|
---|
604 | Volume_Information_Record volinfo;
|
---|
605 | Volume_Control_Record volctrl;
|
---|
606 | CARDINAL32 lasterror;
|
---|
607 | int i;
|
---|
608 |
|
---|
609 | volinfo = OSLibLVMFindVolumeByName(lpszVolume, &volctrl, &lasterror);
|
---|
610 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
611 | DebugInt3();
|
---|
612 | return ERROR_FILE_NOT_FOUND_W;
|
---|
613 | }
|
---|
614 |
|
---|
615 | if(lpVolumeSerialNumber) {
|
---|
616 | *lpVolumeSerialNumber = volctrl.Volume_Serial_Number;
|
---|
617 | }
|
---|
618 | if(lpVolumeNameBuffer)
|
---|
619 | {
|
---|
620 | strncpy(lpVolumeNameBuffer, volinfo.Volume_Name, nVolumeNameSize-1);
|
---|
621 | }
|
---|
622 | return ERROR_SUCCESS_W;
|
---|
623 | }
|
---|
624 | //******************************************************************************
|
---|
625 | //******************************************************************************
|
---|
626 | BOOL OSLibLVMGetVolumeNameForVolumeMountPoint(LPCSTR lpszVolumeMountPoint,
|
---|
627 | LPSTR lpszVolumeName,
|
---|
628 | DWORD cchBufferLength)
|
---|
629 | {
|
---|
630 | int drive;
|
---|
631 |
|
---|
632 | //We only support drive letters as mountpoint names
|
---|
633 | if('A' <= *lpszVolumeMountPoint && *lpszVolumeMountPoint <= 'Z') {
|
---|
634 | drive = *lpszVolumeMountPoint - 'A';
|
---|
635 | }
|
---|
636 | else
|
---|
637 | if('a' <= *lpszVolumeMountPoint && *lpszVolumeMountPoint <= 'z') {
|
---|
638 | drive = *lpszVolumeMountPoint - 'a';
|
---|
639 | }
|
---|
640 | else {
|
---|
641 | return FALSE;
|
---|
642 | }
|
---|
643 | if(lpszVolumeMountPoint[1] != ':') {
|
---|
644 | return FALSE;
|
---|
645 | }
|
---|
646 |
|
---|
647 | Volume_Information_Record volinfo;
|
---|
648 | CARDINAL32 lasterror;
|
---|
649 |
|
---|
650 | volinfo = OSLibLVMFindVolumeByDriveLetter(drive, NULL, &lasterror);
|
---|
651 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
652 | DebugInt3();
|
---|
653 | return FALSE;
|
---|
654 | }
|
---|
655 |
|
---|
656 | strncpy(lpszVolumeName, volinfo.Volume_Name, cchBufferLength-1);
|
---|
657 | return TRUE;
|
---|
658 | }
|
---|
659 | //******************************************************************************
|
---|
660 | //******************************************************************************
|
---|
661 | BOOL OSLibLVMStripVolumeName(LPCSTR lpszWin32VolumeName, LPSTR lpszOS2VolumeName, DWORD cchBufferLength)
|
---|
662 | {
|
---|
663 | int length;
|
---|
664 |
|
---|
665 | //strip volume name prefix (\\\\?\\Volume\\)
|
---|
666 | length = strlen(lpszWin32VolumeName);
|
---|
667 |
|
---|
668 | strncpy(lpszOS2VolumeName, &lpszWin32VolumeName[sizeof(VOLUME_NAME_PREFIX)-1+1], cchBufferLength-1); //-zero term + starting '{'
|
---|
669 | length -= sizeof(VOLUME_NAME_PREFIX)-1+1;
|
---|
670 | if(lpszOS2VolumeName[length-2] == '}')
|
---|
671 | {
|
---|
672 | lpszOS2VolumeName[length-2] = 0;
|
---|
673 | return TRUE;
|
---|
674 | }
|
---|
675 | else
|
---|
676 | if(lpszOS2VolumeName[length-1] == '}')
|
---|
677 | {
|
---|
678 | lpszOS2VolumeName[length-1] = 0;
|
---|
679 | return TRUE;
|
---|
680 | }
|
---|
681 | return FALSE;
|
---|
682 | }
|
---|
683 | //******************************************************************************
|
---|
684 | //******************************************************************************
|
---|
685 | BOOL OSLibLVMGetDiskGeometry(DWORD dwDiskNr, PDISK_GEOMETRY pGeom)
|
---|
686 | {
|
---|
687 | Drive_Control_Array driveinfo;
|
---|
688 | Drive_Control_Record *pDriveRec;
|
---|
689 | CARDINAL32 lasterror;
|
---|
690 | BOOL ret = FALSE;
|
---|
691 | int i;
|
---|
692 |
|
---|
693 | driveinfo = Get_Drive_Control_Data(&lasterror);
|
---|
694 | if(lasterror != LVM_ENGINE_NO_ERROR) {
|
---|
695 | DebugInt3();
|
---|
696 | return FALSE;
|
---|
697 | }
|
---|
698 | pDriveRec = driveinfo.Drive_Control_Data;
|
---|
699 | if(pDriveRec == NULL) {
|
---|
700 | DebugInt3();
|
---|
701 | return FALSE;
|
---|
702 | }
|
---|
703 | if(dwDiskNr > driveinfo.Count) {
|
---|
704 | DebugInt3();
|
---|
705 | ret = FALSE;
|
---|
706 | goto endfunc;
|
---|
707 | }
|
---|
708 | for(i=0;i<driveinfo.Count;i++) {
|
---|
709 | if(pDriveRec->Drive_Number == dwDiskNr) {
|
---|
710 | pGeom->Cylinders.u.LowPart = pDriveRec->Cylinder_Count;
|
---|
711 | pGeom->Cylinders.u.HighPart = 0;
|
---|
712 | pGeom->TracksPerCylinder = pDriveRec->Heads_Per_Cylinder;
|
---|
713 | pGeom->SectorsPerTrack = pDriveRec->Sectors_Per_Track;
|
---|
714 | pGeom->BytesPerSector = 512;
|
---|
715 | pGeom->MediaType = FixedMedia;
|
---|
716 |
|
---|
717 | ret = TRUE;
|
---|
718 | break;
|
---|
719 | }
|
---|
720 | }
|
---|
721 | endfunc:
|
---|
722 | Free_Engine_Memory((ULONG)driveinfo.Drive_Control_Data);
|
---|
723 | return ret;
|
---|
724 | }
|
---|
725 | //******************************************************************************
|
---|
726 | //******************************************************************************
|
---|