1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#![allow(non_camel_case_types, non_snake_case)]
use crate::co;
use crate::decl::*;
use crate::guard::*;
use crate::kernel::{ffi, privs::*};
handle! { HLOCAL;
/// Handle to a
/// [local memory block](https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types#hlocal).
///
/// The allocated memory block is accessible through the
/// [`LocalLock`](crate::HLOCAL::LocalLock) method.
}
impl HLOCAL {
/// [`LocalAlloc`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localalloc)
/// function.
#[must_use]
pub fn LocalAlloc(flags: Option<co::LMEM>, num_bytes: usize) -> SysResult<LocalFreeGuard> {
unsafe {
PtrRet(ffi::LocalAlloc(flags.unwrap_or_default().raw(), num_bytes))
.to_sysresult_handle()
.map(|h| LocalFreeGuard::new(h))
}
}
/// [`LocalFlags`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localflags)
/// function.
#[must_use]
pub fn LocalFlags(&self) -> SysResult<co::LMEM> {
match unsafe { ffi::LocalFlags(self.ptr()) } {
LMEM_INVALID_HANDLE => Err(GetLastError()),
flags => Ok(unsafe { co::LMEM::from_raw(flags) }),
}
}
/// [`LocalLock`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-locallock)
/// function.
///
/// Calls [`LocalSize`](crate::HLOCAL::LocalSize) to retrieve the size of
/// the memory block.
///
/// # Examples
///
/// ```no_run
/// use winsafe::{self as w, prelude::*, co};
///
/// let hlocal = w::HLOCAL::LocalAlloc(
/// Some(co::LMEM::FIXED | co::LMEM::ZEROINIT),
/// 120,
/// )?;
///
/// let mut block = hlocal.LocalLock()?;
///
/// block.as_mut_slice()[0] = 40;
///
/// // LocalUnlock() called automatically
///
/// // LocalFree() called automatically
/// # w::SysResult::Ok(())
/// ```
#[must_use]
pub fn LocalLock(&self) -> SysResult<LocalUnlockGuard<'_>> {
let mem_sz = self.LocalSize()?;
unsafe {
PtrRet(ffi::LocalLock(self.ptr()))
.to_sysresult()
.map(|ptr| LocalUnlockGuard::new(self, ptr, mem_sz))
}
}
/// [`LocalReAlloc`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localrealloc)
/// function.
///
/// Originally this method returns the handle to the reallocated memory
/// object; here the original handle is automatically updated.
pub fn LocalReAlloc(&mut self, num_bytes: usize, flags: Option<co::LMEM>) -> SysResult<()> {
PtrRet(unsafe { ffi::LocalReAlloc(self.ptr(), num_bytes, flags.unwrap_or_default().raw()) })
.to_sysresult_handle()
.map(|h| {
*self = h;
})
}
/// [`LocalSize`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localsize)
/// function.
#[must_use]
pub fn LocalSize(&self) -> SysResult<usize> {
match unsafe { ffi::LocalSize(self.ptr()) } {
0 => Err(GetLastError()),
sz => Ok(sz),
}
}
}