88// if there is insufficient memory. So we treat any NULL output as an
99// `OUT_OF_RESOURCES` error.
1010
11+ use crate :: mem:: PoolAllocation ;
1112use crate :: proto:: device_path:: { DevicePath , DevicePathNode } ;
1213use crate :: proto:: unsafe_protocol;
13- use crate :: { boot , CStr16 , Char16 , Result , Status } ;
14+ use crate :: { CStr16 , Char16 , Result , Status } ;
1415use core:: ops:: Deref ;
1516use core:: ptr:: NonNull ;
1617use uefi_raw:: protocol:: device_path:: { DevicePathFromTextProtocol , DevicePathToTextProtocol } ;
@@ -42,12 +43,12 @@ pub struct AllowShortcuts(pub bool);
4243/// Wrapper for a string internally allocated from
4344/// UEFI boot services memory.
4445#[ derive( Debug ) ]
45- pub struct PoolString ( NonNull < Char16 > ) ;
46+ pub struct PoolString ( PoolAllocation ) ;
4647
4748impl PoolString {
4849 fn new ( text : * const Char16 ) -> Result < Self > {
4950 NonNull :: new ( text. cast_mut ( ) )
50- . map ( Self )
51+ . map ( |p| Self ( PoolAllocation :: new ( p . cast ( ) ) ) )
5152 . ok_or ( Status :: OUT_OF_RESOURCES . into ( ) )
5253 }
5354}
@@ -56,13 +57,31 @@ impl Deref for PoolString {
5657 type Target = CStr16 ;
5758
5859 fn deref ( & self ) -> & Self :: Target {
59- unsafe { CStr16 :: from_ptr ( self . 0 . as_ptr ( ) ) }
60+ unsafe { CStr16 :: from_ptr ( self . 0 . as_ptr ( ) . as_ptr ( ) . cast ( ) ) }
6061 }
6162}
6263
63- impl Drop for PoolString {
64- fn drop ( & mut self ) {
65- unsafe { boot:: free_pool ( self . 0 . cast ( ) ) } . expect ( "Failed to free pool [{addr:#?}]" ) ;
64+ /// Device path allocated from UEFI pool memory.
65+ #[ derive( Debug ) ]
66+ pub struct PoolDevicePath ( PoolAllocation ) ;
67+
68+ impl Deref for PoolDevicePath {
69+ type Target = DevicePath ;
70+
71+ fn deref ( & self ) -> & Self :: Target {
72+ unsafe { DevicePath :: from_ffi_ptr ( self . 0 . as_ptr ( ) . as_ptr ( ) . cast ( ) ) }
73+ }
74+ }
75+
76+ /// Device path node allocated from UEFI pool memory.
77+ #[ derive( Debug ) ]
78+ pub struct PoolDevicePathNode ( PoolAllocation ) ;
79+
80+ impl Deref for PoolDevicePathNode {
81+ type Target = DevicePathNode ;
82+
83+ fn deref ( & self ) -> & Self :: Target {
84+ unsafe { DevicePathNode :: from_ffi_ptr ( self . 0 . as_ptr ( ) . as_ptr ( ) . cast ( ) ) }
6685 }
6786}
6887
@@ -144,14 +163,12 @@ impl DevicePathFromText {
144163 pub fn convert_text_to_device_node (
145164 & self ,
146165 text_device_node : & CStr16 ,
147- ) -> Result < & DevicePathNode > {
166+ ) -> Result < PoolDevicePathNode > {
148167 unsafe {
149168 let ptr = ( self . 0 . convert_text_to_device_node ) ( text_device_node. as_ptr ( ) . cast ( ) ) ;
150- if ptr. is_null ( ) {
151- Err ( Status :: OUT_OF_RESOURCES . into ( ) )
152- } else {
153- Ok ( DevicePathNode :: from_ffi_ptr ( ptr. cast ( ) ) )
154- }
169+ NonNull :: new ( ptr. cast_mut ( ) )
170+ . map ( |p| PoolDevicePathNode ( PoolAllocation :: new ( p. cast ( ) ) ) )
171+ . ok_or ( Status :: OUT_OF_RESOURCES . into ( ) )
155172 }
156173 }
157174
@@ -165,14 +182,12 @@ impl DevicePathFromText {
165182 /// memory for the conversion.
166183 ///
167184 /// [`OUT_OF_RESOURCES`]: Status::OUT_OF_RESOURCES
168- pub fn convert_text_to_device_path ( & self , text_device_path : & CStr16 ) -> Result < & DevicePath > {
185+ pub fn convert_text_to_device_path ( & self , text_device_path : & CStr16 ) -> Result < PoolDevicePath > {
169186 unsafe {
170187 let ptr = ( self . 0 . convert_text_to_device_path ) ( text_device_path. as_ptr ( ) . cast ( ) ) ;
171- if ptr. is_null ( ) {
172- Err ( Status :: OUT_OF_RESOURCES . into ( ) )
173- } else {
174- Ok ( DevicePath :: from_ffi_ptr ( ptr. cast ( ) ) )
175- }
188+ NonNull :: new ( ptr. cast_mut ( ) )
189+ . map ( |p| PoolDevicePath ( PoolAllocation :: new ( p. cast ( ) ) ) )
190+ . ok_or ( Status :: OUT_OF_RESOURCES . into ( ) )
176191 }
177192 }
178193}
0 commit comments