Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

768 lines
22 KiB

  1. //==========================================================================;
  2. //
  3. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. // PURPOSE.
  7. //
  8. // Copyright (c) 1997 Microsoft Corporation. All Rights Reserved.
  9. //
  10. //
  11. // History:
  12. // 22-Aug-97 TKB Created Initial Interface Version
  13. //
  14. //==========================================================================;
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <windows.h>
  18. #include <setupapi.h>
  19. #include <spapip.h>
  20. #include <string.h>
  21. #include <devioctl.h>
  22. #include <ks.h>
  23. #include <iks.h>
  24. //////////////////////////////////////////////////////////////
  25. // IKSDriver::
  26. //////////////////////////////////////////////////////////////
  27. IKSDriver::IKSDriver(LPCGUID lpCategory, LPCSTR lpszFriendlyName)
  28. {
  29. if ( lpszFriendlyName && *lpszFriendlyName )
  30. {
  31. if ( m_lpszDriver = GetSymbolicName( lpCategory, lpszFriendlyName ) )
  32. {
  33. if ( OpenDriver( GENERIC_READ | GENERIC_WRITE, FILE_FLAG_OVERLAPPED ) )
  34. {
  35. }
  36. else
  37. {
  38. // Throw a open failure exception
  39. }
  40. }
  41. }
  42. else
  43. {
  44. // Throw a bad parameter exception.
  45. }
  46. }
  47. IKSDriver::~IKSDriver()
  48. {
  49. if ( m_lpszDriver )
  50. {
  51. delete m_lpszDriver;
  52. m_lpszDriver = NULL;
  53. if ( m_hKSDriver )
  54. {
  55. if ( CloseDriver() )
  56. {
  57. }
  58. else
  59. {
  60. // Throw a close failure exception
  61. }
  62. }
  63. }
  64. }
  65. BOOL
  66. IKSDriver::Ioctl(ULONG dwControlCode, LPBYTE pIn, ULONG nIn,
  67. LPBYTE pOut, ULONG nOut, ULONG *nReturned, LPOVERLAPPED lpOS )
  68. {
  69. BOOL bStatus = FALSE;
  70. if ( IsValid() )
  71. {
  72. bStatus = DeviceIoControl( m_hKSDriver, dwControlCode, pIn, nIn,
  73. pOut, nOut, nReturned, lpOS );
  74. }
  75. else
  76. {
  77. // Throw an invalid object exception
  78. }
  79. return bStatus;
  80. }
  81. #if DBG && 0
  82. #define TRACE printf
  83. #else
  84. #define TRACE
  85. #endif
  86. LPWSTR
  87. IKSDriver::GetSymbolicName(LPCGUID lpCategory, LPCSTR szRequestedDevice )
  88. {
  89. int index = 0;
  90. LPWSTR lpszSymbolicName = NULL;
  91. HDEVINFO hDevInfo = SetupDiGetClassDevs( const_cast<GUID*>(lpCategory), NULL, NULL,
  92. DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
  93. if (hDevInfo != INVALID_HANDLE_VALUE)
  94. {
  95. PSP_DEVICE_INTERFACE_DETAIL_DATA_W pDeviceDetails;
  96. SP_DEVICE_INTERFACE_DATA DeviceData = {sizeof(DeviceData)};
  97. BYTE Storage[sizeof(*pDeviceDetails) + MAX_PATH * sizeof(WCHAR)];
  98. SP_DEVINFO_DATA DeviceInfoData = {sizeof(DeviceInfoData)};
  99. CHAR szDeviceDesc[MAX_PATH];
  100. WCHAR wszSymbolicPath[MAX_PATH];
  101. pDeviceDetails = reinterpret_cast<PSP_DEVICE_INTERFACE_DETAIL_DATA_W>(Storage);
  102. pDeviceDetails->cbSize = sizeof(*pDeviceDetails);
  103. TRACE("Begin SetupDiEnumDeviceInterfaces\n");
  104. while ( SetupDiEnumDeviceInterfaces(hDevInfo, NULL, const_cast<GUID*>(lpCategory), index++, &DeviceData ) )
  105. {
  106. TRACE("A) SetupDiGetDeviceInterfaceDetail\n");
  107. if ( SetupDiGetDeviceInterfaceDetailW(hDevInfo, &DeviceData, pDeviceDetails, sizeof(Storage), NULL, &DeviceInfoData) )
  108. {
  109. SP_INTERFACE_TO_DEVICE_PARAMS_W Translate;
  110. // Save off the original device path so it can be returned if we match the name
  111. wcscpy( wszSymbolicPath, pDeviceDetails->DevicePath);
  112. ZeroMemory(&Translate,sizeof(Translate));
  113. Translate.ClassInstallHeader.cbSize = sizeof(Translate.ClassInstallHeader);
  114. Translate.ClassInstallHeader.InstallFunction = DIF_INTERFACE_TO_DEVICE;
  115. Translate.Interface = pDeviceDetails->DevicePath;
  116. TRACE("B) SetupDiSetClassInstallParams\n");
  117. if ( SetupDiSetClassInstallParamsW( hDevInfo,
  118. &DeviceInfoData,
  119. (PSP_CLASSINSTALL_HEADER)&Translate,
  120. sizeof(Translate)) )
  121. {
  122. TRACE("C) SetupDiCallClassInstaller\n");
  123. if ( SetupDiCallClassInstaller(DIF_INTERFACE_TO_DEVICE,
  124. hDevInfo,
  125. &DeviceInfoData) )
  126. {
  127. // it was translated find out what to
  128. TRACE("D) SetupDiGetClassInstallParams\n");
  129. if( SetupDiGetClassInstallParamsW(hDevInfo,
  130. &DeviceInfoData,
  131. (PSP_CLASSINSTALL_HEADER)&Translate,
  132. sizeof(Translate),
  133. NULL))
  134. {
  135. TRACE("E) SetupDiOpenDeviceInfo\n");
  136. if( SetupDiOpenDeviceInfoW(hDevInfo,
  137. Translate.DeviceId,
  138. NULL,
  139. 0,
  140. &DeviceInfoData))
  141. {
  142. TRACE("F) SetupDiGetDeviceRegistryProperty\n");
  143. if ( SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, NULL, (LPBYTE)&szDeviceDesc,
  144. sizeof(szDeviceDesc), NULL ) )
  145. {
  146. TRACE("G) Name=%s\n",szDeviceDesc);
  147. if ( *szRequestedDevice && *szDeviceDesc
  148. && strncmp( szRequestedDevice, szDeviceDesc,
  149. min( strlen(szRequestedDevice), strlen(szDeviceDesc) ) ) == 0 )
  150. {
  151. TRACE("H) Matched Sympath=%S\n", wszSymbolicPath);
  152. lpszSymbolicName = wcscpy( new WCHAR[wcslen(wszSymbolicPath)+1],
  153. wszSymbolicPath );
  154. break;
  155. }
  156. }
  157. else
  158. {
  159. TRACE("SetupDiGetDeviceRegistryProperty()=0x%lx\n", GetLastError());
  160. }
  161. }
  162. else
  163. {
  164. TRACE("SetupDiOpenDeviceInfo()=0x%lx\n", GetLastError());
  165. }
  166. }
  167. else
  168. {
  169. TRACE("SetupDiGetClassInstallParams()=0x%lx\n", GetLastError());
  170. }
  171. }
  172. else
  173. {
  174. TRACE("SetupDiCallClassInstaller()=0x%lx\n", GetLastError());
  175. }
  176. }
  177. else
  178. {
  179. TRACE("I) SetupDiGetDeviceRegistryProperty\n");
  180. if ( SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DEVICEDESC, NULL, (LPBYTE)&szDeviceDesc,
  181. sizeof(szDeviceDesc), NULL ) )
  182. {
  183. TRACE("J) Name=%s\n",szDeviceDesc);
  184. if ( *szRequestedDevice && *szDeviceDesc
  185. && strncmp( szRequestedDevice, szDeviceDesc,
  186. min( strlen(szRequestedDevice), strlen(szDeviceDesc) ) ) == 0 )
  187. {
  188. TRACE("K) Matched Sympath=%S\n",wszSymbolicPath);
  189. lpszSymbolicName = wcscpy( new WCHAR[wcslen(wszSymbolicPath)+1], wszSymbolicPath );
  190. break;
  191. }
  192. }
  193. else
  194. {
  195. TRACE("SetupDiCallClassInstaller()=0x%lx\n", GetLastError());
  196. }
  197. }
  198. }
  199. }
  200. }
  201. TRACE("End SetupDiEnumDeviceInterfaces\n");
  202. return lpszSymbolicName;
  203. }
  204. BOOL
  205. IKSDriver::OpenDriver(DWORD dwAccess, DWORD dwFlags)
  206. {
  207. BOOL bStatus = FALSE;
  208. SECURITY_ATTRIBUTES SecurityAttributes;
  209. SecurityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  210. SecurityAttributes.bInheritHandle = TRUE;
  211. SecurityAttributes.lpSecurityDescriptor = NULL;
  212. m_hKSDriver = CreateFileW(
  213. m_lpszDriver,
  214. dwAccess,
  215. FILE_SHARE_READ | FILE_SHARE_WRITE,
  216. &SecurityAttributes,
  217. OPEN_EXISTING,
  218. dwFlags,
  219. NULL
  220. );
  221. if ( m_hKSDriver != (HANDLE)-1 )
  222. {
  223. bStatus = TRUE;
  224. }
  225. else
  226. {
  227. m_hKSDriver = NULL;
  228. }
  229. return bStatus;
  230. }
  231. BOOL
  232. IKSDriver::CloseDriver()
  233. {
  234. BOOL bStatus = CloseHandle(m_hKSDriver);
  235. m_hKSDriver = NULL;
  236. return bStatus;
  237. }
  238. //////////////////////////////////////////////////////////////
  239. // IKSPin::
  240. //////////////////////////////////////////////////////////////
  241. IKSPin::IKSPin(IKSDriver &driver,
  242. int nPin,
  243. PKSDATARANGE pKSDataRange )
  244. {
  245. m_bRunning = FALSE;
  246. m_IKSDriver = &driver;
  247. m_nPin = nPin;
  248. if ( pKSDataRange )
  249. {
  250. if ( OpenPin( pKSDataRange ) )
  251. {
  252. if ( Run() )
  253. {
  254. // We are good to go!
  255. }
  256. else
  257. {
  258. // Throw an run failure exception
  259. }
  260. }
  261. else
  262. {
  263. // Throw an open failure exception
  264. }
  265. }
  266. else
  267. {
  268. // Throw a bad parameter exception.
  269. }
  270. }
  271. IKSPin::~IKSPin()
  272. {
  273. if ( m_nPin )
  274. {
  275. m_nPin = -1;
  276. if ( m_hKSPin )
  277. {
  278. if ( m_bRunning )
  279. {
  280. if ( Stop() )
  281. {
  282. }
  283. else
  284. {
  285. // Throw a stop failure exception
  286. }
  287. }
  288. if ( ClosePin() )
  289. {
  290. // We are all destructed.
  291. }
  292. else
  293. {
  294. // Throw a close failure exception
  295. }
  296. }
  297. }
  298. }
  299. BOOL
  300. IKSPin::Ioctl(ULONG dwControlCode, void *pInput, ULONG nInput,
  301. void *pOutput, ULONG nOutput,
  302. ULONG *nReturned, LPOVERLAPPED lpOS )
  303. {
  304. BOOL bStatus = FALSE;
  305. if ( IsValid() )
  306. {
  307. bStatus = DeviceIoControl( m_hKSPin, dwControlCode, pInput, nInput,
  308. pOutput, nOutput, nReturned, lpOS );
  309. if ( !bStatus )
  310. {
  311. int nError = GetLastError();
  312. if ( nError == ERROR_IO_PENDING )
  313. bStatus = TRUE;
  314. }
  315. }
  316. else
  317. {
  318. }
  319. return bStatus;
  320. }
  321. int
  322. IKSPin::ReadData( LPBYTE lpBuffer, int nBytes, DWORD *lpcbReturned, LPOVERLAPPED lpOS )
  323. {
  324. int nStatus = -1;
  325. static int counter = 0;
  326. if ( lpBuffer && IsValid() )
  327. {
  328. if ( lpOS )
  329. {
  330. DWORD dwReturnedHeaderSize; // Ignored in this case.
  331. KSSTREAM_HEADER *lpStreamHeader =
  332. (KSSTREAM_HEADER *)GlobalAlloc(GMEM_FIXED, sizeof(KSSTREAM_HEADER) );
  333. if ( lpStreamHeader )
  334. {
  335. // Cache away the stream header structure so that we can get the "DataUsed" member later
  336. lpOS->Offset = (DWORD)lpStreamHeader;
  337. RtlZeroMemory(lpStreamHeader, sizeof(*lpStreamHeader) );
  338. lpStreamHeader->PresentationTime.Numerator = 1;
  339. lpStreamHeader->PresentationTime.Denominator = 1;
  340. lpStreamHeader->Size = sizeof(*lpStreamHeader);
  341. lpStreamHeader->Data = lpBuffer;
  342. lpStreamHeader->FrameExtent = nBytes;
  343. if ( Ioctl( IOCTL_KS_READ_STREAM,
  344. NULL, 0,
  345. (LPBYTE)lpStreamHeader, sizeof(*lpStreamHeader),
  346. &dwReturnedHeaderSize, lpOS ) )
  347. {
  348. nStatus = 0;
  349. }
  350. }
  351. *lpcbReturned = 0;
  352. }
  353. else
  354. {
  355. #ifdef SUPPORT_NON_OVERLAPPED_READS
  356. DWORD dwReturnedHeaderSize;
  357. KSSTREAM_HEADER StreamHeader;
  358. RtlZeroMemory(&StreamHeader, sizeof(StreamHeader) );
  359. StreamHeader.PresentationTime.Numerator = 1;
  360. StreamHeader.PresentationTime.Denominator = 1;
  361. StreamHeader.Size = sizeof(StreamHeader);
  362. StreamHeader.Data = lpBuffer;
  363. StreamHeader.FrameExtent = nBytes;
  364. if ( Ioctl( IOCTL_KS_READ_STREAM,
  365. NULL, 0,
  366. (LPBYTE)&StreamHeader, sizeof(StreamHeader),
  367. &dwReturnedHeaderSize, lpOS )
  368. && dwReturnedHeaderSize == sizeof(StreamHeader) )
  369. {
  370. *lpcbReturned = StreamHeader.DataUsed;
  371. nStatus = 0;
  372. }
  373. #endif
  374. }
  375. }
  376. return nStatus;
  377. }
  378. int
  379. IKSPin::GetOverlappedResult( LPOVERLAPPED lpOS, LPDWORD lpdwTransferred , BOOL bWait )
  380. {
  381. int nStatus = -1;
  382. if ( IsValid() && lpOS && lpOS->hEvent )
  383. {
  384. // Get the cached STREAM_HEADER memory so we can get the actual data transferred.
  385. KSSTREAM_HEADER *lpStreamHeader = (KSSTREAM_HEADER *)lpOS->Offset;
  386. if ( lpdwTransferred )
  387. *lpdwTransferred = 0;
  388. if ( lpStreamHeader && WaitForSingleObject( lpOS->hEvent, 0 ) == WAIT_OBJECT_0 )
  389. {
  390. DWORD dwKSBuffer = 0;
  391. if ( ::GetOverlappedResult( m_hKSPin, lpOS, &dwKSBuffer, bWait )
  392. && dwKSBuffer == sizeof(KSSTREAM_HEADER) && lpOS->InternalHigh == sizeof(KSSTREAM_HEADER) )
  393. {
  394. if ( lpdwTransferred )
  395. *lpdwTransferred = lpStreamHeader->DataUsed;
  396. // Delete the KSSTREAM_HEADER we allocated
  397. GlobalFree( (HGLOBAL)lpStreamHeader );
  398. lpOS->Offset = 0;
  399. nStatus = 0;
  400. }
  401. else
  402. {
  403. nStatus = GetLastError();
  404. }
  405. }
  406. else
  407. nStatus = ERROR_IO_PENDING;
  408. }
  409. return nStatus;
  410. }
  411. BOOL
  412. IKSPin::Run()
  413. {
  414. BOOL bCompleted = FALSE;
  415. if ( !m_bRunning )
  416. {
  417. if ( SetRunState( KSSTATE_RUN ) )
  418. {
  419. // We are now running
  420. m_bRunning = TRUE;
  421. bCompleted = TRUE;
  422. }
  423. else
  424. {
  425. // Throw a run failure exception
  426. }
  427. }
  428. else
  429. {
  430. // Throw an invalid state exception
  431. }
  432. return bCompleted;
  433. }
  434. BOOL
  435. IKSPin::Stop()
  436. {
  437. BOOL bCompleted = FALSE;
  438. if ( m_bRunning )
  439. {
  440. if ( SetRunState(KSSTATE_STOP) )
  441. {
  442. // We are now stopped.
  443. m_bRunning = FALSE;
  444. bCompleted = TRUE;
  445. }
  446. else
  447. {
  448. // Log the stop failure
  449. }
  450. }
  451. else
  452. {
  453. // Throw an invalid state exception
  454. }
  455. return bCompleted;
  456. }
  457. BOOL
  458. IKSPin::GetRunState( PKSSTATE pKSState )
  459. {
  460. KSPROPERTY KSProp={0};
  461. KSProp.Set = KSPROPSETID_Connection;
  462. KSProp.Id = KSPROPERTY_CONNECTION_STATE;
  463. KSProp.Flags = KSPROPERTY_TYPE_GET;
  464. DWORD dwReturned = 0;
  465. BOOL bStatus = Ioctl( IOCTL_KS_PROPERTY,
  466. &KSProp, sizeof(KSProp),
  467. pKSState, sizeof(*pKSState),
  468. &dwReturned);
  469. return bStatus && dwReturned == sizeof(pKSState);
  470. }
  471. BOOL
  472. IKSPin::SetRunState( KSSTATE KSState )
  473. {
  474. KSPROPERTY KSProp={0};
  475. KSProp.Set = KSPROPSETID_Connection;
  476. KSProp.Id = KSPROPERTY_CONNECTION_STATE;
  477. KSProp.Flags = KSPROPERTY_TYPE_SET;
  478. DWORD dwReturned = 0;
  479. BOOL bStatus = Ioctl( IOCTL_KS_PROPERTY,
  480. &KSProp, sizeof(KSProp),
  481. &KSState, sizeof(KSState),
  482. &dwReturned);
  483. return bStatus && dwReturned == sizeof(KSState);
  484. }
  485. BOOL
  486. IKSPin::OpenPin(PKSDATARANGE pKSDataRange )
  487. {
  488. BOOL bStatus = FALSE;
  489. struct tagPIN_CONNECT_DATARANGE
  490. {
  491. KSPIN_CONNECT PinConnect;
  492. KSDATARANGE DataRange;
  493. BYTE reserved[1024]; // Large enough for any reasonable specifier structure.
  494. } PinGlob;
  495. RtlZeroMemory(&PinGlob, sizeof(PinGlob));
  496. if ( pKSDataRange->FormatSize <= sizeof(KSDATARANGE)+sizeof(PinGlob.reserved) )
  497. {
  498. PinGlob.PinConnect.Interface.Set = KSINTERFACESETID_Standard;
  499. PinGlob.PinConnect.Interface.Id = KSINTERFACE_STANDARD_STREAMING; // STREAMING
  500. PinGlob.PinConnect.Medium.Set = KSMEDIUMSETID_Standard;
  501. PinGlob.PinConnect.Medium.Id = KSMEDIUM_STANDARD_DEVIO;
  502. PinGlob.PinConnect.PinId = m_nPin;
  503. PinGlob.PinConnect.PinToHandle = NULL; // no "connect to"
  504. PinGlob.PinConnect.Priority.PriorityClass = KSPRIORITY_NORMAL;
  505. PinGlob.PinConnect.Priority.PrioritySubClass = 1;
  506. RtlCopyMemory( &PinGlob.DataRange, pKSDataRange, pKSDataRange->FormatSize );
  507. if ( KsCreatePin( m_IKSDriver->m_hKSDriver, &PinGlob.PinConnect, GENERIC_READ | GENERIC_WRITE, &m_hKSPin ) == 0
  508. && m_hKSPin > 0 )
  509. bStatus = TRUE;
  510. else
  511. m_hKSPin = 0;
  512. }
  513. else
  514. {
  515. // Throw a bad parameter exception.
  516. }
  517. return bStatus;
  518. }
  519. BOOL
  520. IKSPin::ClosePin()
  521. {
  522. BOOL bStatus = TRUE;
  523. bStatus = CloseHandle(m_hKSPin);
  524. m_hKSPin = NULL;
  525. return bStatus;
  526. }
  527. //////////////////////////////////////////////////////////////
  528. // IKSProperty::
  529. //////////////////////////////////////////////////////////////
  530. IKSProperty::IKSProperty(IKSDriver &driver, LPCGUID Set, ULONG Id, ULONG Size)
  531. : m_Set(*Set), m_Id(Id), m_Size(Size), m_IKSPin(NULL), m_IKSDriver(NULL)
  532. {
  533. if ( m_Size > 0 )
  534. {
  535. if ( OpenProperty() )
  536. {
  537. m_IKSDriver = &driver;
  538. }
  539. else
  540. {
  541. // Throw an open failure exception
  542. }
  543. }
  544. else
  545. {
  546. // Throw a bad parameter exception.
  547. }
  548. }
  549. IKSProperty::IKSProperty(IKSPin &pin, LPCGUID Set, ULONG Id, ULONG Size)
  550. : m_Set(*Set), m_Id(Id), m_Size(Size), m_IKSPin(NULL), m_IKSDriver(NULL)
  551. {
  552. if ( m_Size > 0 )
  553. {
  554. if ( OpenProperty() )
  555. {
  556. m_IKSPin = &pin;
  557. }
  558. else
  559. {
  560. // Throw an open failure exception
  561. }
  562. }
  563. else
  564. {
  565. // Throw a bad parameter exception.
  566. }
  567. }
  568. IKSProperty::~IKSProperty()
  569. {
  570. if ( m_hKSProperty )
  571. {
  572. if ( CloseProperty() )
  573. {
  574. }
  575. else
  576. {
  577. // Throw a close failure exception
  578. }
  579. }
  580. }
  581. BOOL
  582. IKSProperty::SetValue(void *nValue)
  583. {
  584. BOOL bStatus = FALSE;
  585. PKSPROPERTY pKSProperty = (PKSPROPERTY)m_hKSProperty;
  586. LPBYTE pProperty = (LPBYTE)(pKSProperty+1);
  587. DWORD nReturned = 0;
  588. if ( IsValid() )
  589. {
  590. ZeroMemory(pKSProperty, sizeof(KSPROPERTY)+m_Size);
  591. pKSProperty->Flags = KSPROPERTY_TYPE_SET;
  592. pKSProperty->Set = m_Set;
  593. pKSProperty->Id = m_Id;
  594. CopyMemory( pProperty, nValue, m_Size );
  595. if ( m_IKSDriver )
  596. {
  597. bStatus = m_IKSDriver->Ioctl( IOCTL_KS_PROPERTY,
  598. (LPBYTE)pKSProperty, sizeof(KSPROPERTY)+m_Size,
  599. (LPBYTE)pKSProperty, sizeof(KSPROPERTY)+m_Size,
  600. &nReturned,
  601. NULL);
  602. }
  603. else if ( m_IKSPin )
  604. {
  605. bStatus = m_IKSPin->Ioctl( IOCTL_KS_PROPERTY,
  606. (LPBYTE)pKSProperty, sizeof(KSPROPERTY)+m_Size,
  607. (LPBYTE)pKSProperty, sizeof(KSPROPERTY)+m_Size,
  608. &nReturned,
  609. NULL);
  610. }
  611. }
  612. else
  613. {
  614. }
  615. return bStatus;
  616. }
  617. BOOL
  618. IKSProperty::GetValue(void *nValue)
  619. {
  620. BOOL bStatus = FALSE;
  621. PKSPROPERTY pKSProperty = (PKSPROPERTY)m_hKSProperty;
  622. LPBYTE pProperty = (LPBYTE)(pKSProperty+1);
  623. DWORD nReturned = 0;
  624. if ( IsValid() )
  625. {
  626. ZeroMemory(pKSProperty, sizeof(KSPROPERTY)+m_Size);
  627. pKSProperty->Flags = KSPROPERTY_TYPE_GET;
  628. pKSProperty->Set = m_Set;
  629. pKSProperty->Id = m_Id;
  630. if ( m_IKSDriver )
  631. {
  632. bStatus = m_IKSDriver->Ioctl( IOCTL_KS_PROPERTY,
  633. (LPBYTE)pKSProperty, sizeof(KSPROPERTY)+m_Size,
  634. (LPBYTE)pKSProperty, sizeof(KSPROPERTY)+m_Size,
  635. &nReturned,
  636. NULL);
  637. }
  638. else if ( m_IKSPin )
  639. {
  640. bStatus = m_IKSPin->Ioctl( IOCTL_KS_PROPERTY,
  641. (LPBYTE)pKSProperty, sizeof(KSPROPERTY)+m_Size,
  642. (LPBYTE)pKSProperty, sizeof(KSPROPERTY)+m_Size,
  643. &nReturned,
  644. NULL);
  645. }
  646. if ( bStatus )
  647. CopyMemory( nValue, pProperty, m_Size );
  648. }
  649. else
  650. {
  651. }
  652. return bStatus;
  653. }
  654. // Prob: the buffer is overrun during the Ioctl w/CCDECODE substreams.
  655. #define BUFFER_SLOP 4
  656. BOOL
  657. IKSProperty::OpenProperty()
  658. {
  659. BOOL bStatus = TRUE;
  660. LONG nTotalSize = sizeof(KSPROPERTY)+m_Size+BUFFER_SLOP;
  661. m_hKSProperty = (HANDLE)new BYTE[nTotalSize];
  662. return bStatus;
  663. }
  664. BOOL
  665. IKSProperty::CloseProperty()
  666. {
  667. BOOL bStatus = TRUE;
  668. delete (void *)m_hKSProperty;
  669. m_hKSProperty = NULL;
  670. return bStatus;
  671. }
  672. //////////////////////////////////////////////////////////////
  673. // Embedded class tests
  674. //////////////////////////////////////////////////////////////
  675. #if defined(_CLASSTESTS)
  676. IKSDriver TestDriver(&KSCATEGORY_VBICODEC,"Closed Caption Decoder");
  677. IKSPin TestPin(TestDriver, &GUID_NULL, &GUID_NULL, &GUID_NULL);
  678. IKSProperty TestProperty1(TestDriver, 0);
  679. IKSProperty TestProperty2(TestPin, 0);
  680. #endif
  681. /*EOF*/