Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

816 lines
19 KiB

  1. DOSSEG
  2. .MODEL LARGE
  3. include partit.inc
  4. .DATA?
  5. public PartitionList
  6. PartitionList dd ?
  7. public PartitionListCount
  8. PartitionListCount dw ?
  9. .CODE
  10. ASSUME ds:NOTHING
  11. extrn _InitializeDiskList:far
  12. extrn _OpenDisk:far
  13. extrn _CloseDisk:far
  14. extrn _ReadDisk:far
  15. extrn _WriteDisk:far
  16. extrn _malloc:far
  17. extrn _free:far
  18. .386
  19. ;++
  20. ;
  21. ; UINT
  22. ; _far
  23. ; InitializePartitionList(
  24. ; VOID
  25. ; );
  26. ;
  27. ; Routine Description:
  28. ;
  29. ; This routine initializes internal data structures necessary so that
  30. ; other partition-related routines in this module can be called.
  31. ;
  32. ; All int13 disks are enumerated to find all primary and extended
  33. ; partitions. A data structure is build for each partition/logical drive
  34. ; and relevent information is saved away.
  35. ;
  36. ; Arguments:
  37. ;
  38. ; None.
  39. ;
  40. ; Return Value:
  41. ;
  42. ; Total count of all partitions on all disks that we can deal with.
  43. ; 0 if an error occurs.
  44. ;
  45. ;--
  46. SectorBufferh equ word ptr [bp-2]
  47. SectorBufferl equ word ptr [bp-4]
  48. CurrentSectorh equ word ptr [bp-6]
  49. CurrentSectorl equ word ptr [bp-8]
  50. NextSectorh equ word ptr [bp-10]
  51. NextSectorl equ word ptr [bp-12]
  52. ExtStarth equ word ptr [bp-14]
  53. ExtStartl equ word ptr [bp-16]
  54. DiskHandleh equ word ptr [bp-18]
  55. DiskHandlel equ word ptr [bp-20]
  56. PartCount equ word ptr [bp-22]
  57. InMbr equ byte ptr [bp-24]
  58. public _InitializePartitionList
  59. _InitializePartitionList proc far
  60. push bp
  61. mov bp,sp
  62. sub sp,24
  63. push ds
  64. push es
  65. push bx
  66. push si
  67. push di
  68. mov PartCount,0
  69. ;
  70. ; Allocate a sector buffer. Note that we havn'e overwritten ds
  71. ; so it is addressing _DATA, which is required by the crt.
  72. ;
  73. push 512
  74. call _malloc
  75. add sp,2
  76. mov cx,ax
  77. or cx,dx
  78. jz exit ; ax already 0 for error exit
  79. mov SectorBufferl,ax
  80. mov SectorBufferh,dx
  81. ;
  82. ; _InitializeDiskList could return 0 in case of
  83. ; failure but the code below will then simply execute
  84. ; zero iterations of its loop.
  85. ;
  86. call _InitializeDiskList
  87. mov si,ax ; si is limit of disk ids
  88. mov di,0 ; di is current disk id
  89. nextdisk:
  90. cmp si,di
  91. je done
  92. ;
  93. ; Open this disk.
  94. ;
  95. push di
  96. call _OpenDisk
  97. add sp,2
  98. mov cx,ax
  99. or cx,dx
  100. jz exit ; open failed, bail out
  101. mov DiskHandlel,ax
  102. mov DiskHandleh,dx ; save disk handle
  103. ;
  104. ; Read partition table for this disk
  105. ;
  106. xor ax,ax
  107. mov NextSectorl,ax
  108. mov NextSectorh,ax
  109. mov ExtStartl,ax
  110. mov ExtStarth,ax
  111. mov InMbr,1
  112. nextptable:
  113. ;
  114. ; Read current mbr/ebr
  115. ;
  116. push SectorBufferh
  117. push SectorBufferl
  118. push 1
  119. mov ax,NextSectorh
  120. mov CurrentSectorh,ax
  121. push ax
  122. mov ax,NextSectorl
  123. mov CurrentSectorl,ax
  124. push ax
  125. push DiskHandleh
  126. push DiskHandlel
  127. call _ReadDisk
  128. add sp,14
  129. cmp ax,0
  130. jz exit ; ax already 0 for error exit
  131. mov NextSectorl,0
  132. mov NextSectorh,0
  133. mov bx,SectorBufferl
  134. add bx,1beh
  135. mov ax,SectorBufferh
  136. mov es,ax ; es:bx -> first partition table entry
  137. mov cx,4
  138. nextent:
  139. cmp byte ptr es:[bx+4],0
  140. jz nextent1 ; unused entry
  141. cmp byte ptr es:[bx+4],5
  142. je gotlink
  143. cmp byte ptr es:[bx+4],0fh
  144. jnz gotentry
  145. gotlink:
  146. ;
  147. ; Link-type partition, track next ebr location
  148. ;
  149. mov ax,ExtStartl
  150. add ax,es:[bx+8]
  151. mov NextSectorl,ax
  152. mov ax,ExtStarth
  153. adc ax,es:[bx+10]
  154. mov NextSectorh,ax
  155. cmp InMbr,1
  156. jne nextent1
  157. mov ax,es:[bx+8]
  158. mov ExtStartl,ax
  159. mov ax,es:[bx+10]
  160. mov ExtStarth,ax
  161. jmp nextent1
  162. gotentry:
  163. mov ax,CurrentSectorl
  164. add ax,es:[bx+8]
  165. mov dx,CurrentSectorh
  166. adc dx,es:[bx+10]
  167. push cx
  168. push bx
  169. push es
  170. ;
  171. ; Before calling crt ensure that ds addresses _DATA
  172. ;
  173. push ds
  174. mov ax,DGROUP
  175. mov ds,ax
  176. push SIZE PART_INFO
  177. call _malloc
  178. add sp,2
  179. pop ds
  180. pop es
  181. pop bx
  182. mov cx,ax
  183. or cx,dx
  184. pop cx ; does not affect flags
  185. jz exit ; ax already 0 for error exit
  186. push si
  187. push ds
  188. mov ds,dx
  189. mov si,ax ; ds:si -> new partition record
  190. mov ax,PartCount
  191. mov [si].PartInfoOrdinal,ax
  192. inc PartCount
  193. mov ax,CurrentSectorl
  194. add ax,es:[bx+8]
  195. mov [si].PartInfoStartSectorl,ax
  196. mov ax,CurrentSectorh
  197. adc ax,es:[bx+10]
  198. mov [si].PartInfoStartSectorh,ax
  199. mov ax,es:[bx+12]
  200. mov [si].PartInfoSectorCountl,ax
  201. mov ax,es:[bx+14]
  202. mov [si].PartInfoSectorCounth,ax
  203. mov al,es:[bx+4]
  204. mov [si].PartInfoSystemId,al
  205. mov [si].PartInfoDiskId,di
  206. mov [si].PartInfoPartOpen,0
  207. mov [si].PartInfoDiskHandlel,0
  208. mov [si].PartInfoDiskHandleh,0
  209. ;
  210. ; Insert at head of linked list
  211. ;
  212. push es
  213. push di
  214. mov ax,DGROUP
  215. mov es,ax
  216. mov di,OFFSET DGROUP:[PartitionList] ; es:di = &PartitionList
  217. mov ax,es:[di]
  218. mov [si].PartInfoNextl,ax
  219. mov ax,es:[di+2]
  220. mov [si].PartInfoNexth,ax ; Record->Next = PartitionList
  221. mov es:[di],si
  222. mov es:[di+2],dx ; PartitionList = Record
  223. pop di
  224. pop es
  225. pop ds
  226. pop si ; restore int13 unit limit
  227. nextent1:
  228. add bx,16
  229. dec cx
  230. jz @f
  231. jmp nextent
  232. @@:
  233. mov InMbr,0
  234. ;
  235. ; If we found a link entry, follow it. Otherwise we're done
  236. ; with this disk.
  237. ;
  238. cmp NextSectorl,0
  239. jnz nextptable
  240. cmp NextSectorh,0
  241. jnz nextptable
  242. push DiskHandleh
  243. push DiskHandlel
  244. call _CloseDisk
  245. add sp,4
  246. inc di
  247. jmp nextdisk
  248. done:
  249. push DGROUP
  250. pop ds ; address DGROUP for crt
  251. push SectorBufferh
  252. push SectorBufferl
  253. call _free
  254. add sp,4
  255. mov ax,PartCount
  256. mov si,OFFSET DGROUP:PartitionListCount
  257. mov [si],ax ; save count in global var
  258. exit:
  259. pop di
  260. pop si
  261. pop bx
  262. pop es
  263. pop ds
  264. leave
  265. retf
  266. _InitializePartitionList endp
  267. ;++
  268. ;
  269. ; BOOL
  270. ; _far
  271. ; GetPartitionInfoById(
  272. ; IN UINT PartitionId,
  273. ; IN UINT Reserved,
  274. ; OUT FPUINT DiskId,
  275. ; OUT FPBYTE SystemId,
  276. ; OUT FPULONG StartSector,
  277. ; OUT FPULONG SectorCount
  278. ; );
  279. ;
  280. ; BOOL
  281. ; _far
  282. ; GetPartitionInfoByHandle(
  283. ; IN HPARTITION PartitionHandle,
  284. ; OUT FPUINT DiskId,
  285. ; OUT FPBYTE SystemId,
  286. ; OUT FPULONG StartSector,
  287. ; OUT FPULONG SectorCount
  288. ; );
  289. ;
  290. ; Routine Description:
  291. ;
  292. ; These routines retrieve information about a particular partition,
  293. ; either by an ordinal id (range: 0 - n-1 where n is the value returned
  294. ; by InitializePartitionList()), or by a handle returned from
  295. ; OpenPartition().
  296. ;
  297. ; Arguments:
  298. ;
  299. ; PartitionId/PartitionHandle - supplies ordinal id or handle that
  300. ; identifies the partition whose information is of interest.
  301. ;
  302. ; Reserved - unused.
  303. ;
  304. ; DiskId - receives the disk id of the disk where the partition is.
  305. ;
  306. ; SystemId - receives the system id of the partition from the
  307. ; partition table, if known, or 0 if not.
  308. ;
  309. ; StartSector - recieves the absolute physical start sector on the
  310. ; drive where the partition lives.
  311. ;
  312. ; SectorCount - recieves the number of sectors in the partition.
  313. ;
  314. ; Return Value:
  315. ;
  316. ; 0 - failure
  317. ; non-0 - success and caller's variables filled in
  318. ;
  319. ;--
  320. PartitionId equ word ptr [bp+6]
  321. PartitionHandle equ dword ptr [bp+6]
  322. DiskId equ dword ptr [bp+10]
  323. SystemId equ dword ptr [bp+14]
  324. StartSector equ dword ptr [bp+18]
  325. SectorCount equ dword ptr [bp+22]
  326. public _GetPartitionInfoById
  327. _GetPartitionInfoById proc far
  328. push bp
  329. mov bp,sp
  330. push ds
  331. push es
  332. push si
  333. push di
  334. ;
  335. ; Locate the partition record for the requested partition.
  336. ; The far pointer comes back in dx:si and ds:si.
  337. ;
  338. mov ax,PartitionId
  339. call far ptr pLocatePartitionRecord
  340. cmp dx,0
  341. jnz get_p_id
  342. cmp si,0
  343. jz error1
  344. ;
  345. ; Transfer the relevent fields to the caller's variables.
  346. ;
  347. get_p_id:
  348. les di,DiskId
  349. mov ax,[si].PartInfoDiskId
  350. mov es:[di],ax
  351. les di,SystemId
  352. mov al,[si].PartInfoSystemId
  353. mov es:[di],al
  354. les di,StartSector
  355. mov ax,[si].PartInfoStartSectorl
  356. mov es:[di],ax
  357. mov ax,[si].PartInfoStartSectorh
  358. mov es:[di+2],ax
  359. les di,SectorCount
  360. mov ax,[si].PartInfoSectorCountl
  361. mov es:[di],ax
  362. mov ax,[si].PartInfoSectorCounth
  363. mov es:[di+2],ax
  364. mov ax,1
  365. jmp short exit1
  366. error1:
  367. xor ax,ax
  368. exit1:
  369. pop di
  370. pop si
  371. pop es
  372. pop ds
  373. leave
  374. retf
  375. _GetPartitionInfoById endp
  376. public _GetPartitionInfoByHandle
  377. _GetPartitionInfoByHandle label far
  378. push bp
  379. mov bp,sp
  380. push ds
  381. push es
  382. push si
  383. push di
  384. ;
  385. ; Make sure it's open, if not give error.
  386. ;
  387. lds si,PartitionHandle
  388. cmp [si].PartInfoPartOpen,0
  389. jne short get_p_id
  390. je error1
  391. ;++
  392. ;
  393. ; HPARTITION
  394. ; _far
  395. ; OpenPartition(
  396. ; IN UINT PartitionId
  397. ; );
  398. ;
  399. ; Routine Description:
  400. ;
  401. ; This routine 'opens' a partition so that subsequent io may be
  402. ; performed on it.
  403. ;
  404. ; Note that a partition can be open only once at a time.
  405. ;
  406. ; Note that this routine also opens the underlying disk.
  407. ; Disks can be opened only once at a time, thus this routine will
  408. ; fail if the disk is already open.
  409. ;
  410. ; Arguments:
  411. ;
  412. ; PartitionId - supplies an ordinal value identifying the partition.
  413. ; Valid range is 0 - n-1, where n is the number returned
  414. ; from InitializePartitionList().
  415. ;
  416. ; Return Value:
  417. ;
  418. ; If successful, returns a value to be used as a handle to the
  419. ; partition for subsequent i/o with other routines in this module.
  420. ; If failure, returns 0.
  421. ;
  422. ;--
  423. PartitionId equ word ptr [bp+6]
  424. public _OpenPartition
  425. _OpenPartition proc far
  426. push bp
  427. mov bp,sp
  428. push ds
  429. push si
  430. ;
  431. ; Locate the partition record for the requested partition.
  432. ; The far pointer comes back in dx:si and ds:si.
  433. ;
  434. mov ax,PartitionId
  435. call far ptr pLocatePartitionRecord
  436. mov cx,si
  437. or cx,dx
  438. jnz @f
  439. mov ax,cx ; dx:ax = 0
  440. jz o_p_3
  441. ;
  442. ; Make sure the partition is not already open.
  443. ;
  444. @@: cmp [si].PartInfoPartOpen,0
  445. je @f
  446. mov ax,0
  447. mov dx,ax
  448. jne o_p_3
  449. ;
  450. ; Open the underlying disk.
  451. ;
  452. @@: push [si].PartInfoDiskId
  453. call _OpenDisk
  454. add sp,2
  455. mov cx,ax
  456. or cx,dx
  457. jz o_p_3
  458. ;
  459. ; Remember disk handle, that the partition is open,
  460. ; and return the pointer to the partition record as the handle.
  461. ;
  462. mov [si].PartInfoDiskHandlel,ax
  463. mov [si].PartInfoDiskHandleh,dx
  464. inc [si].PartInfoPartOpen
  465. mov dx,ds
  466. mov ax,si
  467. o_p_3:
  468. pop si
  469. pop ds
  470. leave
  471. retf
  472. _OpenPartition endp
  473. ;++
  474. ;
  475. ; VOID
  476. ; _far
  477. ; ClosePartition(
  478. ; IN HPARTITION PartitionHandle
  479. ; );
  480. ;
  481. ; Routine Description:
  482. ;
  483. ; This routine 'closes' a partition previously opened by
  484. ; OpenPartition.
  485. ;
  486. ; This routine also releases its handle to the disk that
  487. ; contains the partition.
  488. ;
  489. ; Arguments:
  490. ;
  491. ; PartitionHandle - supplies a handle previously returned by
  492. ; OpenPartition().
  493. ;
  494. ; Return Value:
  495. ;
  496. ; None.
  497. ;
  498. ;--
  499. PartitionHandle equ dword ptr [bp+6]
  500. public _ClosePartition
  501. _ClosePartition proc far
  502. push bp
  503. mov bp,sp
  504. push ds
  505. push si
  506. ;
  507. ; If not open, nothing to do.
  508. ;
  509. lds si,PartitionHandle
  510. cmp [si].PartInfoPartOpen,0
  511. je c_p_3
  512. ;
  513. ; Close the disk.
  514. ;
  515. push [si].PartInfoDiskHandleh
  516. push [si].PartInfoDiskHandlel
  517. call _CloseDisk
  518. add sp,4
  519. ;
  520. ; Indicate partition closed
  521. ;
  522. mov cx,0
  523. mov [si].PartInfoPartOpen,cl
  524. mov [si].PartInfoDiskHandlel,cx
  525. mov [si].PartInfoDiskHandleh,cx
  526. c_p_3:
  527. pop si
  528. pop ds
  529. leave
  530. retf
  531. _ClosePartition endp
  532. ;++
  533. ;
  534. ; BOOL
  535. ; _far
  536. ; ReadPartition(
  537. ; IN HPARTITION PartitionHandle,
  538. ; IN ULONG StartSector,
  539. ; IN BYTE SectorCount,
  540. ; OUT FPVOID Buffer
  541. ; );
  542. ;
  543. ; BOOL
  544. ; _far
  545. ; WritePartition(
  546. ; IN HPARTITION PartitionHandle,
  547. ; IN ULONG StartSector,
  548. ; IN BYTE SectorCount,
  549. ; IN FPVOID Buffer
  550. ; );
  551. ;
  552. ; Routine Description:
  553. ;
  554. ; These routines read from or write to a partition previously opened by
  555. ; OpenPartition. I/Os use the proper method for the disk,
  556. ; ie, int13, xint13, etc. This routine also ensures that
  557. ; I/O doesn't cross a track boundary.
  558. ;
  559. ; This routine does NOT however, worry about DMA boundaries.
  560. ; The caller must take care of this.
  561. ;
  562. ; Arguments:
  563. ;
  564. ; StartSector - supplies the 0-based sector relative to the start
  565. ; of the partition where I/O is to start.
  566. ;
  567. ; SectorCount - supplies the number of sectors to be transferred.
  568. ;
  569. ; Return Value:
  570. ;
  571. ; 0 - failure
  572. ; non-0 - success
  573. ;
  574. ;--
  575. PartitionHandle equ dword ptr [bp+6]
  576. StartSector equ dword ptr [bp+10]
  577. StartSectorl equ word ptr [bp+10]
  578. StartSectorh equ word ptr [bp+12]
  579. SectorCount equ [bp+14]
  580. Buffer equ dword ptr [bp+16]
  581. Bufferh equ word ptr [bp+18]
  582. IoRoutine equ dword ptr [bp-4]
  583. IoRoutinel equ word ptr [bp-4]
  584. IoRoutineh equ word ptr [bp-2]
  585. public _ReadPartition
  586. _ReadPartition label far
  587. mov dx,SEG _ReadDisk
  588. mov ax,OFFSET _ReadDisk
  589. jmp short PartitionIo
  590. public _WritePartition
  591. _WritePartition label far
  592. mov dx,SEG _WriteDisk
  593. mov ax,OFFSET _WriteDisk
  594. PartitionIo proc far
  595. push bp
  596. mov bp,sp
  597. sub sp,4
  598. push ds
  599. push es
  600. push bx
  601. push si
  602. push di
  603. ;
  604. ; The partition handle is actually a far pointer to
  605. ; the partition data record. Make sure it's open.
  606. ;
  607. lds si,PartitionHandle ; ds:si -> partition record
  608. cmp [si].PartInfoPartOpen,0
  609. jne @f
  610. xor ax,ax
  611. jmp short iodone
  612. ;
  613. ; Store the i/o routine pointer, passed to us in dx:ax.
  614. ;
  615. @@: mov IoRoutineh,dx
  616. mov IoRoutinel,ax
  617. ;
  618. ; Adjust the start sector to be disk-based instead of
  619. ; partition-based.
  620. ;
  621. mov ax,[si].PartInfoStartSectorl
  622. add StartSectorl,ax
  623. mov ax,[si].PartInfoStartSectorh
  624. adc StartSectorh,ax ; StartSector is physical sector#
  625. ;
  626. ; Call the disk routine to do the read.
  627. ;
  628. push Buffer
  629. push SectorCount
  630. push StartSector
  631. push [si].PartInfoDiskHandleh
  632. push [si].PartInfoDiskHandlel
  633. call IoRoutine
  634. add sp,14
  635. iodone:
  636. pop di
  637. pop si
  638. pop bx
  639. pop es
  640. pop ds
  641. leave
  642. retf
  643. PartitionIo endp
  644. ;++
  645. ;
  646. ; PVOID
  647. ; _far
  648. ; pLocatePartitionRecord(
  649. ; IN UINT PartitionId
  650. ; );
  651. ;
  652. ; Routine Description:
  653. ;
  654. ;
  655. ; Internal routine.
  656. ;
  657. ; This routine locates a partition record in the linked list
  658. ; of all partition records as prepared by InitializePartitionList().
  659. ;
  660. ; Arguments:
  661. ;
  662. ; PartitionId - supplies an ordinal value identifying the partition.
  663. ; Valid range is 0 - n-1, where n is the number returned
  664. ; from InitializePartitionList().
  665. ;
  666. ; This parameter is passed in ax, not on the stack.
  667. ;
  668. ; Return Value:
  669. ;
  670. ; NULL if record not located.
  671. ; Otherwise fills ds:si and dx:si with a far pointer to the
  672. ; partition record.
  673. ;
  674. ;--
  675. pLocatePartitionRecord proc far
  676. mov dx,DGROUP
  677. mov ds,dx
  678. mov si,OFFSET PartitionList ; ds:si = &PartitionList
  679. ;
  680. ; Note that this code depends on the link field in the
  681. ; partition record structure being first!
  682. ;
  683. .errnz PartInfoNext
  684. lpr_loop:
  685. lds si,[si].PartInfoNext
  686. mov dx,ds
  687. cmp dx,0
  688. jz lpr_done ; end of list, we're done
  689. cmp [si].PartInfoOrdinal,ax
  690. jz lpr_done
  691. jmp short lpr_loop
  692. lpr_done:
  693. ret
  694. pLocatePartitionRecord endp
  695. end