ptutil.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 26k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //-------------------------------------------------------------------------//
  2. //
  3. // PTutil.cpp
  4. //
  5. //-------------------------------------------------------------------------//
  6. #include "pch.h"
  7. #include "PTutil.h"
  8. #include "PTserver.h"
  9. #define SAFE_SYSFREESTRING( bstr )  if((bstr)){ SysFreeString((bstr)); (bstr)=NULL; }
  10. #define SAFE_COPYSYSSTRING( dest, src )  if((src)){ (dest)=SysAllocString((src)); }
  11. //-------------------------------------------------------------------------//
  12. //  Property Folder ID definitions
  13. //  HACKHACK: These should go in shlguid
  14. // {19469210-75DE-11d2-BE77-00A0C9A83DA1}
  15. static const PFID PFID_Description =
  16.     { 0x19469210, 0x75de, 0x11d2, { 0xbe, 0x77, 0x0, 0xa0, 0xc9, 0xa8, 0x3d, 0xa1 } };
  17. // {19469211-75DE-11d2-BE77-00A0C9A83DA1}
  18. static const PFID PFID_Origin =
  19. { 0x19469211, 0x75de, 0x11d2, { 0xbe, 0x77, 0x0, 0xa0, 0xc9, 0xa8, 0x3d, 0xa1 } };
  20. // {19469212-75DE-11d2-BE77-00A0C9A83DA1}
  21. static const PFID PFID_ImageProperties =
  22. { 0x19469212, 0x75de, 0x11d2, { 0xbe, 0x77, 0x0, 0xa0, 0xc9, 0xa8, 0x3d, 0xa1 } };
  23. // {19469213-75DE-11d2-BE77-00A0C9A83DA1}
  24. static const PFID PFID_AudioProperties =
  25. { 0x19469213, 0x75de, 0x11d2, { 0xbe, 0x77, 0x0, 0xa0, 0xc9, 0xa8, 0x3d, 0xa1 } };
  26. // {19469214-75DE-11d2-BE77-00A0C9A83DA1}
  27. static const PFID PFID_VideoProperties =
  28. { 0x19469214, 0x75de, 0x11d2, { 0xbe, 0x77, 0x0, 0xa0, 0xc9, 0xa8, 0x3d, 0xa1 } };
  29. // {19469214-75DE-11d2-BE77-00A0C9A83DA1}
  30. static const PFID PFID_MidiProperties =
  31. { 0x19469215, 0x75de, 0x11d2, { 0xbe, 0x77, 0x0, 0xa0, 0xc9, 0xa8, 0x3d, 0xa1 } };
  32. // {4C927CBB-7994-11d2-BE78-00A0C9A83DA1}
  33. static const PFID PFID_FaxProperties = 
  34. { 0x4c927cbb, 0x7994, 0x11d2, { 0xbe, 0x78, 0x0, 0xa0, 0xc9, 0xa8, 0x3d, 0xa1 } };
  35. //-------------------------------------------------------------------------//
  36. LPWSTR WINAPI StrA2W( UINT nCodePage, LPWSTR pwsz, LPCSTR pasz, int cch )
  37. {
  38.     ASSERT(pwsz != NULL);
  39.     ASSERT(pasz != NULL);
  40.     pwsz[0] = '';
  41.     MultiByteToWideChar( nCodePage, 0, pasz, -1, pwsz, cch );
  42.     return pwsz;
  43. }
  44. //-------------------------------------------------------------------------//
  45. LPSTR WINAPI StrW2A( UINT nCodePage, LPSTR pasz, LPCWSTR pwsz, int cch )
  46. {
  47.     ASSERT(pasz != NULL);
  48.     ASSERT(pwsz != NULL);
  49.     pasz[0] = '';
  50.     WideCharToMultiByte( nCodePage, 0, pwsz, -1, pasz, cch, NULL, NULL ) ;
  51.     return pasz ;
  52. }
  53. //-------------------------------------------------------------------------//
  54. BOOL WINAPI StrRoundTripsW( UINT nCodePage, LPCWSTR pwsz )
  55. {
  56.     ASSERT( pwsz );
  57.     
  58.     int    cch = lstrlenW( pwsz ) ;
  59.     CHAR*  paszTest = (CHAR*) alloca( sizeof(CHAR)  * (cch+1) ) ;
  60.     WCHAR* pwszTest = (WCHAR*)alloca( sizeof(WCHAR) * (cch+1) ) ;
  61.     StrA2W( nCodePage, 
  62.             pwszTest,
  63.             StrW2A( nCodePage, paszTest, pwsz, cch ),
  64.             cch ) ;
  65.     return 0 == memcmp( pwsz, pwszTest, cch * sizeof(WCHAR) ) ;
  66. }
  67. //-------------------------------------------------------------------------//
  68. BOOL WINAPI StrRoundTripsA( UINT nCodePage, LPCSTR pasz )
  69. {
  70.     ASSERT( pwsz );
  71.     
  72.     int    cch = lstrlenA( pasz ) ;
  73.     CHAR*  paszTest = (CHAR*)alloca( sizeof(CHAR)  * (cch+1) ) ;
  74.     WCHAR* pwszTest = (WCHAR*)alloca( sizeof(WCHAR) * (cch+1) ) ;
  75.     StrW2A( nCodePage,
  76.             paszTest,
  77.             StrA2W( nCodePage, pwszTest, pasz, cch ),
  78.             cch ) ;
  79.     return 0 == memcmp( pasz, paszTest, cch * sizeof(CHAR) ) ;
  80. }
  81. //-------------------------------------------------------------------------//
  82. void InitPropFolderItem( struct tagPROPFOLDERITEM* pItem )
  83. {
  84.     if( pItem )
  85.     {
  86.         memset( pItem, 0, sizeof(*pItem) ) ;
  87.         pItem->cbStruct = sizeof(*pItem) ;
  88.         pItem->pfid     = PFID_NULL ;
  89.         pItem->iOrder   = -1 ;
  90.     }
  91. }
  92. //-------------------------------------------------------------------------//
  93. void ClearPropFolderItem( struct tagPROPFOLDERITEM* pItem )
  94. {
  95.     if( IsValidPropFolderItem( pItem ) )
  96.     {
  97.         SAFE_SYSFREESTRING( pItem->bstrName ) ;
  98.         SAFE_SYSFREESTRING( pItem->bstrDisplayName ) ;
  99.         SAFE_SYSFREESTRING( pItem->bstrQtip ) ;
  100.         InitPropFolderItem( pItem ) ;
  101.     }
  102. }
  103. //-------------------------------------------------------------------------//
  104. BOOL CopyPropFolderItem( struct tagPROPFOLDERITEM* pDest, const struct tagPROPFOLDERITEM* pSrc )
  105. {
  106.     if( !( pDest && IsValidPropFolderItem( pDest ) && IsValidPropFolderItem( pSrc ) ) )
  107.     {
  108.         ASSERT( FALSE ) ; // invalid arg (pDest) or unitialized dest or src.
  109.         return FALSE ;
  110.     }
  111.     ClearPropFolderItem( pDest ) ;
  112.     
  113.     *pDest = *pSrc ;
  114.     SAFE_COPYSYSSTRING( pDest->bstrName, pSrc->bstrName ) ;
  115.     SAFE_COPYSYSSTRING( pDest->bstrDisplayName, pSrc->bstrDisplayName ) ;
  116.     SAFE_COPYSYSSTRING( pDest->bstrQtip, pSrc->bstrQtip ) ;
  117.     return TRUE ;
  118. }
  119. //-------------------------------------------------------------------------//
  120. BOOL IsValidPropFolderItem( const struct tagPROPFOLDERITEM* pItem )
  121. {
  122.     return pItem!=NULL && pItem->cbStruct==sizeof(*pItem) ;
  123. }
  124. //-------------------------------------------------------------------------//
  125. void InitPropertyItem( struct tagPROPERTYITEM* pItem )
  126. {
  127.     if( pItem )
  128.     {
  129.         memset( pItem, 0, sizeof(*pItem) ) ;
  130.         pItem->cbStruct = sizeof(*pItem) ;
  131.         pItem->pfid     = PFID_NULL ;
  132.         pItem->iOrder   = -1 ;
  133.     }
  134. }
  135. //-------------------------------------------------------------------------//
  136. void ClearPropertyItem( struct tagPROPERTYITEM* pItem )
  137. {
  138.     if( IsValidPropertyItem( pItem ) )
  139.     {
  140.         SAFE_SYSFREESTRING( pItem->bstrName ) ;
  141.         SAFE_SYSFREESTRING( pItem->bstrDisplayName ) ;
  142.         SAFE_SYSFREESTRING( pItem->bstrQtip ) ;
  143.         PropVariantClear( &pItem->val ) ;
  144.     }
  145.     InitPropertyItem( pItem ) ;
  146. }
  147. //-------------------------------------------------------------------------//
  148. BOOL CopyPropertyItem( struct tagPROPERTYITEM* pDest, const struct tagPROPERTYITEM* pSrc )
  149. {
  150.     if( !( pDest && IsValidPropertyItem( pSrc ) && IsValidPropertyItem( pDest ) ) )
  151.     {
  152.         ASSERT( FALSE ) ;// invalid arg (pDest) or unitialized source, dest.
  153.         return FALSE ;
  154.     }
  155.     ClearPropertyItem( pDest ) ;
  156.         
  157.     *pDest = *pSrc ;
  158.     SAFE_COPYSYSSTRING( pDest->bstrName, pSrc->bstrName ) ;
  159.     SAFE_COPYSYSSTRING( pDest->bstrDisplayName, pSrc->bstrDisplayName ) ;
  160.     SAFE_COPYSYSSTRING( pDest->bstrQtip, pSrc->bstrQtip ) ;
  161.     PropVariantInit( &pDest->val ) ;
  162.     PropVariantCopy( &pDest->val, &pSrc->val ) ;
  163.     return TRUE ;
  164. }
  165. //-------------------------------------------------------------------------//
  166. BOOL IsValidPropertyItem( const struct tagPROPERTYITEM* pItem )
  167. {
  168.     return pItem!=NULL && pItem->cbStruct==sizeof(*pItem) ;
  169. }
  170. //-------------------------------------------------------------------------//
  171. void InitBasicPropertyItem( struct tagBASICPROPITEM* pItem )
  172. {
  173.     if( pItem )
  174.     {
  175.         memset( pItem, 0, sizeof(*pItem) ) ;
  176.         pItem->cbStruct = sizeof(*pItem) ;
  177.     }
  178. }
  179. //-------------------------------------------------------------------------//
  180. void ClearBasicPropertyItem( struct tagBASICPROPITEM* pItem )
  181. {
  182.     if( IsValidBasicPropertyItem( pItem ) )
  183.     {
  184.         PropVariantClear( &pItem->val ) ;
  185.     }
  186.     InitBasicPropertyItem( pItem ) ;
  187. }
  188. //-------------------------------------------------------------------------//
  189. BOOL CopyBasicPropertyItem( struct tagBASICPROPITEM* pDest, const struct tagBASICPROPITEM* pSrc )
  190. {
  191.     if( !( pDest && IsValidBasicPropertyItem( pSrc ) && IsValidBasicPropertyItem( pDest ) ) )
  192.     {
  193.         ASSERT( FALSE ) ;// invalid arg (pDest) or unitialized source, dest.
  194.         return FALSE ;
  195.     }
  196.     ClearBasicPropertyItem( pDest ) ;
  197.         
  198.     *pDest = *pSrc ;
  199.     PropVariantInit( &pDest->val ) ;
  200.     PropVariantCopy( &pDest->val, &pSrc->val ) ;
  201.     return TRUE ;
  202. }
  203. //-------------------------------------------------------------------------//
  204. BOOL IsValidBasicPropertyItem( const struct tagBASICPROPITEM* pItem )
  205. {
  206.     return pItem!=NULL && pItem->cbStruct==sizeof(*pItem) ;
  207. }
  208. //-------------------------------------------------------------------------//
  209. void InitPropVariantDisplay( struct tagPROPVARIANT_DISPLAY* pItem )
  210. {
  211.     if( pItem )
  212.     {
  213.         PropVariantInit( &pItem->val ) ;
  214.         pItem->bstrDisplay = NULL ;
  215.     }
  216. }
  217. //-------------------------------------------------------------------------//
  218. BOOL CopyPropVariantDisplay( struct tagPROPVARIANT_DISPLAY* pDest, const struct tagPROPVARIANT_DISPLAY* pSrc )
  219. {
  220.     if( pDest && pSrc )
  221.     {
  222.         ClearPropVariantDisplay( pDest ) ;
  223.         PropVariantCopy( &pDest->val, &pSrc->val ) ;
  224.         if( pSrc->bstrDisplay )
  225.             pDest->bstrDisplay =  SysAllocString( pSrc->bstrDisplay ) ;
  226.         
  227.         return TRUE ;
  228.     }
  229.     return FALSE ;
  230. }
  231. //-------------------------------------------------------------------------//
  232. void ClearPropVariantDisplay( struct tagPROPVARIANT_DISPLAY* pItem )
  233. {
  234.     if( pItem )
  235.     {
  236.         PropVariantClear( &pItem->val ) ;
  237.         if( pItem->bstrDisplay )
  238.             SysFreeString( pItem->bstrDisplay ) ;
  239.         InitPropVariantDisplay( pItem ) ;
  240.     }
  241. }
  242. //-------------------------------------------------------------------------//
  243. BOOL PTCheckWriteAccessA( LPCSTR pszFile )
  244. {
  245.     //  Test write access.
  246.     HANDLE hFile = CreateFileA( pszFile, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL,
  247.                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OPEN_NO_RECALL, NULL );
  248.     if( INVALID_HANDLE_VALUE != hFile )
  249.     {
  250.         CloseHandle( hFile );
  251.         return TRUE;
  252.     }
  253.     return FALSE;
  254. }
  255. //-------------------------------------------------------------------------//
  256. BOOL PTCheckWriteAccessW( LPCWSTR pwszFile )
  257. {
  258.     //  Test write access.
  259.     HANDLE hFile = CreateFileW( pwszFile, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL,
  260.                                 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OPEN_NO_RECALL, NULL );
  261.     if( INVALID_HANDLE_VALUE != hFile )
  262.     {
  263.         CloseHandle( hFile );
  264.         return TRUE;
  265.     }
  266.     return FALSE;
  267. }
  268. //-------------------------------------------------------------------------//
  269. ULONG PTGetFileAttributesA( LPCSTR pszFile )
  270. {
  271.     ULONG dwAttr = GetFileAttributesA( pszFile );
  272.     if( dwAttr != 0xFFFFFFFF && (dwAttr & FILE_ATTRIBUTE_READONLY) == 0 )
  273.     {
  274.         if( !PTCheckWriteAccessA( pszFile ) )
  275.             dwAttr |= FILE_ATTRIBUTE_READONLY; 
  276.     }
  277.     return dwAttr;
  278. }
  279. //-------------------------------------------------------------------------//
  280. ULONG PTGetFileAttributesW( LPCWSTR pszFile )
  281. {
  282.     ULONG dwAttr = GetFileAttributesW( pszFile );
  283.     
  284.     if( dwAttr != 0xFFFFFFFF && (dwAttr & FILE_ATTRIBUTE_READONLY) == 0 )
  285.     {
  286.         if( !PTCheckWriteAccessW( pszFile ) )
  287.             dwAttr |= FILE_ATTRIBUTE_READONLY; 
  288.     }
  289.     return dwAttr;
  290. }
  291. //-------------------------------------------------------------------------//
  292. //  Tokenizes a string into a linked list of token descriptors.  On return, 
  293. //  all delimiters present in the original input string will be
  294. //  replaced with NULL characters.
  295. int GetTokens( LPTSTR pszString, LPCTSTR pszDelims, OUT PSTRTOK *ppList )
  296. {
  297.     PSTRTOK pNext = NULL,
  298.             pTok  = NULL ;
  299.     int     cRet  = 0 ;
  300.     if( !( pszString && *pszString && pszDelims && *pszDelims && ppList) )
  301.         return NULL ;
  302.     *ppList = NULL ;
  303.     LPTSTR  pszTok = pszString ;
  304.     int     cchString = lstrlen( pszString ),
  305.             cchDelims = lstrlen( pszDelims ) ;
  306.     for( int i=0; i < cchString; i++ )
  307.     {
  308.         //  Is the character a delimiter
  309.         if( _tcschr( pszDelims, pszTok[i] )!=NULL )
  310.         {
  311.             pszTok[i] = (TCHAR)0 ;  // zero it in place.
  312.             if( i > 0 ) continue ;  // go to next character if we're into the string
  313.         }
  314.         //  Allocate and initialize a token descriptor
  315.         if( (pTok = new STRTOK)!=NULL )
  316.         {
  317.             memset( pTok, 0, sizeof(*pTok) ) ;
  318.             pTok->pszTok = &pszTok[i] ;
  319.             
  320.             //  skip to next character
  321.             for( ; i < cchString ; i++ )
  322.             {
  323.                 if( _tcschr( pszDelims, pszTok[i] )!=NULL )
  324.                 {
  325.                     pszTok[i] = (TCHAR)0 ;  // Zero the delimiter in place
  326.                     break ;                 // We've reached the end of the token;
  327.                                             // bust out of the loop and link it to the list.
  328.                 }
  329.                 pTok->cchTok++ ;  // not a delimiter; increment char count for the token.
  330.             }
  331.             //  link the token to the list
  332.             if( pNext == NULL )
  333.                 *ppList = pNext = pTok ; // no list yet; establish our head.
  334.             else
  335.             {
  336.                 pNext->pNext = pTok ;
  337.                 pNext = pTok ;
  338.             }
  339.             cRet++ ;  // increment token count
  340.         }
  341.     }
  342.     return cRet ;
  343. }
  344. //-------------------------------------------------------------------------//
  345. //  Frees a list of token descriptors generated by GetTokens().
  346. int FreeTokens( PSTRTOK* ppList )
  347. {
  348.     int cTokens = 0 ;
  349.     if( ppList )
  350.     {
  351.         while( *ppList )
  352.         {
  353.             PSTRTOK pNext = (*ppList)->pNext ;
  354.             delete (*ppList) ;
  355.             cTokens++ ;
  356.             (*ppList) = pNext ;
  357.         }
  358.     }
  359.     
  360.     return cTokens ;
  361. }
  362. //-------------------------------------------------------------------------//
  363. //  Time validation routines.   These will remain necessary until
  364. //  SystemTimeToVariantTime() and VariantTimeToSystemTime() to date validation.
  365. //  See bug# #329259 for more info.
  366. //-------------------------------------------------------------------------//
  367. #if 0
  368. //-------------------------------------------------------------------------//
  369. EXTERN_C BOOL IsValidSystemTime( SYSTEMTIME* pst )
  370. {
  371.     FILETIME ft ;
  372.     return SystemTimeToFileTime( pst, &ft ); // validates the SYSTEMTIME arg
  373. }
  374. //-------------------------------------------------------------------------//
  375. EXTERN_C BOOL IsValidFileTime( FILETIME* pft )
  376. {
  377.     SYSTEMTIME st;
  378.     return FileTimeToSystemTime( pft, &st ); // validates the FILETIME arg
  379. }
  380. //-------------------------------------------------------------------------//
  381. EXTERN_C BOOL IsValidVariantTime( DATE* pvt )
  382. {
  383.     SYSTEMTIME st;
  384.     FILETIME   ft;
  385.     VariantTimeToSystemTime( pvt, &st );
  386.     return SystemTimeToFileTime( &st, &ft );// validates the SYSTEMTIME arg
  387. }
  388. #endif 0
  389. //-------------------------------------------------------------------------//
  390. //  Accessibility primitives
  391. //-------------------------------------------------------------------------//
  392. //-------------------------------------------------------------------------//
  393. typedef HRESULT (WINAPI * PFNCREATESDTACCESSIBLEPROXY)( HWND, LPCTSTR, LONG, REFIID, void ** );
  394. typedef LRESULT (WINAPI * PFNLRESULTFROMOBJECT)( REFIID, WPARAM, LPUNKNOWN );
  395. #ifdef UNICODE
  396. #define CREATESTDACCESSIBLEPROXY    "CreateStdAccessibleProxyW"
  397. #else
  398. #define CREATESTDACCESSIBLEPROXY    "CreateStdAccessibleProxyA"
  399. #endif
  400. #define LRESULTFROMOBJECT           "LresultFromObject"
  401. //-------------------------------------------------------------------------//
  402. class COleAcc
  403. //-------------------------------------------------------------------------//
  404. {
  405. public:
  406.     COleAcc()
  407.         :   _hinstOleAcc(NULL),
  408.             _pfnCreateStdAccessibleProxy(NULL),
  409.             _pfnLresultFromObject(NULL) {}
  410.     ~COleAcc()    {
  411.         if( _hinstOleAcc )  {
  412.             FreeLibrary( _hinstOleAcc );
  413.             _hinstOleAcc = NULL;
  414.         }
  415.     }
  416.     HRESULT _CreateStdAccessibleProxy( HWND, WPARAM, IAccessible** );
  417.     LRESULT _LresultFromObject( REFIID, WPARAM, LPUNKNOWN );
  418. private:
  419.     BOOL Init();
  420.     HINSTANCE                    _hinstOleAcc;
  421.     PFNCREATESDTACCESSIBLEPROXY  _pfnCreateStdAccessibleProxy;
  422.     PFNLRESULTFROMOBJECT         _pfnLresultFromObject;    
  423. } OleAcc ;
  424. //-------------------------------------------------------------------------//
  425. BOOL COleAcc::Init()
  426. {
  427.     if( NULL == _hinstOleAcc )
  428.     {
  429.         if( NULL == (_hinstOleAcc = LoadLibrary( TEXT("oleacc.dll") )) )
  430.             return FALSE;
  431.     }
  432.     
  433.     if( NULL == _pfnCreateStdAccessibleProxy )
  434.     {
  435.         if( NULL == (_pfnCreateStdAccessibleProxy = (PFNCREATESDTACCESSIBLEPROXY)GetProcAddress(
  436.                             _hinstOleAcc, CREATESTDACCESSIBLEPROXY )) )
  437.             return FALSE;
  438.     }
  439.     if( NULL == _pfnLresultFromObject )
  440.     {
  441.         if( NULL == (_pfnLresultFromObject = (PFNLRESULTFROMOBJECT)GetProcAddress(
  442.                             _hinstOleAcc, LRESULTFROMOBJECT )) )
  443.             return FALSE;
  444.     }
  445.    
  446.     return TRUE;
  447. }
  448. //-------------------------------------------------------------------------//
  449. HRESULT COleAcc::_CreateStdAccessibleProxy( HWND hwnd, WPARAM wParam, IAccessible** ppacc )
  450. {
  451. #if DBG
  452.     // Validate that we declared the function correctly
  453.     if (_pfnCreateStdAccessibleProxy == CreateStdAccessibleProxy) { }
  454. #endif
  455.     if( !Init() )
  456.         return E_UNEXPECTED;
  457.     return _pfnCreateStdAccessibleProxy( hwnd, WC_TREEVIEW, (LONG)wParam,
  458.                                          IID_IAccessible, (void **)ppacc );
  459. }
  460. //-------------------------------------------------------------------------//
  461. HRESULT _CreateStdAccessibleProxy( HWND hwnd, WPARAM wParam, IAccessible** ppacc )
  462. {
  463.     return OleAcc._CreateStdAccessibleProxy( hwnd, wParam, ppacc );
  464. }
  465. //-------------------------------------------------------------------------//
  466. LRESULT COleAcc::_LresultFromObject( REFIID riid, WPARAM wParam, LPUNKNOWN punk )
  467. {
  468. #if DBG
  469.     // Validate that we declared the function correctly
  470.     if (_pfnLresultFromObject == LresultFromObject) { }
  471. #endif
  472.     if( !Init() )
  473.         return E_UNEXPECTED;
  474.     return _pfnLresultFromObject( riid, wParam, punk );
  475. }
  476. //-------------------------------------------------------------------------//
  477. LRESULT _LresultFromObject( REFIID riid, WPARAM wParam, LPUNKNOWN punk )
  478. {
  479.     return OleAcc._LresultFromObject( riid, wParam, punk );
  480. }
  481. //-------------------------------------------------------------------------//
  482. //  CAccessibleBase
  483. //-------------------------------------------------------------------------//
  484. //-------------------------------------------------------------------------//
  485. //  CAccessibleBase IUnknown impl
  486. STDMETHODIMP CAccessibleBase::QueryInterface( REFIID riid, void** ppvObj )
  487. {
  488.     HRESULT hres;
  489.     if( !ppvObj ) return E_POINTER;
  490.     *ppvObj = NULL;
  491.     if( IsEqualIID( riid, IID_IUnknown ) )
  492.         *ppvObj = (IUnknown*)(IAccessible*)this;
  493.     else if( IsEqualIID( riid, IID_IDispatch ) )
  494.         *ppvObj = (IDispatch*)this;
  495.     else if( IsEqualIID( riid, IID_IAccessible ) )
  496.         *ppvObj = (IAccessible*)this;
  497.     else if( IsEqualIID( riid, IID_IOleWindow ) )
  498.         *ppvObj = (IOleWindow*)this;
  499.     if( *ppvObj )
  500.     {
  501.         AddRef();
  502.         return S_OK;
  503.     }
  504.     return E_NOINTERFACE;
  505. }
  506. //-------------------------------------------------------------------------//
  507. STDMETHODIMP_(ULONG) CAccessibleBase::AddRef()
  508. {
  509.     return InterlockedIncrement( (LONG*)&_cRef );
  510. }
  511. //-------------------------------------------------------------------------//
  512. STDMETHODIMP_(ULONG) CAccessibleBase::Release()
  513. {
  514.     ULONG cRef = InterlockedDecrement( (LONG*)&_cRef );
  515.     if( cRef <= 0 )
  516.     {
  517.         DllRelease();
  518.         delete this;
  519.     }
  520.     return cRef;
  521. }
  522. //-------------------------------------------------------------------------//
  523. //  CAccessibleBase IOleWindow impl
  524. STDMETHODIMP CAccessibleBase::GetWindow( HWND* phwnd )
  525. {
  526.     *phwnd = _hwnd;
  527.     return IsWindow( _hwnd ) ? S_OK : S_FALSE;
  528. }
  529. //-------------------------------------------------------------------------//
  530. //  CAccessibleBase IDispatch impl
  531. //-------------------------------------------------------------------------//
  532. UINT WMU_GETACCSTRING()
  533. {
  534.     static UINT _wmu_getaccstring = 0;
  535.     if( 0 == _wmu_getaccstring )
  536.         _wmu_getaccstring = RegisterWindowMessage( TEXT("PropTreeGetAccString") );
  537.     return _wmu_getaccstring;
  538. }
  539. inline BSTR _GetAccString( HWND hwnd, DISPID dispid, LPARAM lParam ) 
  540. {
  541.     if( lParam )
  542.         return (BSTR)SendMessage( hwnd, WMU_GETACCSTRING(), (WPARAM)dispid, lParam );
  543.     return NULL;
  544. }
  545. static BOOL _accLoadTypeInfo( ITypeInfo** ppti )
  546. {
  547.     ITypeLib* ptl;
  548.     HRESULT hr = LoadTypeLib(L"oleacc.dll", &ptl);
  549.     if( SUCCEEDED( hr ) )
  550.     {
  551.         hr = ptl->GetTypeInfoOfGuid( IID_IAccessible, ppti );
  552.         ATOMICRELEASE( ptl );
  553.     }
  554.     return hr;
  555. }
  556. STDMETHODIMP CAccessibleBase::GetTypeInfoCount( UINT * pctinfo ) 
  557.     *pctinfo = 1;
  558.     return S_OK;
  559. }
  560. STDMETHODIMP CAccessibleBase::GetTypeInfo( UINT itinfo, LCID lcid, ITypeInfo** pptinfo )
  561.     HRESULT hr = E_FAIL;
  562.     if( NULL == _ptiAcc && FAILED( (hr = _accLoadTypeInfo( &_ptiAcc )) ) )
  563.         return hr;
  564.     *pptinfo = _ptiAcc;
  565.     (*pptinfo)->AddRef();
  566.     return S_OK;
  567. }
  568. STDMETHODIMP CAccessibleBase::GetIDsOfNames( 
  569.     REFIID riid, 
  570.     OLECHAR** rgszNames, 
  571.     UINT cNames,
  572.     LCID lcid, DISPID * rgdispid )
  573. {
  574.     HRESULT hr = E_FAIL;
  575.     if( IID_NULL != riid && IID_IAccessible != riid )
  576.         return DISP_E_UNKNOWNINTERFACE;
  577.     if( NULL == _ptiAcc && FAILED( (hr = _accLoadTypeInfo( &_ptiAcc )) ) )
  578.         return hr;
  579.     return _ptiAcc->GetIDsOfNames( rgszNames, cNames, rgdispid );
  580. }
  581. STDMETHODIMP CAccessibleBase::Invoke( 
  582.     DISPID  dispidMember, 
  583.     REFIID  riid, 
  584.     LCID    lcid, 
  585.     WORD    wFlags,
  586.     DISPPARAMS * pdispparams, 
  587.     VARIANT * pvarResult, 
  588.     EXCEPINFO * pexcepinfo, 
  589.     UINT * puArgErr )
  590. {
  591.     HRESULT hr = E_FAIL;
  592.     if( IID_NULL != riid && IID_IAccessible != riid )
  593.         return DISP_E_UNKNOWNINTERFACE;
  594.     if( NULL == _ptiAcc && FAILED( (hr = _accLoadTypeInfo( &_ptiAcc )) ) )
  595.         return hr;
  596.     return _ptiAcc->Invoke( this, dispidMember, wFlags, pdispparams, 
  597.                             pvarResult, pexcepinfo, puArgErr );
  598. }
  599. STDMETHODIMP CAccessibleBase::get_accParent( IDispatch ** ppdispParent )
  600. {
  601.     ASSERT(_paccProxy);
  602.     return _paccProxy->get_accParent( ppdispParent );
  603. }
  604. STDMETHODIMP CAccessibleBase::get_accChildCount( long * pcChildren )
  605. {
  606.     ASSERT(_paccProxy);
  607.     return _paccProxy->get_accChildCount( pcChildren );
  608. }
  609. STDMETHODIMP CAccessibleBase::get_accChild( VARIANT varChildIndex, IDispatch ** ppdispChild)
  610. {
  611.     ASSERT(_paccProxy);
  612.     return _paccProxy->get_accChild( varChildIndex, ppdispChild );
  613. }
  614. STDMETHODIMP CAccessibleBase::get_accName( VARIANT varChild, BSTR* pbstrName)
  615. {
  616.     ASSERT(_paccProxy);
  617.     *pbstrName = _GetAccString( _hwnd, DISPID_ACC_NAME, varChild.lVal );
  618.     return *pbstrName ? S_OK :S_FALSE ;
  619. }
  620. STDMETHODIMP CAccessibleBase::get_accValue( VARIANT varChild, BSTR* pbstrValue)
  621. {
  622.     ASSERT(_paccProxy);
  623.     *pbstrValue = _GetAccString( _hwnd, DISPID_ACC_VALUE, varChild.lVal );
  624.     return *pbstrValue ? S_OK : S_FALSE;
  625. }
  626. STDMETHODIMP CAccessibleBase::get_accDescription( VARIANT varChild, BSTR * pbstrDescription)
  627. {
  628.     ASSERT(_paccProxy);
  629.     *pbstrDescription = _GetAccString( _hwnd, DISPID_ACC_DESCRIPTION, varChild.lVal );
  630.     return *pbstrDescription ? S_OK :S_FALSE ;
  631. }
  632. STDMETHODIMP CAccessibleBase::get_accRole( VARIANT varChild, VARIANT *pvarRole )
  633. {
  634.     ASSERT(_paccProxy);
  635.     return _paccProxy->get_accRole( varChild, pvarRole );
  636. }
  637. STDMETHODIMP CAccessibleBase::get_accState( VARIANT varChild, VARIANT *pvarState )
  638. {
  639.     ASSERT(_paccProxy);
  640.     return _paccProxy->get_accState( varChild, pvarState );
  641. }
  642. STDMETHODIMP CAccessibleBase::get_accHelp( VARIANT varChild, BSTR* pbstrHelp )
  643. {
  644.     ASSERT(_paccProxy);
  645.     return _paccProxy->get_accHelp( varChild, pbstrHelp );
  646. }
  647. STDMETHODIMP CAccessibleBase::get_accHelpTopic( BSTR* pbstrHelpFile, VARIANT varChild, long* pidTopic )
  648. {
  649.     ASSERT(_paccProxy);
  650.     return _paccProxy->get_accHelpTopic( pbstrHelpFile, varChild, pidTopic );
  651. }
  652. STDMETHODIMP CAccessibleBase::get_accKeyboardShortcut( VARIANT varChild, BSTR* pbstrKeyboardShortcut )
  653. {
  654.     ASSERT(_paccProxy);
  655.     return _paccProxy->get_accKeyboardShortcut( varChild, pbstrKeyboardShortcut );
  656. }
  657. STDMETHODIMP CAccessibleBase::get_accFocus( VARIANT FAR * pvarFocusChild )
  658. {
  659.     ASSERT(_paccProxy);
  660.     return _paccProxy->get_accFocus( pvarFocusChild );
  661. }
  662. STDMETHODIMP CAccessibleBase::get_accSelection( VARIANT FAR * pvarSelectedChildren )
  663. {
  664.     ASSERT(_paccProxy);
  665.     return _paccProxy->get_accSelection( pvarSelectedChildren );
  666. }
  667. STDMETHODIMP CAccessibleBase::get_accDefaultAction( VARIANT varChild, BSTR* pbstrDefaultAction )
  668. {
  669.     ASSERT(_paccProxy);
  670.     return _paccProxy->get_accDefaultAction( varChild, pbstrDefaultAction );
  671. }
  672. STDMETHODIMP CAccessibleBase::accSelect( long flagsSelect, VARIANT varChild )
  673. {
  674.     ASSERT(_paccProxy);
  675.     return _paccProxy->accSelect( flagsSelect, varChild );
  676. }
  677. STDMETHODIMP CAccessibleBase::accLocation( long* pxLeft, long* pyTop, long* pcxWidth, long* pcyHeight, VARIANT varChild )
  678. {
  679.     ASSERT(_paccProxy);
  680.     return _paccProxy->accLocation( pxLeft, pyTop, pcxWidth, pcyHeight, varChild );
  681. }
  682. STDMETHODIMP CAccessibleBase::accNavigate( long navDir, VARIANT varStart, VARIANT * pvarEndUpAt )
  683. {
  684.     ASSERT(_paccProxy);
  685.     return _paccProxy->accNavigate( navDir, varStart, pvarEndUpAt );
  686. }
  687. STDMETHODIMP CAccessibleBase::accHitTest( long xLeft, long yTop, VARIANT * pvarChildAtPoint )
  688. {
  689.     ASSERT(_paccProxy);
  690.     return _paccProxy->accHitTest( xLeft, yTop, pvarChildAtPoint );
  691. }
  692. STDMETHODIMP CAccessibleBase::accDoDefaultAction( VARIANT varChild )
  693. {
  694.     ASSERT(_paccProxy);
  695.     return _paccProxy->accDoDefaultAction( varChild );
  696. }
  697. STDMETHODIMP CAccessibleBase::put_accName( VARIANT varChild, BSTR bstrName )
  698. {
  699.     ASSERT(_paccProxy);
  700.     return _paccProxy->put_accName( varChild, bstrName );
  701. }
  702. STDMETHODIMP CAccessibleBase::put_accValue( VARIANT varChild, BSTR bstrValue )
  703. {
  704.     ASSERT(_paccProxy);
  705.     return _paccProxy->put_accValue( varChild, bstrValue );
  706. }