1 #ifndef _STREAM_H 2 #define _STREAM_H 3 4 #include <ntddk.h> 5 #include <windef.h> 6 #include <ks.h> 7 8 #define STREAMAPI __stdcall 9 #define STREAM_SYSTEM_TIME_MASK ((STREAM_SYSTEM_TIME)0x00000001FFFFFFFF) 10 11 typedef enum { 12 DebugLevelFatal = 0, 13 DebugLevelError, 14 DebugLevelWarning, 15 DebugLevelInfo, 16 DebugLevelTrace, 17 DebugLevelVerbose, 18 DebugLevelMaximum 19 } STREAM_DEBUG_LEVEL; 20 21 #if DBG 22 23 #define DebugPrint(x) StreamClassDebugPrint x 24 #define DEBUG_BREAKPOINT() DbgBreakPoint() 25 #define DEBUG_ASSERT(exp) \ 26 if ( !(exp) ) { \ 27 StreamClassDebugAssert( __FILE__, __LINE__, #exp, exp); \ 28 } 29 #else 30 31 #define DebugPrint(x) 32 #define DEBUG_BREAKPOINT() 33 #define DEBUG_ASSERT(exp) 34 35 #endif 36 37 typedef PHYSICAL_ADDRESS STREAM_PHYSICAL_ADDRESS, *PSTREAM_PHYSICAL_ADDRESS; 38 __GNU_EXTENSION typedef unsigned __int64 STREAM_SYSTEM_TIME, *PSTREAM_SYSTEM_TIME; 39 __GNU_EXTENSION typedef unsigned __int64 STREAM_TIMESTAMP, *PSTREAM_TIMESTAMP; 40 41 typedef enum { 42 TIME_GET_STREAM_TIME, 43 TIME_READ_ONBOARD_CLOCK, 44 TIME_SET_ONBOARD_CLOCK 45 } TIME_FUNCTION; 46 47 typedef struct _HW_TIME_CONTEXT { 48 struct _HW_DEVICE_EXTENSION *HwDeviceExtension; 49 struct _HW_STREAM_OBJECT *HwStreamObject; 50 TIME_FUNCTION Function; 51 ULONGLONG Time; 52 ULONGLONG SystemTime; 53 } HW_TIME_CONTEXT, *PHW_TIME_CONTEXT; 54 55 typedef struct _HW_EVENT_DESCRIPTOR { 56 BOOLEAN Enable; 57 PKSEVENT_ENTRY EventEntry; 58 PKSEVENTDATA EventData; 59 __GNU_EXTENSION union { 60 struct _HW_STREAM_OBJECT * StreamObject; 61 struct _HW_DEVICE_EXTENSION *DeviceExtension; 62 }; 63 ULONG EnableEventSetIndex; 64 PVOID HwInstanceExtension; 65 ULONG Reserved; 66 } HW_EVENT_DESCRIPTOR, *PHW_EVENT_DESCRIPTOR; 67 68 struct _HW_STREAM_REQUEST_BLOCK; 69 70 typedef VOID (STREAMAPI *PHW_RECEIVE_STREAM_DATA_SRB) (IN struct _HW_STREAM_REQUEST_BLOCK *SRB); 71 typedef VOID (STREAMAPI *PHW_RECEIVE_STREAM_CONTROL_SRB) (IN struct _HW_STREAM_REQUEST_BLOCK *SRB); 72 typedef NTSTATUS (STREAMAPI *PHW_EVENT_ROUTINE) (IN PHW_EVENT_DESCRIPTOR EventDescriptor); 73 typedef VOID (STREAMAPI *PHW_CLOCK_FUNCTION) (IN PHW_TIME_CONTEXT HwTimeContext); 74 75 typedef struct _HW_CLOCK_OBJECT { 76 PHW_CLOCK_FUNCTION HwClockFunction; 77 ULONG ClockSupportFlags; 78 ULONG Reserved[2]; 79 } HW_CLOCK_OBJECT, *PHW_CLOCK_OBJECT; 80 81 #define CLOCK_SUPPORT_CAN_SET_ONBOARD_CLOCK 0x1 82 #define CLOCK_SUPPORT_CAN_READ_ONBOARD_CLOCK 0x2 83 #define CLOCK_SUPPORT_CAN_RETURN_STREAM_TIME 0x4 84 85 typedef struct _HW_STREAM_OBJECT { 86 ULONG SizeOfThisPacket; 87 ULONG StreamNumber; 88 PVOID HwStreamExtension; 89 PHW_RECEIVE_STREAM_DATA_SRB ReceiveDataPacket; 90 PHW_RECEIVE_STREAM_CONTROL_SRB ReceiveControlPacket; 91 HW_CLOCK_OBJECT HwClockObject; 92 BOOLEAN Dma; 93 BOOLEAN Pio; 94 PVOID HwDeviceExtension; 95 ULONG StreamHeaderMediaSpecific; 96 ULONG StreamHeaderWorkspace; 97 BOOLEAN Allocator; 98 PHW_EVENT_ROUTINE HwEventRoutine; 99 ULONG Reserved[2]; 100 } HW_STREAM_OBJECT, *PHW_STREAM_OBJECT; 101 102 typedef struct _HW_STREAM_HEADER { 103 ULONG NumberOfStreams; 104 ULONG SizeOfHwStreamInformation; 105 ULONG NumDevPropArrayEntries; 106 PKSPROPERTY_SET DevicePropertiesArray; 107 ULONG NumDevEventArrayEntries; 108 PKSEVENT_SET DeviceEventsArray; 109 PKSTOPOLOGY Topology; 110 PHW_EVENT_ROUTINE DeviceEventRoutine; 111 LONG NumDevMethodArrayEntries; 112 PKSMETHOD_SET DeviceMethodsArray; 113 } HW_STREAM_HEADER, *PHW_STREAM_HEADER; 114 115 typedef struct _HW_STREAM_INFORMATION { 116 ULONG NumberOfPossibleInstances; 117 KSPIN_DATAFLOW DataFlow; 118 BOOLEAN DataAccessible; 119 ULONG NumberOfFormatArrayEntries; 120 _Field_size_(NumberOfFormatArrayEntries) PKSDATAFORMAT* StreamFormatsArray; 121 PVOID ClassReserved[4]; 122 ULONG NumStreamPropArrayEntries; 123 _Field_size_(NumStreamPropArrayEntries) PKSPROPERTY_SET StreamPropertiesArray; 124 ULONG NumStreamEventArrayEntries; 125 _Field_size_(NumStreamEventArrayEntries) PKSEVENT_SET StreamEventsArray; 126 GUID* Category; 127 GUID* Name; 128 ULONG MediumsCount; 129 _Field_size_(MediumsCount) const KSPIN_MEDIUM* Mediums; 130 BOOLEAN BridgeStream; 131 ULONG Reserved[2]; 132 } HW_STREAM_INFORMATION, *PHW_STREAM_INFORMATION; 133 134 typedef struct _HW_STREAM_DESCRIPTOR { 135 HW_STREAM_HEADER StreamHeader; 136 HW_STREAM_INFORMATION StreamInfo; 137 } HW_STREAM_DESCRIPTOR, *PHW_STREAM_DESCRIPTOR; 138 139 typedef struct _STREAM_TIME_REFERENCE { 140 STREAM_TIMESTAMP CurrentOnboardClockValue; 141 LARGE_INTEGER OnboardClockFrequency; 142 LARGE_INTEGER CurrentSystemTime; 143 ULONG Reserved[2]; 144 } STREAM_TIME_REFERENCE, *PSTREAM_TIME_REFERENCE; 145 146 typedef struct _STREAM_DATA_INTERSECT_INFO { 147 ULONG StreamNumber; 148 PKSDATARANGE DataRange; 149 _Field_size_bytes_(SizeOfDataFormatBuffer) PVOID DataFormatBuffer; 150 ULONG SizeOfDataFormatBuffer; 151 } STREAM_DATA_INTERSECT_INFO, *PSTREAM_DATA_INTERSECT_INFO; 152 153 typedef struct _STREAM_PROPERTY_DESCRIPTOR { 154 PKSPROPERTY Property; 155 ULONG PropertySetID; 156 PVOID PropertyInfo; 157 ULONG PropertyInputSize; 158 ULONG PropertyOutputSize; 159 } STREAM_PROPERTY_DESCRIPTOR, *PSTREAM_PROPERTY_DESCRIPTOR; 160 161 typedef struct _STREAM_METHOD_DESCRIPTOR { 162 ULONG MethodSetID; 163 PKSMETHOD Method; 164 PVOID MethodInfo; 165 LONG MethodInputSize; 166 LONG MethodOutputSize; 167 } STREAM_METHOD_DESCRIPTOR, *PSTREAM_METHOD_DESCRIPTOR; 168 169 #define STREAM_REQUEST_BLOCK_SIZE sizeof(STREAM_REQUEST_BLOCK) 170 171 typedef enum _SRB_COMMAND { 172 SRB_READ_DATA, 173 SRB_WRITE_DATA, 174 SRB_GET_STREAM_STATE, 175 SRB_SET_STREAM_STATE, 176 SRB_SET_STREAM_PROPERTY, 177 SRB_GET_STREAM_PROPERTY, 178 SRB_OPEN_MASTER_CLOCK, 179 180 SRB_INDICATE_MASTER_CLOCK, 181 SRB_UNKNOWN_STREAM_COMMAND, 182 SRB_SET_STREAM_RATE, 183 SRB_PROPOSE_DATA_FORMAT, 184 SRB_CLOSE_MASTER_CLOCK, 185 SRB_PROPOSE_STREAM_RATE, 186 SRB_SET_DATA_FORMAT, 187 SRB_GET_DATA_FORMAT, 188 SRB_BEGIN_FLUSH, 189 SRB_END_FLUSH, 190 191 SRB_GET_STREAM_INFO = 0x100, 192 SRB_OPEN_STREAM, 193 SRB_CLOSE_STREAM, 194 SRB_OPEN_DEVICE_INSTANCE, 195 SRB_CLOSE_DEVICE_INSTANCE, 196 SRB_GET_DEVICE_PROPERTY, 197 SRB_SET_DEVICE_PROPERTY, 198 SRB_INITIALIZE_DEVICE, 199 SRB_CHANGE_POWER_STATE, 200 SRB_UNINITIALIZE_DEVICE, 201 SRB_UNKNOWN_DEVICE_COMMAND, 202 SRB_PAGING_OUT_DRIVER, 203 SRB_GET_DATA_INTERSECTION, 204 SRB_INITIALIZATION_COMPLETE, 205 SRB_SURPRISE_REMOVAL 206 207 #if (NTDDI_VERSION >= NTDDI_WINXP) 208 ,SRB_DEVICE_METHOD 209 ,SRB_STREAM_METHOD 210 #if ( (NTDDI_VERSION >= NTDDI_WINXPSP2) && (NTDDI_VERSION < NTDDI_WS03) ) || (NTDDI_VERSION >= NTDDI_WS03SP1) 211 ,SRB_NOTIFY_IDLE_STATE 212 #endif 213 #endif 214 } SRB_COMMAND; 215 216 typedef struct { 217 PHYSICAL_ADDRESS PhysicalAddress; 218 ULONG Length; 219 } KSSCATTER_GATHER, *PKSSCATTER_GATHER; 220 221 222 typedef struct _HW_STREAM_REQUEST_BLOCK { 223 ULONG SizeOfThisPacket; 224 SRB_COMMAND Command; 225 NTSTATUS Status; 226 PHW_STREAM_OBJECT StreamObject; 227 PVOID HwDeviceExtension; 228 PVOID SRBExtension; 229 230 union _CommandData { 231 _Field_size_(_Inexpressible_(NumberOfBuffers)) PKSSTREAM_HEADER DataBufferArray; 232 PHW_STREAM_DESCRIPTOR StreamBuffer; 233 KSSTATE StreamState; 234 PSTREAM_TIME_REFERENCE TimeReference; 235 PSTREAM_PROPERTY_DESCRIPTOR PropertyInfo; 236 PKSDATAFORMAT OpenFormat; 237 struct _PORT_CONFIGURATION_INFORMATION *ConfigInfo; 238 HANDLE MasterClockHandle; 239 DEVICE_POWER_STATE DeviceState; 240 PSTREAM_DATA_INTERSECT_INFO IntersectInfo; 241 242 #if (NTDDI_VERSION >= NTDDI_WINXP) 243 PVOID MethodInfo; 244 LONG FilterTypeIndex; 245 #if ( (NTDDI_VERSION >= NTDDI_WINXPSP2) && (NTDDI_VERSION < NTDDI_WS03) ) || (NTDDI_VERSION >= NTDDI_WS03SP1) 246 BOOLEAN Idle; 247 #endif 248 #endif 249 } CommandData; 250 251 ULONG NumberOfBuffers; 252 ULONG TimeoutCounter; 253 ULONG TimeoutOriginal; 254 struct _HW_STREAM_REQUEST_BLOCK *NextSRB; 255 256 PIRP Irp; 257 ULONG Flags; 258 PVOID HwInstanceExtension; 259 260 __GNU_EXTENSION union { 261 ULONG NumberOfBytesToTransfer; 262 ULONG ActualBytesTransferred; 263 }; 264 265 _Field_size_(NumberOfScatterGatherElements) PKSSCATTER_GATHER ScatterGatherBuffer; 266 ULONG NumberOfPhysicalPages; 267 ULONG NumberOfScatterGatherElements; 268 ULONG Reserved[1]; 269 } HW_STREAM_REQUEST_BLOCK, *PHW_STREAM_REQUEST_BLOCK; 270 271 #define SRB_HW_FLAGS_DATA_TRANSFER 0x01 272 #define SRB_HW_FLAGS_STREAM_REQUEST 0x2 273 274 typedef enum { 275 PerRequestExtension, 276 DmaBuffer, 277 SRBDataBuffer 278 } STREAM_BUFFER_TYPE; 279 280 typedef struct _ACCESS_RANGE { 281 _Field_size_bytes_(RangeLength) STREAM_PHYSICAL_ADDRESS RangeStart; 282 ULONG RangeLength; 283 BOOLEAN RangeInMemory; 284 ULONG Reserved; 285 } ACCESS_RANGE, *PACCESS_RANGE; 286 287 typedef struct _PORT_CONFIGURATION_INFORMATION { 288 ULONG SizeOfThisPacket; 289 PVOID HwDeviceExtension; 290 PDEVICE_OBJECT ClassDeviceObject; 291 PDEVICE_OBJECT PhysicalDeviceObject; 292 ULONG SystemIoBusNumber; 293 INTERFACE_TYPE AdapterInterfaceType; 294 ULONG BusInterruptLevel; 295 ULONG BusInterruptVector; 296 KINTERRUPT_MODE InterruptMode; 297 ULONG DmaChannel; 298 ULONG NumberOfAccessRanges; 299 _Field_size_(NumberOfAccessRanges) PACCESS_RANGE AccessRanges; 300 ULONG StreamDescriptorSize; 301 PIRP Irp; 302 PKINTERRUPT InterruptObject; 303 PADAPTER_OBJECT DmaAdapterObject; 304 PDEVICE_OBJECT RealPhysicalDeviceObject; 305 ULONG Reserved[1]; 306 } PORT_CONFIGURATION_INFORMATION, *PPORT_CONFIGURATION_INFORMATION; 307 308 typedef VOID (STREAMAPI *PHW_RECEIVE_DEVICE_SRB) (IN PHW_STREAM_REQUEST_BLOCK SRB); 309 typedef VOID (STREAMAPI *PHW_CANCEL_SRB) (IN PHW_STREAM_REQUEST_BLOCK SRB); 310 typedef VOID (STREAMAPI *PHW_REQUEST_TIMEOUT_HANDLER) (IN PHW_STREAM_REQUEST_BLOCK SRB); 311 typedef BOOLEAN (STREAMAPI *PHW_INTERRUPT) (IN PVOID DeviceExtension); 312 typedef VOID (STREAMAPI *PHW_TIMER_ROUTINE) (IN PVOID Context); 313 typedef VOID (STREAMAPI *PHW_PRIORITY_ROUTINE) (IN PVOID Context); 314 typedef VOID (STREAMAPI *PHW_QUERY_CLOCK_ROUTINE) (IN PHW_TIME_CONTEXT TimeContext); 315 typedef BOOLEAN (STREAMAPI *PHW_RESET_ADAPTER) (IN PVOID DeviceExtension); 316 317 typedef enum _STREAM_MINIDRIVER_STREAM_NOTIFICATION_TYPE { 318 ReadyForNextStreamDataRequest, 319 ReadyForNextStreamControlRequest, 320 HardwareStarved, 321 StreamRequestComplete, 322 SignalMultipleStreamEvents, 323 SignalStreamEvent, 324 DeleteStreamEvent, 325 StreamNotificationMaximum 326 } STREAM_MINIDRIVER_STREAM_NOTIFICATION_TYPE, *PSTREAM_MINIDRIVER_STREAM_NOTIFICATION_TYPE; 327 328 typedef enum _STREAM_MINIDRIVER_DEVICE_NOTIFICATION_TYPE { 329 ReadyForNextDeviceRequest, 330 DeviceRequestComplete, 331 SignalMultipleDeviceEvents, 332 SignalDeviceEvent, 333 DeleteDeviceEvent, 334 #if (NTDDI_VERSION >= NTDDI_WINXP) 335 SignalMultipleDeviceInstanceEvents, 336 #endif 337 DeviceNotificationMaximum 338 } STREAM_MINIDRIVER_DEVICE_NOTIFICATION_TYPE, *PSTREAM_MINIDRIVER_DEVICE_NOTIFICATION_TYPE; 339 340 #define STREAM_CLASS_VERSION_20 0x0200 341 342 typedef struct _HW_INITIALIZATION_DATA { 343 #if (NTDDI_VERSION >= NTDDI_WINXP) 344 __GNU_EXTENSION union { 345 ULONG HwInitializationDataSize; 346 __GNU_EXTENSION struct { 347 USHORT SizeOfThisPacket; 348 USHORT StreamClassVersion; 349 }; 350 }; 351 #else 352 ULONG HwInitializationDataSize; 353 #endif /* NTDDI_VERSION >= NTDDI_WINXP */ 354 355 PHW_INTERRUPT HwInterrupt; 356 PHW_RECEIVE_DEVICE_SRB HwReceivePacket; 357 PHW_CANCEL_SRB HwCancelPacket; 358 PHW_REQUEST_TIMEOUT_HANDLER HwRequestTimeoutHandler; 359 ULONG DeviceExtensionSize; 360 ULONG PerRequestExtensionSize; 361 ULONG PerStreamExtensionSize; 362 ULONG FilterInstanceExtensionSize; 363 BOOLEAN BusMasterDMA; 364 BOOLEAN Dma24BitAddresses; 365 ULONG BufferAlignment; 366 BOOLEAN TurnOffSynchronization; 367 ULONG DmaBufferSize; 368 369 #if (NTDDI_VERSION >= NTDDI_WINXP) 370 ULONG NumNameExtensions; 371 _Field_size_(NumNameExtensions) PWCHAR *NameExtensionArray; 372 #else 373 ULONG Reserved[2]; 374 #endif 375 } HW_INITIALIZATION_DATA, *PHW_INITIALIZATION_DATA; 376 377 typedef enum _STREAM_PRIORITY { 378 High, 379 Dispatch, 380 Low, 381 LowToHigh 382 } STREAM_PRIORITY, *PSTREAM_PRIORITY; 383 384 385 VOID 386 StreamClassAbortOutstandingRequests( 387 _In_ PVOID HwDeviceExtension, 388 _In_opt_ PHW_STREAM_OBJECT HwStreamObject, 389 _In_ NTSTATUS Status); 390 391 VOID 392 STREAMAPI 393 StreamClassCallAtNewPriority( 394 _In_opt_ PHW_STREAM_OBJECT StreamObject, 395 _In_ PVOID HwDeviceExtension, 396 _In_ STREAM_PRIORITY Priority, 397 _In_ PHW_PRIORITY_ROUTINE PriorityRoutine, 398 _In_ PVOID Context); 399 400 VOID 401 STREAMAPI 402 StreamClassCompleteRequestAndMarkQueueReady( 403 _In_ PHW_STREAM_REQUEST_BLOCK Srb); 404 405 __analysis_noreturn 406 VOID 407 STREAMAPI 408 StreamClassDebugAssert( 409 _In_ PCHAR File, 410 _In_ ULONG Line, 411 _In_ PCHAR AssertText, 412 _In_ ULONG AssertValue); 413 414 VOID 415 __cdecl 416 StreamClassDebugPrint( 417 _In_ STREAM_DEBUG_LEVEL DebugPrintLevel, 418 _In_ PCCHAR DebugMessage, 419 ...); 420 421 VOID 422 __cdecl 423 StreamClassDeviceNotification( 424 IN STREAM_MINIDRIVER_DEVICE_NOTIFICATION_TYPE NotificationType, 425 IN PVOID HwDeviceExtension, 426 IN PHW_STREAM_REQUEST_BLOCK pSrb, 427 IN PKSEVENT_ENTRY EventEntry, 428 IN GUID *EventSet, 429 IN ULONG EventId); 430 431 VOID 432 STREAMAPI 433 StreamClassFilterReenumerateStreams( 434 _In_ PVOID HwInstanceExtension, 435 _In_ ULONG StreamDescriptorSize); 436 437 PVOID 438 STREAMAPI 439 StreamClassGetDmaBuffer( 440 _In_ PVOID HwDeviceExtension); 441 442 443 PKSEVENT_ENTRY 444 StreamClassGetNextEvent( 445 _In_opt_ PVOID HwInstanceExtension_OR_HwDeviceExtension, 446 _In_opt_ PHW_STREAM_OBJECT HwStreamObject, 447 _In_opt_ GUID *EventGuid, 448 _In_ ULONG EventItem, 449 _In_opt_ PKSEVENT_ENTRY CurrentEvent); 450 451 STREAM_PHYSICAL_ADDRESS 452 STREAMAPI 453 StreamClassGetPhysicalAddress( 454 _In_ PVOID HwDeviceExtension, 455 _In_opt_ PHW_STREAM_REQUEST_BLOCK HwSRB, 456 _In_ PVOID VirtualAddress, 457 _In_ STREAM_BUFFER_TYPE Type, 458 _Out_ ULONG *Length); 459 460 VOID 461 StreamClassQueryMasterClock( 462 _In_ PHW_STREAM_OBJECT HwStreamObject, 463 _In_ HANDLE MasterClockHandle, 464 _In_ TIME_FUNCTION TimeFunction, 465 _In_ PHW_QUERY_CLOCK_ROUTINE ClockCallbackRoutine); 466 467 _IRQL_requires_max_(DISPATCH_LEVEL) 468 VOID 469 STREAMAPI 470 StreamClassQueryMasterClockSync( 471 _In_ HANDLE MasterClockHandle, 472 _Inout_ PHW_TIME_CONTEXT TimeContext); 473 474 _IRQL_requires_max_(PASSIVE_LEVEL) 475 BOOLEAN 476 STREAMAPI 477 StreamClassReadWriteConfig( 478 _In_ PVOID HwDeviceExtension, 479 _In_ BOOLEAN Read, 480 _Inout_updates_bytes_(Length) PVOID Buffer, 481 _In_ ULONG Offset, 482 _In_ ULONG Length); 483 484 VOID 485 STREAMAPI 486 StreamClassReenumerateStreams( 487 _In_ PVOID HwDeviceExtension, 488 _In_ ULONG StreamDescriptorSize); 489 490 _IRQL_requires_max_(PASSIVE_LEVEL) 491 NTSTATUS 492 STREAMAPI 493 StreamClassRegisterAdapter( 494 _In_ PVOID Argument1, 495 _In_ PVOID Argument2, 496 _In_ PHW_INITIALIZATION_DATA HwInitializationData); 497 498 #define StreamClassRegisterMinidriver StreamClassRegisterAdapter 499 500 _IRQL_requires_max_(APC_LEVEL) 501 NTSTATUS 502 StreamClassRegisterFilterWithNoKSPins( 503 _In_ PDEVICE_OBJECT DeviceObject, 504 _In_ const GUID *InterfaceClassGUID, 505 _In_ ULONG PinCount, 506 _In_reads_(PinCount) BOOL *PinDirection, 507 _In_reads_(PinCount) KSPIN_MEDIUM *MediumList, 508 _In_reads_opt_(PinCount) GUID *CategoryList); 509 510 VOID 511 STREAMAPI 512 StreamClassScheduleTimer( 513 _In_opt_ PHW_STREAM_OBJECT StreamObject, 514 _In_ PVOID HwDeviceExtension, 515 _In_ ULONG NumberOfMicroseconds, 516 _In_ PHW_TIMER_ROUTINE TimerRoutine, 517 _In_ PVOID Context); 518 519 VOID 520 __cdecl 521 StreamClassStreamNotification( 522 _In_ STREAM_MINIDRIVER_STREAM_NOTIFICATION_TYPE NotificationType, 523 _In_ PHW_STREAM_OBJECT StreamObject, 524 ...); 525 526 #endif /* _STREAM_H */ 527