| 1 | ; AiR-BOOT (c) Copyright 1998-2008 M. Kiewitz | 
|---|
| 2 | ; | 
|---|
| 3 | ; This file is part of AiR-BOOT | 
|---|
| 4 | ; | 
|---|
| 5 | ; AiR-BOOT is free software: you can redistribute it and/or modify it under | 
|---|
| 6 | ;  the terms of the GNU General Public License as published by the Free | 
|---|
| 7 | ;  Software Foundation, either version 3 of the License, or (at your option) | 
|---|
| 8 | ;  any later version. | 
|---|
| 9 | ; | 
|---|
| 10 | ; AiR-BOOT is distributed in the hope that it will be useful, but WITHOUT ANY | 
|---|
| 11 | ;  WARRANTY: without even the implied warranty of MERCHANTABILITY or FITNESS | 
|---|
| 12 | ;  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | 
|---|
| 13 | ;  details. | 
|---|
| 14 | ; | 
|---|
| 15 | ; You should have received a copy of the GNU General Public License along with | 
|---|
| 16 | ;  AiR-BOOT. If not, see <http://www.gnu.org/licenses/>. | 
|---|
| 17 | ; | 
|---|
| 18 | ;--------------------------------------------------------------------------- | 
|---|
| 19 | ;                                                            AiR-BOOT / LVM | 
|---|
| 20 | ;--------------------------------------------------------------------------- | 
|---|
| 21 |  | 
|---|
| 22 | IFDEF   MODULE_NAMES | 
|---|
| 23 | DB 'LVM',0 | 
|---|
| 24 | ENDIF | 
|---|
| 25 |  | 
|---|
| 26 | LVM_InitCRCTable                Proc Near | 
|---|
| 27 | ; Initializes our LVM-CRC-Table | 
|---|
| 28 | xor     cl, cl | 
|---|
| 29 | mov     di, offset [LVM_CRCTable] | 
|---|
| 30 | LVM_ICRCT_Loop: | 
|---|
| 31 | ;movzx  ax, cl | 
|---|
| 32 | mov     al,cl | 
|---|
| 33 | mov     ah,0 | 
|---|
| 34 | xor     dx, dx                      ; DX:AX - CRC-Value | 
|---|
| 35 | mov     ch, 8 | 
|---|
| 36 | LVM_ICRCT_Loop2: | 
|---|
| 37 | shr     dx, 1 | 
|---|
| 38 | rcr     ax, 1                    ; Shift value 1 to the right | 
|---|
| 39 | jnc     LVM_ICRCT_NoXOR | 
|---|
| 40 | xor     dx, 0EDB8h | 
|---|
| 41 | xor     ax, 8320h | 
|---|
| 42 | LVM_ICRCT_NoXOR: | 
|---|
| 43 | dec     ch | 
|---|
| 44 | jnz     LVM_ICRCT_Loop2 | 
|---|
| 45 | mov     wptr [di+0], ax | 
|---|
| 46 | mov     wptr [di+2], dx | 
|---|
| 47 | add     di, 4 | 
|---|
| 48 | add     cl, 1 | 
|---|
| 49 | jnc     LVM_ICRCT_Loop | 
|---|
| 50 | ret | 
|---|
| 51 | LVM_InitCRCTable                EndP | 
|---|
| 52 |  | 
|---|
| 53 | ; Calculates an LVM-Sector CRC of a given sector | 
|---|
| 54 | ;        In: DS:SI - Points to Sector... | 
|---|
| 55 | ;       Out: DX:AX - LVM CRC | 
|---|
| 56 | ; Destroyed: None | 
|---|
| 57 | LVM_GetSectorCRC                Proc Near   Uses bx cx | 
|---|
| 58 | push    word ptr [si+LocLVM_CRC+00] | 
|---|
| 59 | push    word ptr [si+LocLVM_CRC+02] | 
|---|
| 60 | push    si | 
|---|
| 61 | mov     word ptr [si+LocLVM_CRC], 0 | 
|---|
| 62 | mov     word ptr [si+LocLVM_CRC+2], 0 | 
|---|
| 63 | mov     ax, -1 | 
|---|
| 64 | mov     dx, -1 | 
|---|
| 65 | mov     cx, 512 | 
|---|
| 66 | LVM_GSCRC_Loop: | 
|---|
| 67 | xor     bh, bh | 
|---|
| 68 | mov     bl, al                      ; Save last byte to BL | 
|---|
| 69 | mov     al, ah | 
|---|
| 70 | mov     ah, dl | 
|---|
| 71 | mov     dl, dh | 
|---|
| 72 | xor     dh, dh                      ; SHR DX:AX, 8 | 
|---|
| 73 | xor     bl, [si] | 
|---|
| 74 | inc     si                          ; XOR last byte with [data] | 
|---|
| 75 | shl     bx, 1 | 
|---|
| 76 | shl     bx, 1 | 
|---|
| 77 | xor     ax, word ptr [LVM_CRCTable+bx+0] | 
|---|
| 78 | xor     dx, word ptr [LVM_CRCTable+bx+2] ; XOR with CRC-Table | 
|---|
| 79 | loop    LVM_GSCRC_Loop | 
|---|
| 80 | pop     si | 
|---|
| 81 | pop     word ptr [si+LocLVM_CRC+2] | 
|---|
| 82 | pop     word ptr [si+LocLVM_CRC] | 
|---|
| 83 | ret | 
|---|
| 84 | LVM_GetSectorCRC                EndP | 
|---|
| 85 |  | 
|---|
| 86 | ; Checks ds:[SI], if a valid LVM Signature is found (sets carry in that case) | 
|---|
| 87 | ;  This does not check for valid LVM CRC (which also needs to be done) | 
|---|
| 88 | ;        In: DS:SI - Sector that needs to get checked... | 
|---|
| 89 | ;       Out: Carry set, if valid LVM signature found | 
|---|
| 90 | ; Destroyed: None | 
|---|
| 91 | LVM_CheckSectorSignature        Proc Near | 
|---|
| 92 | test    byte ptr [CFG_IgnoreLVM], 1 ; We are supposed to ignore LVM, so | 
|---|
| 93 | jnz     LVMCSS_InvalidSignature     ;  any sector is bad! | 
|---|
| 94 | cmp     word ptr [si+LocLVM_SignatureStart], 5202h | 
|---|
| 95 | jne     LVMCSS_InvalidSignature | 
|---|
| 96 | cmp     word ptr [si+LocLVM_SignatureStart+2], 'BM' | 
|---|
| 97 | jne     LVMCSS_InvalidSignature | 
|---|
| 98 | cmp     word ptr [si+LocLVM_SignatureStart+4], 'MP' | 
|---|
| 99 | jne     LVMCSS_InvalidSignature | 
|---|
| 100 | cmp     word ptr [si+LocLVM_SignatureStart+6], 'DF' | 
|---|
| 101 | jne     LVMCSS_InvalidSignature | 
|---|
| 102 | stc | 
|---|
| 103 | ret | 
|---|
| 104 | LVMCSS_InvalidSignature: | 
|---|
| 105 | clc | 
|---|
| 106 | ret | 
|---|
| 107 | LVM_CheckSectorSignature        EndP | 
|---|
| 108 |  | 
|---|
| 109 | ; Checks Sector for a valid LVM CRC is encountered | 
|---|
| 110 | ;  First one should check for a valid signature and call this later. | 
|---|
| 111 | ;        In: DS:SI - Sector that needs to get checked... | 
|---|
| 112 | ;       Out: Carry set, if LVM CRC valid | 
|---|
| 113 | ; Destroyed: None | 
|---|
| 114 | LVM_CheckSectorCRC              Proc Near   Uses ax dx | 
|---|
| 115 | call    LVM_GetSectorCRC | 
|---|
| 116 | cmp     ax, word ptr [si+LocLVM_CRC] | 
|---|
| 117 | jne     LVMCSCRC_BadCRC | 
|---|
| 118 | cmp     dx, word ptr [si+LocLVM_CRC+2] | 
|---|
| 119 | jne     LVMCSCRC_BadCRC | 
|---|
| 120 | stc | 
|---|
| 121 | ret | 
|---|
| 122 | LVMCSCRC_BadCRC: | 
|---|
| 123 | clc | 
|---|
| 124 | ret | 
|---|
| 125 | LVM_CheckSectorCRC              EndP | 
|---|
| 126 |  | 
|---|
| 127 | ; Updates Sector with valid LVM CRC | 
|---|
| 128 | ;  This one doesn't check, if it's really an LVM sector, so check before! | 
|---|
| 129 | ;        In: DS:SI - Sector that needs to get checked... | 
|---|
| 130 | ;       Out: None, CRC updated | 
|---|
| 131 | ; Destroyed: None | 
|---|
| 132 | LVM_UpdateSectorCRC            Proc Near   Uses ax dx | 
|---|
| 133 | call    LVM_GetSectorCRC | 
|---|
| 134 | mov     word ptr [si+LocLVM_CRC], ax | 
|---|
| 135 | mov     word ptr [si+LocLVM_CRC+2], dx | 
|---|
| 136 | ret | 
|---|
| 137 | LVM_UpdateSectorCRC            EndP | 
|---|
| 138 |  | 
|---|
| 139 | ; Searches for a partition in LVM Information Sector and sets SI to point to | 
|---|
| 140 | ;  the LVM-entry. It will also set CARRY then. | 
|---|
| 141 | ;        In: DX:AX - LBA starting sector of partition to be searched | 
|---|
| 142 | ;            DS:SI - Valid (previously checked) LVM-Information-Sector | 
|---|
| 143 | ;       Out: Carry set, if partition found | 
|---|
| 144 | ;            DS:SI - points to LVM information entry | 
|---|
| 145 | ; Destroyed: None | 
|---|
| 146 | LVM_SearchForPartition          Proc Near   Uses cx | 
|---|
| 147 | cmp     byte ptr [si+LocLVM_SignatureStart], LocLVM_SignatureByte0 | 
|---|
| 148 | jne     LVMSFP_NotFound               ; Quick Check, if LVM sector there | 
|---|
| 149 | add     si, LocLVM_StartOfEntries | 
|---|
| 150 | mov     cl, LocLVM_MaxEntries | 
|---|
| 151 | LVMSFP_Loop: | 
|---|
| 152 | cmp     ax, [si+LocLVM_PartitionStart] | 
|---|
| 153 | jne     LVMSFP_NextEntry | 
|---|
| 154 | cmp     dx, [si+LocLVM_PartitionStart+2] | 
|---|
| 155 | je      LVMSFP_FoundIt | 
|---|
| 156 | LVMSFP_NextEntry: | 
|---|
| 157 | add     si, LocLVM_LenOfEntry | 
|---|
| 158 | dec     cl | 
|---|
| 159 | jnz     LVMSFP_Loop | 
|---|
| 160 | LVMSFP_NotFound: | 
|---|
| 161 | clc | 
|---|
| 162 | ret | 
|---|
| 163 | LVMSFP_FoundIt: | 
|---|
| 164 | stc | 
|---|
| 165 | ret | 
|---|
| 166 | LVM_SearchForPartition          EndP | 
|---|
| 167 |  | 
|---|
| 168 |  | 
|---|
| 169 | ; Gets a drive-letter from the LVM-info of a partition. (if it exists) | 
|---|
| 170 | ;        In: BX:CX - LBA starting sector of partition to be searched | 
|---|
| 171 | ;            DL = Physical Disk in BIOS notation. (80h+) | 
|---|
| 172 | ;       Out: CY=1 if LVM-info found, 0 if no LVM-info. | 
|---|
| 173 | ;            AL - drive-letter from LVM-info or zero if no drive-letter | 
|---|
| 174 | ;            assigned or no LVM-info. | 
|---|
| 175 | LVM_GetDriveLetter      Proc Near   Uses bx cx dx si di ds es | 
|---|
| 176 | ; For primary partitions this information is stored in the last | 
|---|
| 177 | ; sector of track0; for all four partition entries in case they | 
|---|
| 178 | ; they are all primary ones. | 
|---|
| 179 | ; | 
|---|
| 180 | ; LVM DLAT info for logical partitions is stored in the sector | 
|---|
| 181 | ; preceding the start of the partition. | 
|---|
| 182 | ; | 
|---|
| 183 | ; Because the LVM info of a logical partition is the easiest to find, | 
|---|
| 184 | ; we do that first. The LVM info for primary partitions is located | 
|---|
| 185 | ; dependent on the geometry in use, so we use a special locater | 
|---|
| 186 | ; call for that. Also, since the LVM info for primaries contains | 
|---|
| 187 | ; info on all 4 entries, we need the partition index to obtain the | 
|---|
| 188 | ; correct drive-letter. | 
|---|
| 189 | ; | 
|---|
| 190 |  | 
|---|
| 191 | ; See if this is a primary partition | 
|---|
| 192 | ; CY will be set if it is and AL will contain the 0-based | 
|---|
| 193 | ; index in the P-table. | 
|---|
| 194 | ; If it's a logical partition, CY will be clear and AL | 
|---|
| 195 | ; will be set to 0ffh indicating an invalid index. | 
|---|
| 196 | call    PART_IsPrimaryPartition | 
|---|
| 197 | mov     al,0 | 
|---|
| 198 | rcl     al,1        ; CY if primary | 
|---|
| 199 | mov     dh,al       ; Save PRI or LOG | 
|---|
| 200 |  | 
|---|
| 201 | ; Save PRI/LOG indicator for later use | 
|---|
| 202 | push    dx | 
|---|
| 203 |  | 
|---|
| 204 | ; Load *possible* LVM sector | 
|---|
| 205 | ; This load is only valid if the partition is logical, in which case | 
|---|
| 206 | ; the LVM sector is below the start of the partition. | 
|---|
| 207 | ; If primary, the LVM sector is at a location that | 
|---|
| 208 | ; DriveIO_LoadMasterLVMSector will find out. | 
|---|
| 209 |  | 
|---|
| 210 | ; Push LBA address | 
|---|
| 211 | push    bx | 
|---|
| 212 | push    cx | 
|---|
| 213 |  | 
|---|
| 214 | ; Adjust for logical LVM-sector | 
|---|
| 215 | sub     cx,1 | 
|---|
| 216 | sbb     bx,0 | 
|---|
| 217 |  | 
|---|
| 218 | ; Load the LVM sector | 
|---|
| 219 | push    si | 
|---|
| 220 | push    di | 
|---|
| 221 | mov     si,offset [LVMSector] | 
|---|
| 222 | mov     di,ds | 
|---|
| 223 | call    DriveIO_LoadSectorLBA                                           ; Change this to normal IO-routine !!!!!! | 
|---|
| 224 | pop     di | 
|---|
| 225 | pop     si | 
|---|
| 226 |  | 
|---|
| 227 | ; Restore LBA address | 
|---|
| 228 | pop     cx | 
|---|
| 229 | pop     bx | 
|---|
| 230 |  | 
|---|
| 231 | ; Restore PRI/LOG partition indicator in DH | 
|---|
| 232 | pop     dx | 
|---|
| 233 |  | 
|---|
| 234 | ; Test PRI or not | 
|---|
| 235 | test    dh,dh | 
|---|
| 236 | ; It's not a PRI so we can use the previously loaded LVM sector | 
|---|
| 237 | jz      LVM_GetDriveLetter_is_not_pri | 
|---|
| 238 |  | 
|---|
| 239 | ; | 
|---|
| 240 | ; It's a PRI so we use the special locator function. | 
|---|
| 241 | ; This locator takes care of extended OS/2 geometry should that be used | 
|---|
| 242 | ; | 
|---|
| 243 | call    DriveIO_LoadMasterLVMSector | 
|---|
| 244 |  | 
|---|
| 245 | LVM_GetDriveLetter_is_not_pri: | 
|---|
| 246 |  | 
|---|
| 247 |  | 
|---|
| 248 | ; | 
|---|
| 249 | ; At this stage the LVM-info sector has been loaded at [LVMSector]. | 
|---|
| 250 | ; From here we look for an LVM entry for the partition. | 
|---|
| 251 | ; If one is found, based on it's LBA-start, it's driveletter is used | 
|---|
| 252 | ; in case byte 25h in the BPB is zero. | 
|---|
| 253 | ; | 
|---|
| 254 |  | 
|---|
| 255 |  | 
|---|
| 256 | ; Search for the partition in the LVM info. | 
|---|
| 257 | ; If found, CY is set and SI points to LVM entry. | 
|---|
| 258 | push    si | 
|---|
| 259 | mov     ax,cx | 
|---|
| 260 | mov     dx,bx | 
|---|
| 261 | mov     si,offset [LVMSector] | 
|---|
| 262 | call    LVM_SearchForPartition | 
|---|
| 263 | mov     bx,si   ; BX now points to LVM entry | 
|---|
| 264 | mov     dx,0 | 
|---|
| 265 | pop     si | 
|---|
| 266 |  | 
|---|
| 267 | mov     al,0    ; Setup null driveletter | 
|---|
| 268 | ; Oops, no valid LVM record was used so we have a null driveletter. | 
|---|
| 269 | jnc     LVM_GetDriveLetter_null_lvm_dl | 
|---|
| 270 |  | 
|---|
| 271 | ; | 
|---|
| 272 | ; At this point BX points to the LVM-entry related to the | 
|---|
| 273 | ; partition, whether it was a logical or a primary one. | 
|---|
| 274 | ; | 
|---|
| 275 | mov     al,[bx+LocLVM_VolumeLetter] | 
|---|
| 276 | ; Test for zero dtive-letter. | 
|---|
| 277 | test    al,al | 
|---|
| 278 | ; Preset CY in case drive-letter is zero. | 
|---|
| 279 | clc | 
|---|
| 280 | jz      LVM_GetDriveLetter_null_lvm_dl | 
|---|
| 281 |  | 
|---|
| 282 | ; We have a non-zero drive-letter, so set CY. | 
|---|
| 283 | stc | 
|---|
| 284 |  | 
|---|
| 285 | LVM_GetDriveLetter_null_lvm_dl: | 
|---|
| 286 | ret | 
|---|
| 287 | LVM_GetDriveLetter      EndP | 
|---|
| 288 |  | 
|---|
| 289 |  | 
|---|
| 290 |  | 
|---|
| 291 | ; Sets a drive-letter in the LVM-info of a partition. (if it exists) | 
|---|
| 292 | ;        In: BX:CX - LBA starting sector of partition to be searched | 
|---|
| 293 | ;            DL = Physical Disk in BIOS notation. (80h+) | 
|---|
| 294 | ;            AL = DriveLetter to set (can be zero to hide partition from LVM) | 
|---|
| 295 | ;       Out: CY=1 if LVM-info found, 0 if no LVM-info. | 
|---|
| 296 | LVM_SetDriveLetter      Proc Near   Uses bx cx dx si di ds es | 
|---|
| 297 | local   disk:byte | 
|---|
| 298 | local   drive_letter:byte | 
|---|
| 299 | local   pri_ind:byte | 
|---|
| 300 | local   lvm_log_high:word | 
|---|
| 301 | local   lvm_log_low:word | 
|---|
| 302 | ; For primary partitions this information is stored in the last | 
|---|
| 303 | ; sector of track0; for all four partition entries in case they | 
|---|
| 304 | ; they are all primary ones. | 
|---|
| 305 | ; | 
|---|
| 306 | ; LVM DLAT info for logical partitions is stored in the sector | 
|---|
| 307 | ; preceding the start of the partition. | 
|---|
| 308 | ; | 
|---|
| 309 | ; Because the LVM info of a logical partition is the easiest to find, | 
|---|
| 310 | ; we do that first. The LVM info for primary partitions is located | 
|---|
| 311 | ; dependent on the geometry in use, so we use a special locater | 
|---|
| 312 | ; call for that. Also, since the LVM info for primaries contains | 
|---|
| 313 | ; info on all 4 entries, we need the partition index to obtain the | 
|---|
| 314 | ; correct drive-letter. | 
|---|
| 315 | ; | 
|---|
| 316 |  | 
|---|
| 317 | mov     [disk], dl | 
|---|
| 318 |  | 
|---|
| 319 | ; Store the drive-letter for later use | 
|---|
| 320 | mov     [drive_letter], al | 
|---|
| 321 |  | 
|---|
| 322 |  | 
|---|
| 323 | ; See if this is a primary partition | 
|---|
| 324 | ; CY will be set if it is and AL will contain the 0-based | 
|---|
| 325 | ; index in the P-table. | 
|---|
| 326 | ; If it's a logical partition, CY will be clear and AL | 
|---|
| 327 | ; will be set to 0ffh indicating an invalid index. | 
|---|
| 328 | call    PART_IsPrimaryPartition | 
|---|
| 329 | mov     al,0 | 
|---|
| 330 | rcl     al,1        ; CY if primary | 
|---|
| 331 | mov     dh,al       ; Save PRI or LOG | 
|---|
| 332 | mov     [pri_ind],al | 
|---|
| 333 |  | 
|---|
| 334 | ; Save PRI/LOG indicator for later use | 
|---|
| 335 | push    dx | 
|---|
| 336 |  | 
|---|
| 337 | ; Load *possible* LVM sector | 
|---|
| 338 | ; This load is only valid if the partition is logical, in which case | 
|---|
| 339 | ; the LVM sector is below the start of the partition. | 
|---|
| 340 | ; If primary, the LVM sector is at a location that | 
|---|
| 341 | ; DriveIO_LoadMasterLVMSector will find out. | 
|---|
| 342 |  | 
|---|
| 343 | ; Push LBA address | 
|---|
| 344 | push    bx | 
|---|
| 345 | push    cx | 
|---|
| 346 |  | 
|---|
| 347 | ; Adjust for logical LVM-sector | 
|---|
| 348 | sub     cx,1 | 
|---|
| 349 | sbb     bx,0 | 
|---|
| 350 |  | 
|---|
| 351 | ; Store LBA address of LVM-sector | 
|---|
| 352 | mov     [lvm_log_low],cx | 
|---|
| 353 | mov     [lvm_log_high],bx | 
|---|
| 354 |  | 
|---|
| 355 | ; Load the LVM sector | 
|---|
| 356 | push    si | 
|---|
| 357 | push    di | 
|---|
| 358 | mov     si,offset [LVMSector] | 
|---|
| 359 | mov     di,ds | 
|---|
| 360 | call    DriveIO_LoadSectorLBA                                           ; Change this to normal IO-routine !!!!!! | 
|---|
| 361 | pop     di | 
|---|
| 362 | pop     si | 
|---|
| 363 |  | 
|---|
| 364 | ; Restore LBA address | 
|---|
| 365 | pop     cx | 
|---|
| 366 | pop     bx | 
|---|
| 367 |  | 
|---|
| 368 | ; Restore PRI/LOG partition indicator in DH | 
|---|
| 369 | pop     dx | 
|---|
| 370 |  | 
|---|
| 371 | ; Test PRI or not | 
|---|
| 372 | test    dh,dh | 
|---|
| 373 | ; It's not a PRI so we can use the previously loaded LVM sector | 
|---|
| 374 | jz      LVM_SetDriveLetter_is_not_pri | 
|---|
| 375 |  | 
|---|
| 376 | ; | 
|---|
| 377 | ; It's a PRI so we use the special locator function. | 
|---|
| 378 | ; This locator takes care of extended OS/2 geometry should that be used | 
|---|
| 379 | ; | 
|---|
| 380 | call    DriveIO_LoadMasterLVMSector | 
|---|
| 381 | jnc     LVM_SetDriveLetter_null_lvm_dl | 
|---|
| 382 |  | 
|---|
| 383 | mov     ax, word ptr [MasterLVMLBA]                                         ; ARRAY VAN MAKEN ! | 
|---|
| 384 | mov     [lvm_log_low], ax | 
|---|
| 385 | mov     [lvm_log_high], 0 | 
|---|
| 386 |  | 
|---|
| 387 | LVM_SetDriveLetter_is_not_pri: | 
|---|
| 388 |  | 
|---|
| 389 | ; | 
|---|
| 390 | ; At this stage the LVM-info sector has been loaded at [LVMSector]. | 
|---|
| 391 | ; From here we look for an LVM entry for the partition. | 
|---|
| 392 | ; If one is found, based on it's LBA-start, it's driveletter is used | 
|---|
| 393 | ; in case byte 25h in the BPB is zero. | 
|---|
| 394 | ; | 
|---|
| 395 |  | 
|---|
| 396 | ; Search for the partition in the LVM info. | 
|---|
| 397 | ; If found, CY is set and SI points to LVM entry. | 
|---|
| 398 | push    si | 
|---|
| 399 | mov     ax,cx | 
|---|
| 400 | mov     dx,bx | 
|---|
| 401 | mov     si,offset [LVMSector] | 
|---|
| 402 | call    LVM_SearchForPartition | 
|---|
| 403 | mov     bx,si   ; BX now points to LVM entry | 
|---|
| 404 | pop     si | 
|---|
| 405 |  | 
|---|
| 406 | mov     al,0    ; Setup null driveletter | 
|---|
| 407 | ; Oops, no valid LVM record was used so we have a null driveletter. | 
|---|
| 408 | jnc     LVM_SetDriveLetter_null_lvm_dl | 
|---|
| 409 |  | 
|---|
| 410 | ; | 
|---|
| 411 | ; At this point BX points to the LVM-entry related to the | 
|---|
| 412 | ; partition, whether it was a logical or a primary one. | 
|---|
| 413 | ; | 
|---|
| 414 | mov     al, [drive_letter] | 
|---|
| 415 | mov     [bx+LocLVM_VolumeLetter],al | 
|---|
| 416 |  | 
|---|
| 417 | mov     si, offset [LVMSector] | 
|---|
| 418 | call    LVM_UpdateSectorCRC | 
|---|
| 419 |  | 
|---|
| 420 | mov     dl, [disk] | 
|---|
| 421 | mov     bx, [lvm_log_high] | 
|---|
| 422 | mov     ax, [lvm_log_low] | 
|---|
| 423 |  | 
|---|
| 424 | call    DriveIO_SaveSector | 
|---|
| 425 |  | 
|---|
| 426 | LVM_SetDriveLetter_null_lvm_dl: | 
|---|
| 427 | ret | 
|---|
| 428 | LVM_SetDriveLetter      EndP | 
|---|
| 429 |  | 
|---|
| 430 |  | 
|---|
| 431 |  | 
|---|
| 432 | ; Removes a given drive-letter from the whole LVM information sector | 
|---|
| 433 | ;        In: CH    - drive-letter (ascii) | 
|---|
| 434 | ;            DS:SI - LVM-Information-Sector | 
|---|
| 435 | ;       Out: LVM-Information-Sector updated (including LVM CRC) | 
|---|
| 436 | ; Destroyed: None | 
|---|
| 437 | LVM_RemoveVolLetterFromSector   Proc Near   Uses cx | 
|---|
| 438 | cmp     bptr [si+LocLVM_SignatureStart], LocLVM_SignatureByte0 | 
|---|
| 439 | jne     LVMRVLFS_Done                 ; Quick Check, if LVM sector there | 
|---|
| 440 | push    si | 
|---|
| 441 | add     si, LocLVM_StartOfEntries | 
|---|
| 442 | mov     cl, LocLVM_MaxEntries | 
|---|
| 443 | LVMRVLFS_Loop: | 
|---|
| 444 | cmp     ch, [si+LocLVM_VolumeLetter] | 
|---|
| 445 | jne     LVMRVLFS_NextEntry | 
|---|
| 446 | ; Reset drive-letter, if matched | 
|---|
| 447 | mov     bptr [si+LocLVM_VolumeLetter], 0          ; ASSIGN NEXT FREE HERE...  (DOET DUBBEL ALS ZELFDE DL ALS SYS) | 
|---|
| 448 | LVMRVLFS_NextEntry: | 
|---|
| 449 | add     si, LocLVM_LenOfEntry | 
|---|
| 450 | dec     cl | 
|---|
| 451 | jnz     LVMRVLFS_Loop | 
|---|
| 452 | pop     si | 
|---|
| 453 | call    LVM_UpdateSectorCRC | 
|---|
| 454 | LVMRVLFS_Done: | 
|---|
| 455 | ret | 
|---|
| 456 | LVM_RemoveVolLetterFromSector   EndP | 
|---|
| 457 |  | 
|---|
| 458 | ; Reassigns LVM volume driveletter | 
|---|
| 459 | ;  Will remove the drive-letter from any volume that got it currently | 
|---|
| 460 | ;   and finally change the drive-letter of the given partition | 
|---|
| 461 | ;        In: AL    - drive-letter | 
|---|
| 462 | ;            DS:SI - points to partition, that needs that driveletter | 
|---|
| 463 | ;       Out: None | 
|---|
| 464 | ; Destroyed: AX | 
|---|
| 465 |  | 
|---|
| 466 | LVM_DoLetterReassignment        Proc Near   Uses bx cx dx si di | 
|---|
| 467 |  | 
|---|
| 468 | IFDEF   AUX_DEBUG | 
|---|
| 469 | pusha | 
|---|
| 470 | mov     si, offset dlra | 
|---|
| 471 | call    AuxIO_Print | 
|---|
| 472 | call    AuxIO_Teletype | 
|---|
| 473 | call    AuxIO_TeletypeNL | 
|---|
| 474 | popa | 
|---|
| 475 | ENDIF | 
|---|
| 476 |  | 
|---|
| 477 | mov     di, si              ; Save SI in DI (Partition-pointer) | 
|---|
| 478 | mov     ch, al              ; and AL in CH (drive-letter) | 
|---|
| 479 | xor     bx, bx | 
|---|
| 480 | mov     cl, CFG_Partitions | 
|---|
| 481 | or      cl, cl | 
|---|
| 482 | jz      LVMDLR_SkipRemove | 
|---|
| 483 |  | 
|---|
| 484 | LVMDLR_RemoveLoop: | 
|---|
| 485 | cmp     bptr [PartitionVolumeLetters+bx], ch | 
|---|
| 486 | jne     LVMDLR_NextPartition | 
|---|
| 487 | ; One volume that has our wanted drive-letter, so remove it! | 
|---|
| 488 | mov     dl, bl | 
|---|
| 489 | call    PART_GetPartitionPointer   ; DL - partition -> SI | 
|---|
| 490 | ; Now set CurPartition_Location for the DriveIO-functions to work | 
|---|
| 491 | mov     ax, wptr [si+LocIPT_AbsolutePartTable] | 
|---|
| 492 | mov     wptr [CurPartition_Location+0], ax | 
|---|
| 493 | mov     ax, wptr [si+LocIPT_AbsolutePartTable+2] | 
|---|
| 494 | mov     wptr [CurPartition_Location+2], ax | 
|---|
| 495 | mov     ax, wptr [si+LocIPT_LocationPartTable+1] | 
|---|
| 496 | mov     wptr [CurPartition_Location+6], ax | 
|---|
| 497 | mov     ah, bptr [si+LocIPT_LocationPartTable+0] | 
|---|
| 498 | mov     al, [si+LocIPT_Drive] | 
|---|
| 499 | mov     wptr [CurPartition_Location+4], ax | 
|---|
| 500 | call    DriveIO_LoadLVMSector      ; SI points now to LVM-Sector | 
|---|
| 501 | call    LVM_RemoveVolLetterFromSector | 
|---|
| 502 |  | 
|---|
| 503 | IFDEF ReleaseCode | 
|---|
| 504 | call    DriveIO_SaveLVMSector   ; Save sector | 
|---|
| 505 | ENDIF | 
|---|
| 506 | LVMDLR_NextPartition: | 
|---|
| 507 | inc     bx | 
|---|
| 508 | dec     cl | 
|---|
| 509 | jnz     LVMDLR_RemoveLoop | 
|---|
| 510 |  | 
|---|
| 511 | LVMDLR_SkipRemove: | 
|---|
| 512 | ; Set CurPartition_Location information of destination partition | 
|---|
| 513 | mov     ax, wptr [di+LocIPT_AbsolutePartTable] | 
|---|
| 514 | mov     wptr [CurPartition_Location+0], ax | 
|---|
| 515 | mov     ax, wptr [di+LocIPT_AbsolutePartTable+2] | 
|---|
| 516 | mov     wptr [CurPartition_Location+2], ax | 
|---|
| 517 | mov     ah, bptr [di+LocIPT_LocationPartTable+0] | 
|---|
| 518 | mov     al, [di+LocIPT_Drive] | 
|---|
| 519 | mov     wptr [CurPartition_Location+4], ax | 
|---|
| 520 | mov     ax, wptr [di+LocIPT_LocationPartTable+1] | 
|---|
| 521 | mov     wptr [CurPartition_Location+6], ax | 
|---|
| 522 | call    DriveIO_LoadLVMSector         ; SI points now to LVM-Sector | 
|---|
| 523 | mov     ax, wptr [di+LocIPT_AbsoluteBegin] | 
|---|
| 524 | mov     dx, wptr [di+LocIPT_AbsoluteBegin+2] | 
|---|
| 525 | mov     di, si                        ; Save SI in DI | 
|---|
| 526 | call    LVM_SearchForPartition | 
|---|
| 527 | jnc     LVMDLR_DestPartNotFound | 
|---|
| 528 | ; Set new volume letter | 
|---|
| 529 | mov     bptr [si+LocLVM_VolumeLetter], ch | 
|---|
| 530 | mov     si, di                        ; SI - LVM Sector again | 
|---|
| 531 | call    LVM_UpdateSectorCRC           ; Update LVM-CRC now | 
|---|
| 532 |  | 
|---|
| 533 | IFDEF ReleaseCode | 
|---|
| 534 | call    DriveIO_SaveLVMSector      ; Save sector | 
|---|
| 535 | ENDIF | 
|---|
| 536 |  | 
|---|
| 537 | LVMDLR_DestPartNotFound: | 
|---|
| 538 | ; This here is done for safety, because we misuse CurPartition_Location | 
|---|
| 539 | xor     ax, ax | 
|---|
| 540 | mov     di, offset CurPartition_Location | 
|---|
| 541 | mov     cx, 4 | 
|---|
| 542 | rep     stosw                         ; NUL out CurPartition_Location | 
|---|
| 543 | ret | 
|---|
| 544 | LVM_DoLetterReassignment        EndP | 
|---|
| 545 |  | 
|---|
| 546 |  | 
|---|
| 547 | ; This walks the IPT and for each partition it obtains the LVM drive-letter | 
|---|
| 548 | ; if available. This drive-letter is then marked as in-use in the Map. | 
|---|
| 549 | ; The FreeDriveletterMap is used by the drive-letter reassignment function | 
|---|
| 550 | ; to assign a new drive to a data-partition when a system-partition is booted | 
|---|
| 551 | ; with the same drive-letter. The original drive-letter for the data-partition | 
|---|
| 552 | ; is saved so it can be restored later when a system is booted that does not | 
|---|
| 553 | ; use the drive-letter. Note that there can be multiple system-partitions | 
|---|
| 554 | ; using the same drive-letter and data-partitions can become system-partition | 
|---|
| 555 | ; by making them bootable. (and vice versa) | 
|---|
| 556 | LVM_ComposeFreeDriveletterMap   Proc | 
|---|
| 557 |  | 
|---|
| 558 | ; get nr of partitions in IPT | 
|---|
| 559 | ; for each partition get LVM drive-letter and reset bit in map. | 
|---|
| 560 |  | 
|---|
| 561 | LVM_ComposeFreeDriveletterMap   EndP | 
|---|
| 562 |  | 
|---|