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
96
#![allow(non_camel_case_types, non_snake_case)]
use crate::co;
use crate::decl::*;
use crate::guard::*;
use crate::kernel::{ffi, privs::*};
handle! { HGLOBAL;
/// Handle to a
/// [global memory block](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc).
/// Originally just a `HANDLE`.
///
/// The allocated memory block is accessible through the
/// [`GlobalLock`](crate::HGLOBAL::GlobalLock) method.
}
impl HGLOBAL {
/// [`GlobalAlloc`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalalloc)
/// function.
#[must_use]
pub fn GlobalAlloc(flags: co::GMEM, num_bytes: usize) -> SysResult<GlobalFreeGuard> {
unsafe {
PtrRet(ffi::GlobalAlloc(flags.raw(), num_bytes))
.to_sysresult_handle()
.map(|h| GlobalFreeGuard::new(h))
}
}
/// [`GlobalFlags`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalflags)
/// function.
#[must_use]
pub fn GlobalFlags(&self) -> SysResult<co::GMEM> {
match unsafe { ffi::GlobalFlags(self.ptr()) } {
GMEM_INVALID_HANDLE => Err(GetLastError()),
flags => Ok(unsafe { co::GMEM::from_raw(flags) }),
}
}
/// [`GlobalLock`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globallock)
/// function.
///
/// Calls [`GlobalSize`](crate::HGLOBAL::GlobalSize) to retrieve the size of
/// the memory block.
///
/// # Examples
///
/// ```no_run
/// use winsafe::{self as w, prelude::*, co};
///
/// let hglobal = w::HGLOBAL::GlobalAlloc(
/// co::GMEM::FIXED | co::GMEM::ZEROINIT,
/// 120,
/// )?;
///
/// let mut block = hglobal.GlobalLock()?;
///
/// block.as_mut_slice()[0] = 40;
///
/// // GlobalUnlock() called automatically
///
/// // GlobalFree() called automatically
/// # w::SysResult::Ok(())
/// ```
#[must_use]
pub fn GlobalLock(&self) -> SysResult<GlobalUnlockGuard<'_>> {
let mem_sz = self.GlobalSize()?;
unsafe {
PtrRet(ffi::GlobalLock(self.ptr()))
.to_sysresult()
.map(|ptr| GlobalUnlockGuard::new(self, ptr, mem_sz))
}
}
/// [`GlobalReAlloc`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalrealloc)
/// function.
///
/// Originally this method returns the handle to the reallocated memory
/// object; here the original handle is automatically updated.
pub fn GlobalReAlloc(&mut self, num_bytes: usize, flags: co::GMEM) -> SysResult<()> {
PtrRet(unsafe { ffi::GlobalReAlloc(self.ptr(), num_bytes, flags.raw()) })
.to_sysresult_handle()
.map(|h| {
*self = h;
})
}
/// [`GlobalSize`](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-globalsize)
/// function.
#[must_use]
pub fn GlobalSize(&self) -> SysResult<usize> {
match unsafe { ffi::GlobalSize(self.ptr()) } {
0 => Err(GetLastError()),
sz => Ok(sz),
}
}
}