1 // Copyright © 2015-2017 winapi-rs developers 2 // Licensed under the Apache License, Version 2.0 3 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 4 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option. 5 // All files in the project carrying such notice may not be copied, modified, or distributed 6 // except according to those terms. 7 //! ApiSet Contract for api-ms-win-core-memory-l1-1-0 8 use ctypes::c_void; 9 use shared::basetsd::{PSIZE_T, PULONG_PTR, SIZE_T, ULONG64, ULONG_PTR}; 10 use shared::minwindef::{ 11 BOOL, DWORD, LPCVOID, LPDWORD, LPVOID, PBOOL, PDWORD, PULONG, UINT, ULONG, 12 }; 13 use um::minwinbase::{LPSECURITY_ATTRIBUTES, PSECURITY_ATTRIBUTES}; 14 use um::winnt::{ 15 HANDLE, LPCWSTR, PCWSTR, PMEMORY_BASIC_INFORMATION, PVOID, SECTION_ALL_ACCESS, 16 SECTION_MAP_EXECUTE_EXPLICIT, SECTION_MAP_READ, SECTION_MAP_WRITE, 17 }; 18 pub const FILE_MAP_WRITE: DWORD = SECTION_MAP_WRITE; 19 pub const FILE_MAP_READ: DWORD = SECTION_MAP_READ; 20 pub const FILE_MAP_ALL_ACCESS: DWORD = SECTION_ALL_ACCESS; 21 pub const FILE_MAP_EXECUTE: DWORD = SECTION_MAP_EXECUTE_EXPLICIT; 22 pub const FILE_MAP_COPY: DWORD = 0x00000001; 23 pub const FILE_MAP_RESERVE: DWORD = 0x80000000; 24 pub const FILE_MAP_TARGETS_INVALID: DWORD = 0x40000000; 25 pub const FILE_MAP_LARGE_PAGES: DWORD = 0x20000000; 26 extern "system" { VirtualAlloc( lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD, ) -> LPVOID27 pub fn VirtualAlloc( 28 lpAddress: LPVOID, 29 dwSize: SIZE_T, 30 flAllocationType: DWORD, 31 flProtect: DWORD, 32 ) -> LPVOID; VirtualProtect( lpAddress: LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, lpflOldProtect: PDWORD, ) -> BOOL33 pub fn VirtualProtect( 34 lpAddress: LPVOID, 35 dwSize: SIZE_T, 36 flNewProtect: DWORD, 37 lpflOldProtect: PDWORD, 38 ) -> BOOL; VirtualFree( lpAddress: LPVOID, dwSize: SIZE_T, dwFreeType: DWORD, ) -> BOOL39 pub fn VirtualFree( 40 lpAddress: LPVOID, 41 dwSize: SIZE_T, 42 dwFreeType: DWORD, 43 ) -> BOOL; VirtualQuery( lpAddress: LPCVOID, lpBuffer: PMEMORY_BASIC_INFORMATION, dwLength: SIZE_T, ) -> SIZE_T44 pub fn VirtualQuery( 45 lpAddress: LPCVOID, 46 lpBuffer: PMEMORY_BASIC_INFORMATION, 47 dwLength: SIZE_T, 48 ) -> SIZE_T; VirtualAllocEx( hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD, ) -> LPVOID49 pub fn VirtualAllocEx( 50 hProcess: HANDLE, 51 lpAddress: LPVOID, 52 dwSize: SIZE_T, 53 flAllocationType: DWORD, 54 flProtect: DWORD, 55 ) -> LPVOID; VirtualFreeEx( hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, dwFreeType: DWORD, ) -> BOOL56 pub fn VirtualFreeEx( 57 hProcess: HANDLE, 58 lpAddress: LPVOID, 59 dwSize: SIZE_T, 60 dwFreeType: DWORD, 61 ) -> BOOL; VirtualProtectEx( hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, lpflOldProtect: PDWORD, ) -> BOOL62 pub fn VirtualProtectEx( 63 hProcess: HANDLE, 64 lpAddress: LPVOID, 65 dwSize: SIZE_T, 66 flNewProtect: DWORD, 67 lpflOldProtect: PDWORD, 68 ) -> BOOL; VirtualQueryEx( hProcess: HANDLE, lpAddress: LPCVOID, lpBuffer: PMEMORY_BASIC_INFORMATION, dwLength: SIZE_T, ) -> SIZE_T69 pub fn VirtualQueryEx( 70 hProcess: HANDLE, 71 lpAddress: LPCVOID, 72 lpBuffer: PMEMORY_BASIC_INFORMATION, 73 dwLength: SIZE_T, 74 ) -> SIZE_T; ReadProcessMemory( hProcess: HANDLE, lpBaseAddress: LPCVOID, lpBuffer: LPVOID, nSize: SIZE_T, lpNumberOfBytesRead: *mut SIZE_T, ) -> BOOL75 pub fn ReadProcessMemory( 76 hProcess: HANDLE, 77 lpBaseAddress: LPCVOID, 78 lpBuffer: LPVOID, 79 nSize: SIZE_T, 80 lpNumberOfBytesRead: *mut SIZE_T, 81 ) -> BOOL; WriteProcessMemory( hProcess: HANDLE, lpBaseAddress: LPVOID, lpBuffer: LPCVOID, nSize: SIZE_T, lpNumberOfBytesWritten: *mut SIZE_T, ) -> BOOL82 pub fn WriteProcessMemory( 83 hProcess: HANDLE, 84 lpBaseAddress: LPVOID, 85 lpBuffer: LPCVOID, 86 nSize: SIZE_T, 87 lpNumberOfBytesWritten: *mut SIZE_T, 88 ) -> BOOL; CreateFileMappingW( hFile: HANDLE, lpFileMappingAttributes: LPSECURITY_ATTRIBUTES, flProtect: DWORD, dwMaximumSizeHigh: DWORD, dwMaximumSizeLow: DWORD, lpName: LPCWSTR, ) -> HANDLE89 pub fn CreateFileMappingW( 90 hFile: HANDLE, 91 lpFileMappingAttributes: LPSECURITY_ATTRIBUTES, 92 flProtect: DWORD, 93 dwMaximumSizeHigh: DWORD, 94 dwMaximumSizeLow: DWORD, 95 lpName: LPCWSTR, 96 ) -> HANDLE; OpenFileMappingW( dwDesiredAccess: DWORD, bInheritHandle: BOOL, lpName: LPCWSTR, ) -> HANDLE97 pub fn OpenFileMappingW( 98 dwDesiredAccess: DWORD, 99 bInheritHandle: BOOL, 100 lpName: LPCWSTR, 101 ) -> HANDLE; MapViewOfFile( hFileMappingObject: HANDLE, dwDesiredAccess: DWORD, dwFileOffsetHigh: DWORD, dwFileOffsetLow: DWORD, dwNumberOfBytesToMap: SIZE_T, ) -> LPVOID102 pub fn MapViewOfFile( 103 hFileMappingObject: HANDLE, 104 dwDesiredAccess: DWORD, 105 dwFileOffsetHigh: DWORD, 106 dwFileOffsetLow: DWORD, 107 dwNumberOfBytesToMap: SIZE_T, 108 ) -> LPVOID; MapViewOfFileEx( hFileMappingObject: HANDLE, dwDesiredAccess: DWORD, dwFileOffsetHigh: DWORD, dwFileOffsetLow: DWORD, dwNumberOfBytesToMap: SIZE_T, lpBaseAddress: LPVOID, ) -> LPVOID109 pub fn MapViewOfFileEx( 110 hFileMappingObject: HANDLE, 111 dwDesiredAccess: DWORD, 112 dwFileOffsetHigh: DWORD, 113 dwFileOffsetLow: DWORD, 114 dwNumberOfBytesToMap: SIZE_T, 115 lpBaseAddress: LPVOID, 116 ) -> LPVOID; FlushViewOfFile( lpBaseAddress: LPCVOID, dwNumberOfBytesToFlush: SIZE_T, ) -> BOOL117 pub fn FlushViewOfFile( 118 lpBaseAddress: LPCVOID, 119 dwNumberOfBytesToFlush: SIZE_T, 120 ) -> BOOL; UnmapViewOfFile( lpBaseAddress: LPCVOID, ) -> BOOL121 pub fn UnmapViewOfFile( 122 lpBaseAddress: LPCVOID, 123 ) -> BOOL; GetLargePageMinimum() -> SIZE_T124 pub fn GetLargePageMinimum() -> SIZE_T; GetProcessWorkingSetSizeEx( hProcess: HANDLE, lpMinimumWorkingSetSize: PSIZE_T, lpMaximumWorkingSetSize: PSIZE_T, Flags: PDWORD, ) -> BOOL125 pub fn GetProcessWorkingSetSizeEx( 126 hProcess: HANDLE, 127 lpMinimumWorkingSetSize: PSIZE_T, 128 lpMaximumWorkingSetSize: PSIZE_T, 129 Flags: PDWORD, 130 ) -> BOOL; SetProcessWorkingSetSizeEx( hProcess: HANDLE, dwMinimumWorkingSetSize: SIZE_T, dwMaximumWorkingSetSize: SIZE_T, Flags: DWORD, ) -> BOOL131 pub fn SetProcessWorkingSetSizeEx( 132 hProcess: HANDLE, 133 dwMinimumWorkingSetSize: SIZE_T, 134 dwMaximumWorkingSetSize: SIZE_T, 135 Flags: DWORD, 136 ) -> BOOL; VirtualLock( lpAddress: LPVOID, dwSize: SIZE_T, ) -> BOOL137 pub fn VirtualLock( 138 lpAddress: LPVOID, 139 dwSize: SIZE_T, 140 ) -> BOOL; VirtualUnlock( lpAddress: LPVOID, dwSize: SIZE_T, ) -> BOOL141 pub fn VirtualUnlock( 142 lpAddress: LPVOID, 143 dwSize: SIZE_T, 144 ) -> BOOL; GetWriteWatch( dwFlags: DWORD, lpBaseAddress: PVOID, dwRegionSize: SIZE_T, lpAddresses: *mut PVOID, lpdwCount: *mut ULONG_PTR, lpdwGranularity: LPDWORD, ) -> UINT145 pub fn GetWriteWatch( 146 dwFlags: DWORD, 147 lpBaseAddress: PVOID, 148 dwRegionSize: SIZE_T, 149 lpAddresses: *mut PVOID, 150 lpdwCount: *mut ULONG_PTR, 151 lpdwGranularity: LPDWORD, 152 ) -> UINT; ResetWriteWatch( lpBaseAddress: LPVOID, dwRegionSize: SIZE_T, ) -> UINT153 pub fn ResetWriteWatch( 154 lpBaseAddress: LPVOID, 155 dwRegionSize: SIZE_T, 156 ) -> UINT; 157 } 158 ENUM!{enum MEMORY_RESOURCE_NOTIFICATION_TYPE { 159 LowMemoryResourceNotification, 160 HighMemoryResourceNotification, 161 }} 162 extern "system" { CreateMemoryResourceNotification( NotificationType: MEMORY_RESOURCE_NOTIFICATION_TYPE, ) -> HANDLE163 pub fn CreateMemoryResourceNotification( 164 NotificationType: MEMORY_RESOURCE_NOTIFICATION_TYPE, 165 ) -> HANDLE; QueryMemoryResourceNotification( ResourceNotificationHandle: HANDLE, ResourceState: PBOOL, ) -> BOOL166 pub fn QueryMemoryResourceNotification( 167 ResourceNotificationHandle: HANDLE, 168 ResourceState: PBOOL, 169 ) -> BOOL; 170 } 171 pub const FILE_CACHE_MAX_HARD_ENABLE: DWORD = 0x00000001; 172 pub const FILE_CACHE_MAX_HARD_DISABLE: DWORD = 0x00000002; 173 pub const FILE_CACHE_MIN_HARD_ENABLE: DWORD = 0x00000004; 174 pub const FILE_CACHE_MIN_HARD_DISABLE: DWORD = 0x00000008; 175 extern "system" { GetSystemFileCacheSize( lpMinimumFileCacheSize: PSIZE_T, lpMaximumFileCacheSize: PSIZE_T, lpFlags: PDWORD, ) -> BOOL176 pub fn GetSystemFileCacheSize( 177 lpMinimumFileCacheSize: PSIZE_T, 178 lpMaximumFileCacheSize: PSIZE_T, 179 lpFlags: PDWORD, 180 ) -> BOOL; SetSystemFileCacheSize( MinimumFileCacheSize: SIZE_T, MaximumFileCacheSize: SIZE_T, Flags: DWORD, ) -> BOOL181 pub fn SetSystemFileCacheSize( 182 MinimumFileCacheSize: SIZE_T, 183 MaximumFileCacheSize: SIZE_T, 184 Flags: DWORD, 185 ) -> BOOL; CreateFileMappingNumaW( hFile: HANDLE, lpFileMappingAttributes: LPSECURITY_ATTRIBUTES, flProtect: DWORD, dwMaximumSizeHigh: DWORD, dwMaximumSizeLow: DWORD, lpName: LPCWSTR, nndPreferred: DWORD, ) -> HANDLE186 pub fn CreateFileMappingNumaW( 187 hFile: HANDLE, 188 lpFileMappingAttributes: LPSECURITY_ATTRIBUTES, 189 flProtect: DWORD, 190 dwMaximumSizeHigh: DWORD, 191 dwMaximumSizeLow: DWORD, 192 lpName: LPCWSTR, 193 nndPreferred: DWORD, 194 ) -> HANDLE; 195 } 196 STRUCT!{struct WIN32_MEMORY_RANGE_ENTRY { 197 VirtualAddress: PVOID, 198 NumberOfBytes: SIZE_T, 199 }} 200 pub type PWIN32_MEMORY_RANGE_ENTRY = *mut WIN32_MEMORY_RANGE_ENTRY; 201 extern "system" { PrefetchVirtualMemory( hProcess: HANDLE, NumberOfEntries: ULONG_PTR, VirtualAddresses: PWIN32_MEMORY_RANGE_ENTRY, Flags: ULONG, ) -> BOOL202 pub fn PrefetchVirtualMemory( 203 hProcess: HANDLE, 204 NumberOfEntries: ULONG_PTR, 205 VirtualAddresses: PWIN32_MEMORY_RANGE_ENTRY, 206 Flags: ULONG, 207 ) -> BOOL; CreateFileMappingFromApp( hFile: HANDLE, SecurityAttributes: PSECURITY_ATTRIBUTES, PageProtection: ULONG, MaximumSize: ULONG64, Name: PCWSTR, ) -> HANDLE208 pub fn CreateFileMappingFromApp( 209 hFile: HANDLE, 210 SecurityAttributes: PSECURITY_ATTRIBUTES, 211 PageProtection: ULONG, 212 MaximumSize: ULONG64, 213 Name: PCWSTR, 214 ) -> HANDLE; MapViewOfFileFromApp( hFileMappingObject: HANDLE, DesiredAccess: ULONG, FileOffset: ULONG64, NumberOfBytesToMap: SIZE_T, ) -> PVOID215 pub fn MapViewOfFileFromApp( 216 hFileMappingObject: HANDLE, 217 DesiredAccess: ULONG, 218 FileOffset: ULONG64, 219 NumberOfBytesToMap: SIZE_T, 220 ) -> PVOID; UnmapViewOfFileEx( BaseAddress: PVOID, UnmapFlags: ULONG, ) -> BOOL221 pub fn UnmapViewOfFileEx( 222 BaseAddress: PVOID, 223 UnmapFlags: ULONG, 224 ) -> BOOL; AllocateUserPhysicalPages( hProcess: HANDLE, NumberOfPages: PULONG_PTR, PageArray: PULONG_PTR, ) -> BOOL225 pub fn AllocateUserPhysicalPages( 226 hProcess: HANDLE, 227 NumberOfPages: PULONG_PTR, 228 PageArray: PULONG_PTR, 229 ) -> BOOL; FreeUserPhysicalPages( hProcess: HANDLE, NumberOfPages: PULONG_PTR, PageArray: PULONG_PTR, ) -> BOOL230 pub fn FreeUserPhysicalPages( 231 hProcess: HANDLE, 232 NumberOfPages: PULONG_PTR, 233 PageArray: PULONG_PTR, 234 ) -> BOOL; MapUserPhysicalPages( VirtualAddress: PVOID, NumberOfPages: ULONG_PTR, PageArray: PULONG_PTR, ) -> BOOL235 pub fn MapUserPhysicalPages( 236 VirtualAddress: PVOID, 237 NumberOfPages: ULONG_PTR, 238 PageArray: PULONG_PTR, 239 ) -> BOOL; AllocateUserPhysicalPagesNuma( hProcess: HANDLE, NumberOfPages: PULONG_PTR, PageArray: PULONG_PTR, nndPreferred: DWORD, ) -> BOOL240 pub fn AllocateUserPhysicalPagesNuma( 241 hProcess: HANDLE, 242 NumberOfPages: PULONG_PTR, 243 PageArray: PULONG_PTR, 244 nndPreferred: DWORD, 245 ) -> BOOL; VirtualAllocExNuma( hProcess: HANDLE, lpAddress: LPVOID, dwSize: SIZE_T, flAllocationType: DWORD, flProtect: DWORD, nndPreferred: DWORD, ) -> LPVOID246 pub fn VirtualAllocExNuma( 247 hProcess: HANDLE, 248 lpAddress: LPVOID, 249 dwSize: SIZE_T, 250 flAllocationType: DWORD, 251 flProtect: DWORD, 252 nndPreferred: DWORD, 253 ) -> LPVOID; 254 } 255 pub const MEHC_PATROL_SCRUBBER_PRESENT: ULONG = 0x1; 256 extern "system" { GetMemoryErrorHandlingCapabilities( Capabilities: PULONG, ) -> BOOL257 pub fn GetMemoryErrorHandlingCapabilities( 258 Capabilities: PULONG, 259 ) -> BOOL; 260 } 261 FN!{stdcall PBAD_MEMORY_CALLBACK_ROUTINE() -> ()} 262 extern "system" { RegisterBadMemoryNotification( Callback: PBAD_MEMORY_CALLBACK_ROUTINE, ) -> PVOID263 pub fn RegisterBadMemoryNotification( 264 Callback: PBAD_MEMORY_CALLBACK_ROUTINE, 265 ) -> PVOID; UnregisterBadMemoryNotification( RegistrationHandle: PVOID, ) -> BOOL266 pub fn UnregisterBadMemoryNotification( 267 RegistrationHandle: PVOID, 268 ) -> BOOL; 269 } 270 ENUM!{enum OFFER_PRIORITY { 271 VmOfferPriorityVeryLow = 1, 272 VmOfferPriorityLow, 273 VmOfferPriorityBelowNormal, 274 VmOfferPriorityNormal, 275 }} 276 extern "system" { OfferVirtualMemory( VirtualAddress: PVOID, Size: SIZE_T, Priority: OFFER_PRIORITY, ) -> DWORD277 pub fn OfferVirtualMemory( 278 VirtualAddress: PVOID, 279 Size: SIZE_T, 280 Priority: OFFER_PRIORITY, 281 ) -> DWORD; ReclaimVirtualMemory( VirtualAddress: *const c_void, Size: SIZE_T, ) -> DWORD282 pub fn ReclaimVirtualMemory( 283 VirtualAddress: *const c_void, 284 Size: SIZE_T, 285 ) -> DWORD; DiscardVirtualMemory( VirtualAddress: PVOID, Size: SIZE_T, ) -> DWORD286 pub fn DiscardVirtualMemory( 287 VirtualAddress: PVOID, 288 Size: SIZE_T, 289 ) -> DWORD; 290 // TODO: Needs winnt::PCFG_CALL_TARGET_INFO. 291 /* pub fn SetProcessValidCallTargets( 292 hProcess: HANDLE, 293 VirtualAddress: PVOID, 294 RegionSize: SIZE_T, 295 NumberOfOffsets: ULONG, 296 OffsetInformation: PCFG_CALL_TARGET_INFO, 297 ) -> BOOL; */ VirtualAllocFromApp( BaseAddress: PVOID, Size: SIZE_T, AllocationType: ULONG, Protection: ULONG, ) -> PVOID298 pub fn VirtualAllocFromApp( 299 BaseAddress: PVOID, 300 Size: SIZE_T, 301 AllocationType: ULONG, 302 Protection: ULONG, 303 ) -> PVOID; VirtualProtectFromApp( Address: PVOID, Size: SIZE_T, NewProtection: ULONG, OldProtection: PULONG, ) -> BOOL304 pub fn VirtualProtectFromApp( 305 Address: PVOID, 306 Size: SIZE_T, 307 NewProtection: ULONG, 308 OldProtection: PULONG, 309 ) -> BOOL; OpenFileMappingFromApp( DesiredAccess: ULONG, InheritHandle: BOOL, Name: PCWSTR, ) -> HANDLE310 pub fn OpenFileMappingFromApp( 311 DesiredAccess: ULONG, 312 InheritHandle: BOOL, 313 Name: PCWSTR, 314 ) -> HANDLE; 315 } 316 // TODO: Under WINAPI_PARTITION_APP, define CreateFileMappingW, MapViewOfFile, VirtualAlloc, 317 // VirtualProtect, and OpenFileMappingW as wrappers around the *FromApp functions. 318 ENUM!{enum WIN32_MEMORY_INFORMATION_CLASS { 319 MemoryRegionInfo, 320 }} 321 STRUCT!{struct WIN32_MEMORY_REGION_INFORMATION { 322 AllocationBase: PVOID, 323 AllocationProtect: ULONG, 324 u: WIN32_MEMORY_REGION_INFORMATION_u, 325 RegionSize: SIZE_T, 326 CommitSize: SIZE_T, 327 }} 328 UNION!{union WIN32_MEMORY_REGION_INFORMATION_u { 329 [u32; 1], 330 Flags Flags_mut: ULONG, 331 s s_mut: WIN32_MEMORY_REGION_INFORMATION_u_s, 332 }} 333 STRUCT!{struct WIN32_MEMORY_REGION_INFORMATION_u_s { 334 Bitfield: ULONG, 335 }} 336 BITFIELD!{WIN32_MEMORY_REGION_INFORMATION_u_s Bitfield: ULONG [ 337 Private set_Private[0..1], 338 MappedDataFile set_MappedDataFile[1..2], 339 MappedImage set_MappedImage[2..3], 340 MappedPageFile set_MappedPageFile[3..4], 341 MappedPhysical set_MappedPhysical[4..5], 342 DirectMapped set_DirectMapped[5..6], 343 Reserved set_Reserved[6..32], 344 ]} 345 // TODO: Need to resolve issue #323 first. 346 /*extern "system" { 347 pub fn QueryVirtualMemoryInformation( 348 Process: HANDLE, 349 VirtualAddress: *const VOID, 350 MemoryInformationClass: WIN32_MEMORY_INFORMATION_CLASS, 351 MemoryInformation: PVOID, 352 MemoryInformationSize: SIZE_T, 353 ReturnSize: PSIZE_T, 354 ) -> BOOL; 355 pub fn MapViewOfFileNuma2( 356 FileMappingHandle: HANDLE, 357 ProcessHandle: HANDLE, 358 Offset: ULONG64, 359 BaseAddress: PVOID, 360 ViewSize: SIZE_T, 361 AllocationType: ULONG, 362 PageProtection: ULONG, 363 PreferredNode: ULONG, 364 ) -> PVOID; 365 } 366 #[inline] 367 pub unsafe fn MapViewOfFile2( 368 FileMappingHandle: HANDLE, 369 ProcessHandle: HANDLE, 370 Offset: ULONG64, 371 BaseAddress: PVOID, 372 ViewSize: SIZE_T, 373 AllocationType: ULONG, 374 PageProtection: ULONG, 375 ) -> PVOID { 376 MapViewOfFileNuma2(FileMappingHandle, 377 ProcessHandle, 378 Offset, 379 BaseAddress, 380 ViewSize, 381 AllocationType, 382 PageProtection, 383 NUMA_NO_PREFERRED_NODE) 384 }*/ 385 extern "system" { UnmapViewOfFile2( ProcessHandle: HANDLE, BaseAddress: PVOID, UnmapFlags: ULONG, ) -> BOOL386 pub fn UnmapViewOfFile2( 387 ProcessHandle: HANDLE, 388 BaseAddress: PVOID, 389 UnmapFlags: ULONG, 390 ) -> BOOL; 391 } 392