1 // Licensed under the Apache License, Version 2.0 2 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 3 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option. 4 // All files in the project carrying such notice may not be copied, modified, or distributed 5 // except according to those terms. 6 //! Macros to make things easier to define 7 macro_rules! DECLARE_HANDLE { 8 ($name:ident, $inner:ident) => { 9 pub enum $inner {} 10 pub type $name = *mut $inner; 11 }; 12 } 13 macro_rules! MAKE_HRESULT { 14 ($sev:expr, $fac:expr, $code:expr) => { 15 ($sev << 31) | ($fac << 16) | $code 16 } 17 } 18 macro_rules! MAKE_SCODE { 19 ($sev:expr, $fac:expr, $code:expr) => { 20 ($sev << 31) | ($fac << 16) | $code 21 } 22 } 23 macro_rules! HIDP_ERROR_CODES { 24 ($sev:expr, $code:expr) => { 25 ($sev << 28) | (FACILITY_HID_ERROR_CODE << 16) | $code 26 } 27 } 28 macro_rules! MAKEFOURCC { 29 ($a:expr, $b:expr, $c:expr, $d:expr) => { 30 ($a as u32) | (($b as u32) << 8) | (($c as u32) << 16) | (($d as u32) << 24) 31 } 32 } 33 #[macro_export] 34 macro_rules! DEFINE_GUID { 35 ( 36 $name:ident, $l:expr, $w1:expr, $w2:expr, 37 $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr 38 ) => { 39 pub const $name: $crate::shared::guiddef::GUID = $crate::shared::guiddef::GUID { 40 Data1: $l, 41 Data2: $w1, 42 Data3: $w2, 43 Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], 44 }; 45 } 46 } 47 macro_rules! DEFINE_BLUETOOTH_UUID128 { 48 ($name:ident, $shortId:expr) => { 49 DEFINE_GUID!{$name, 50 $shortId as u32, 0x0000, 0x1000, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB} 51 } 52 } 53 #[macro_export] 54 macro_rules! DEFINE_PROPERTYKEY { 55 ( 56 $name:ident, $l:expr, $w1:expr, $w2:expr, 57 $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr, 58 $pid:expr 59 ) => { 60 pub const $name: PROPERTYKEY 61 = PROPERTYKEY { 62 fmtid: $crate::shared::guiddef::GUID { 63 Data1: $l, 64 Data2: $w1, 65 Data3: $w2, 66 Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], 67 }, 68 pid: $pid, 69 }; 70 } 71 } 72 #[macro_export] 73 macro_rules! DEFINE_DEVPROPKEY { 74 ( 75 $name:ident, $l:expr, $w1:expr, $w2:expr, 76 $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr, 77 $pid:expr 78 ) => { 79 pub const $name: DEVPROPKEY = DEVPROPKEY { 80 fmtid: $crate::shared::guiddef::GUID { 81 Data1: $l, 82 Data2: $w1, 83 Data3: $w2, 84 Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], 85 }, 86 pid: $pid, 87 }; 88 } 89 } 90 macro_rules! CTL_CODE { 91 ($DeviceType:expr, $Function:expr, $Method:expr, $Access:expr) => { 92 ($DeviceType << 16) | ($Access << 14) | ($Function << 2) | $Method 93 } 94 } 95 macro_rules! BTH_CTL { 96 ($id:expr) => { 97 CTL_CODE!(FILE_DEVICE_BLUETOOTH, $id, METHOD_BUFFERED, FILE_ANY_ACCESS) 98 }; 99 } 100 macro_rules! BTH_KERNEL_CTL { 101 ($id:expr) => { 102 CTL_CODE!(FILE_DEVICE_BLUETOOTH, $id, METHOD_NEITHER, FILE_ANY_ACCESS) 103 }; 104 } 105 macro_rules! HID_CTL_CODE { 106 ($id:expr) => { 107 CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_NEITHER, FILE_ANY_ACCESS) 108 } 109 } 110 macro_rules! HID_BUFFER_CTL_CODE { 111 ($id:expr) => { 112 CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_BUFFERED, FILE_ANY_ACCESS) 113 } 114 } 115 macro_rules! HID_IN_CTL_CODE { 116 ($id:expr) => { 117 CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_IN_DIRECT, FILE_ANY_ACCESS) 118 } 119 } 120 macro_rules! HID_OUT_CTL_CODE { 121 ($id:expr) => { 122 CTL_CODE!(FILE_DEVICE_KEYBOARD, $id, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) 123 } 124 } 125 macro_rules! AUDCLNT_ERR { 126 ($n:expr) => { 127 MAKE_HRESULT!(SEVERITY_ERROR, FACILITY_AUDCLNT, $n) 128 }; 129 } 130 macro_rules! AUDCLNT_SUCCESS { 131 ($n:expr) => { 132 MAKE_SCODE!(SEVERITY_SUCCESS, FACILITY_AUDCLNT, $n) 133 }; 134 } 135 macro_rules! BCRYPT_MAKE_INTERFACE_VERSION { 136 ($major:expr, $minor:expr) => { 137 $crate::shared::bcrypt::BCRYPT_INTERFACE_VERSION { 138 MajorVersion: $major, MinorVersion: $minor, 139 } 140 } 141 } 142 macro_rules! MAKEINTRESOURCE { 143 ($i:expr) => { $i as u16 as usize as LPWSTR } 144 } 145 #[macro_export] 146 macro_rules! RIDL { 147 (#[uuid($l:expr, $w1:expr, $w2:expr, 148 $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr)] 149 class $class:ident;) => ( 150 pub enum $class {} 151 impl $crate::Class for $class { 152 #[inline] 153 fn uuidof() -> $crate::shared::guiddef::GUID { 154 $crate::shared::guiddef::GUID { 155 Data1: $l, 156 Data2: $w1, 157 Data3: $w2, 158 Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], 159 } 160 } 161 } 162 ); 163 (#[uuid($($uuid:expr),+)] 164 interface $interface:ident ($vtbl:ident) {$( 165 $(#[$($attrs:tt)*])* fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty, 166 )+}) => ( 167 RIDL!{@vtbl $interface $vtbl () $( 168 $(#[$($attrs)*])* fn $method($($p: $t,)*) -> $rtr, 169 )+} 170 #[repr(C)] 171 pub struct $interface { 172 pub lpVtbl: *const $vtbl, 173 } 174 impl $interface { 175 $(RIDL!{@method $(#[$($attrs)*])* fn $method($($p: $t,)*) -> $rtr})+ 176 } 177 RIDL!{@uuid $interface $($uuid),+} 178 ); 179 (#[uuid($($uuid:expr),+)] 180 interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {}) => ( 181 RIDL!{@vtbl $interface $vtbl (pub parent: $pvtbl,)} 182 #[repr(C)] 183 pub struct $interface { 184 pub lpVtbl: *const $vtbl, 185 } 186 RIDL!{@deref $interface $pinterface} 187 RIDL!{@uuid $interface $($uuid),+} 188 ); 189 (#[uuid($($uuid:expr),+)] 190 interface $interface:ident ($vtbl:ident) : $pinterface:ident ($pvtbl:ident) {$( 191 $(#[$($attrs:tt)*])* fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty, 192 )+}) => ( 193 RIDL!{@vtbl $interface $vtbl (pub parent: $pvtbl,) $( 194 $(#[$($attrs)*])* fn $method($($p: $t,)*) -> $rtr, 195 )+} 196 #[repr(C)] 197 pub struct $interface { 198 pub lpVtbl: *const $vtbl, 199 } 200 impl $interface { 201 $(RIDL!{@method $(#[$($attrs)*])* fn $method($($p: $t,)*) -> $rtr})+ 202 } 203 RIDL!{@deref $interface $pinterface} 204 RIDL!{@uuid $interface $($uuid),+} 205 ); 206 (@deref $interface:ident $pinterface:ident) => ( 207 impl $crate::_core::ops::Deref for $interface { 208 type Target = $pinterface; 209 #[inline] 210 fn deref(&self) -> &$pinterface { 211 unsafe { &*(self as *const $interface as *const $pinterface) } 212 } 213 } 214 ); 215 (@method fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty) => ( 216 #[inline] pub unsafe fn $method(&self, $($p: $t,)*) -> $rtr { 217 ((*self.lpVtbl).$method)(self as *const _ as *mut _, $($p,)*) 218 } 219 ); 220 (@method #[fixme] fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty) => ( 221 #[inline] pub unsafe fn $method(&self, $($p: $t,)*) -> $rtr { 222 let mut ret = $crate::_core::mem::uninitialized(); 223 ((*self.lpVtbl).$method)(self as *const _ as *mut _, &mut ret, $($p,)*); 224 ret 225 } 226 ); 227 (@vtbl $interface:ident $vtbl:ident ($($fields:tt)*) 228 $(fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty,)* 229 ) => ( 230 RIDL!{@item #[repr(C)] 231 pub struct $vtbl { 232 $($fields)* 233 $(pub $method: unsafe extern "system" fn( 234 This: *mut $interface, 235 $($p: $t,)* 236 ) -> $rtr,)* 237 }} 238 ); 239 (@vtbl $interface:ident $vtbl:ident ($($fields:tt)*) 240 fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty, 241 $($tail:tt)*) => ( 242 RIDL!{@vtbl $interface $vtbl ( 243 $($fields)* 244 pub $method: unsafe extern "system" fn( 245 This: *mut $interface, 246 $($p: $t,)* 247 ) -> $rtr, 248 ) $($tail)*} 249 ); 250 (@vtbl $interface:ident $vtbl:ident ($($fields:tt)*) 251 #[fixme] fn $method:ident($($p:ident : $t:ty,)*) -> $rtr:ty, 252 $($tail:tt)*) => ( 253 RIDL!{@vtbl $interface $vtbl ( 254 $($fields)* 255 pub $method: unsafe extern "system" fn( 256 This: *mut $interface, 257 ret: *mut $rtr, 258 $($p: $t,)* 259 ) -> *mut $rtr, 260 ) $($tail)*} 261 ); 262 (@uuid $interface:ident 263 $l:expr, $w1:expr, $w2:expr, 264 $b1:expr, $b2:expr, $b3:expr, $b4:expr, $b5:expr, $b6:expr, $b7:expr, $b8:expr 265 ) => ( 266 impl $crate::Interface for $interface { 267 #[inline] 268 fn uuidof() -> $crate::shared::guiddef::GUID { 269 $crate::shared::guiddef::GUID { 270 Data1: $l, 271 Data2: $w1, 272 Data3: $w2, 273 Data4: [$b1, $b2, $b3, $b4, $b5, $b6, $b7, $b8], 274 } 275 } 276 } 277 ); 278 (@item $thing:item) => ($thing); 279 } 280 macro_rules! UNION { 281 ($(#[$attrs:meta])* union $name:ident { 282 [$stype:ty; $ssize:expr], 283 $($variant:ident $variant_mut:ident: $ftype:ty,)+ 284 }) => ( 285 #[repr(C)] $(#[$attrs])* 286 pub struct $name([$stype; $ssize]); 287 impl Copy for $name {} 288 impl Clone for $name { 289 #[inline] 290 fn clone(&self) -> $name { *self } 291 } 292 #[cfg(feature = "impl-default")] 293 impl Default for $name { 294 #[inline] 295 fn default() -> $name { unsafe { $crate::_core::mem::zeroed() } } 296 } 297 impl $name {$( 298 #[inline] 299 pub unsafe fn $variant(&self) -> &$ftype { 300 &*(self as *const _ as *const $ftype) 301 } 302 #[inline] 303 pub unsafe fn $variant_mut(&mut self) -> &mut $ftype { 304 &mut *(self as *mut _ as *mut $ftype) 305 } 306 )+} 307 ); 308 ($(#[$attrs:meta])* union $name:ident { 309 [$stype32:ty; $ssize32:expr] [$stype64:ty; $ssize64:expr], 310 $($variant:ident $variant_mut:ident: $ftype:ty,)+ 311 }) => ( 312 #[repr(C)] $(#[$attrs])* #[cfg(target_pointer_width = "32")] 313 pub struct $name([$stype32; $ssize32]); 314 #[repr(C)] $(#[$attrs])* #[cfg(target_pointer_width = "64")] 315 pub struct $name([$stype64; $ssize64]); 316 impl Copy for $name {} 317 impl Clone for $name { 318 #[inline] 319 fn clone(&self) -> $name { *self } 320 } 321 #[cfg(feature = "impl-default")] 322 impl Default for $name { 323 #[inline] 324 fn default() -> $name { unsafe { $crate::_core::mem::zeroed() } } 325 } 326 impl $name {$( 327 #[inline] 328 pub unsafe fn $variant(&self) -> &$ftype { 329 &*(self as *const _ as *const $ftype) 330 } 331 #[inline] 332 pub unsafe fn $variant_mut(&mut self) -> &mut $ftype { 333 &mut *(self as *mut _ as *mut $ftype) 334 } 335 )+} 336 ); 337 } 338 macro_rules! BITFIELD { 339 ($base:ident $field:ident: $fieldtype:ty [ 340 $($thing:ident $set_thing:ident[$r:expr],)+ 341 ]) => { 342 impl $base {$( 343 #[inline] 344 pub fn $thing(&self) -> $fieldtype { 345 let size = $crate::core::mem::size_of::<$fieldtype>() * 8; 346 self.$field << (size - $r.end) >> (size - $r.end + $r.start) 347 } 348 #[inline] 349 pub fn $set_thing(&mut self, val: $fieldtype) { 350 let mask = ((1 << ($r.end - $r.start)) - 1) << $r.start; 351 self.$field &= !mask; 352 self.$field |= (val << $r.start) & mask; 353 } 354 )+} 355 } 356 } 357 #[macro_export] 358 macro_rules! ENUM { 359 {enum $name:ident { $($variant:ident = $value:expr,)+ }} => { 360 pub type $name = u32; 361 $(pub const $variant: $name = $value;)+ 362 }; 363 {enum $name:ident { $variant:ident = $value:expr, $($rest:tt)* }} => { 364 pub type $name = u32; 365 pub const $variant: $name = $value; 366 ENUM!{@gen $name $variant, $($rest)*} 367 }; 368 {enum $name:ident { $variant:ident, $($rest:tt)* }} => { 369 ENUM!{enum $name { $variant = 0, $($rest)* }} 370 }; 371 {@gen $name:ident $base:ident,} => {}; 372 {@gen $name:ident $base:ident, $variant:ident = $value:expr, $($rest:tt)*} => { 373 pub const $variant: $name = $value; 374 ENUM!{@gen $name $variant, $($rest)*} 375 }; 376 {@gen $name:ident $base:ident, $variant:ident, $($rest:tt)*} => { 377 pub const $variant: $name = $base + 1u32; 378 ENUM!{@gen $name $variant, $($rest)*} 379 }; 380 } 381 #[macro_export] 382 macro_rules! STRUCT { 383 (#[debug] $($rest:tt)*) => ( 384 STRUCT!{#[cfg_attr(feature = "impl-debug", derive(Debug))] $($rest)*} 385 ); 386 ($(#[$attrs:meta])* struct $name:ident { 387 $($field:ident: $ftype:ty,)+ 388 }) => ( 389 #[repr(C)] #[derive(Copy)] $(#[$attrs])* 390 pub struct $name { 391 $(pub $field: $ftype,)+ 392 } 393 impl Clone for $name { 394 #[inline] 395 fn clone(&self) -> $name { *self } 396 } 397 #[cfg(feature = "impl-default")] 398 impl Default for $name { 399 #[inline] 400 fn default() -> $name { unsafe { $crate::_core::mem::zeroed() } } 401 } 402 ); 403 } 404 macro_rules! IFDEF { 405 ($($thing:item)*) => ($($thing)*) 406 } 407 macro_rules! FN { 408 (stdcall $func:ident($($t:ty,)*) -> $ret:ty) => ( 409 pub type $func = Option<unsafe extern "system" fn($($t,)*) -> $ret>; 410 ); 411 (stdcall $func:ident($($p:ident: $t:ty,)*) -> $ret:ty) => ( 412 pub type $func = Option<unsafe extern "system" fn($($p: $t,)*) -> $ret>; 413 ); 414 (cdecl $func:ident($($t:ty,)*) -> $ret:ty) => ( 415 pub type $func = Option<unsafe extern "C" fn($($t,)*) -> $ret>; 416 ); 417 (cdecl $func:ident($($p:ident: $t:ty,)*) -> $ret:ty) => ( 418 pub type $func = Option<unsafe extern "C" fn($($p: $t,)*) -> $ret>; 419 ); 420 } 421 macro_rules! _WSAIO { 422 ($x:expr, $y:expr) => { 423 $crate::shared::ws2def::IOC_VOID | $x | $y 424 } 425 } 426 macro_rules! _WSAIOR { 427 ($x:expr, $y:expr) => { 428 $crate::shared::ws2def::IOC_OUT | $x | $y 429 } 430 } 431 macro_rules! _WSAIOW { 432 ($x:expr, $y:expr) => { 433 $crate::shared::ws2def::IOC_IN | $x | $y 434 } 435 } 436 macro_rules! _WSAIORW { 437 ($x:expr, $y:expr) => { 438 $crate::shared::ws2def::IOC_INOUT | $x | $y 439 } 440 } 441