Leaked source code of windows server 2003
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.

224 lines
5.7 KiB

  1. // ProgIDSpecification.cpp: implementation of the CProgIDSpecification class.
  2. //
  3. // Copyright (c) 1997-2002 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "ProgIDSpecification.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CProgIDSpecification::CProgIDSpecification(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CProgIDSpecification::~CProgIDSpecification()
  18. {
  19. }
  20. HRESULT CProgIDSpecification::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  21. {
  22. HRESULT hr = WBEM_S_NO_ERROR;
  23. MSIHANDLE hView = NULL, hRecord = NULL;
  24. int i = -1;
  25. WCHAR wcBuf[BUFF_SIZE];
  26. WCHAR wcProductCode[39];
  27. DWORD dwBufSize;
  28. bool bMatch;
  29. UINT uiStatus;
  30. bool bGotID = false;
  31. WCHAR wcProgId[BUFF_SIZE];
  32. WCHAR wcTestCode[39];
  33. //These will change from class to class
  34. bool bCheck;
  35. SetSinglePropertyPath(L"CheckID");
  36. //improve getobject performance by optimizing the query
  37. if(atAction != ACTIONTYPE_ENUM)
  38. {
  39. // we are doing GetObject so we need to be reinitialized
  40. hr = WBEM_E_NOT_FOUND;
  41. BSTR bstrCompare;
  42. int iPos = -1;
  43. bstrCompare = SysAllocString ( L"CheckID" );
  44. if ( bstrCompare )
  45. {
  46. if(FindIn(m_pRequest->m_Property, bstrCompare, &iPos))
  47. {
  48. if ( ::SysStringLen ( m_pRequest->m_Value[iPos] ) < BUFF_SIZE )
  49. {
  50. //Get the action we're looking for
  51. wcscpy(wcBuf, m_pRequest->m_Value[iPos]);
  52. // safe operation if wcslen ( wcBuf ) > 38
  53. if ( wcslen ( wcBuf ) > 38 )
  54. {
  55. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  56. }
  57. else
  58. {
  59. // we are not good to go, they have sent us longer string
  60. SysFreeString ( bstrCompare );
  61. throw hr;
  62. }
  63. // safe because lenght has been tested already in condition
  64. RemoveFinalGUID(m_pRequest->m_Value[iPos], wcProgId);
  65. bGotID = true;
  66. }
  67. else
  68. {
  69. // we are not good to go, they have sent us longer string
  70. SysFreeString ( bstrCompare );
  71. throw hr;
  72. }
  73. }
  74. SysFreeString ( bstrCompare );
  75. }
  76. else
  77. {
  78. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  79. }
  80. }
  81. Query wcQuery;
  82. wcQuery.Append ( 1, L"select distinct `ProgId`, `ProgId_Parent`, `Description` from ProgId" );
  83. //optimize for GetObject
  84. if ( bGotID )
  85. {
  86. wcQuery.Append ( 3, L" where `ProgId`=\'", wcProgId, L"\'" );
  87. }
  88. LPWSTR Buffer = NULL;
  89. LPWSTR dynBuffer = NULL;
  90. DWORD dwDynBuffer = 0L;
  91. while(m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  92. {
  93. // safe operation:
  94. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  95. wcscpy(wcProductCode, m_pRequest->Package(i));
  96. if((atAction == ACTIONTYPE_ENUM) || (bGotID && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  97. bMatch = false;
  98. //Open our database
  99. try
  100. {
  101. if ( GetView ( &hView, wcProductCode, wcQuery, L"ProgId", TRUE, FALSE ) )
  102. {
  103. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  104. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  105. CheckMSI(uiStatus);
  106. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  107. //----------------------------------------------------
  108. dwBufSize = BUFF_SIZE;
  109. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  110. PutProperty(m_pObj, pProgID, Buffer);
  111. PutProperty(m_pObj, pName, Buffer);
  112. PutKeyProperty ( m_pObj, pCheckID, Buffer, &bCheck, m_pRequest, 1, wcProductCode );
  113. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  114. {
  115. dynBuffer [ 0 ] = 0;
  116. }
  117. //====================================================
  118. dwBufSize = BUFF_SIZE;
  119. PutPropertySpecial ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pParent);
  120. dwBufSize = BUFF_SIZE;
  121. PutPropertySpecial ( hRecord, 3, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, FALSE, 2, pCaption, pDescription );
  122. //----------------------------------------------------
  123. if(bCheck) bMatch = true;
  124. if((atAction != ACTIONTYPE_GET) || bMatch){
  125. hr = pHandler->Indicate(1, &m_pObj);
  126. }
  127. m_pObj->Release();
  128. m_pObj = NULL;
  129. g_fpMsiCloseHandle(hRecord);
  130. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  131. }
  132. }
  133. }
  134. catch(...)
  135. {
  136. if ( dynBuffer )
  137. {
  138. delete [] dynBuffer;
  139. dynBuffer = NULL;
  140. }
  141. if (hRecord)
  142. g_fpMsiCloseHandle(hRecord);
  143. if (hView)
  144. {
  145. g_fpMsiViewClose(hView);
  146. g_fpMsiCloseHandle(hView);
  147. }
  148. msidata.CloseDatabase ();
  149. if(m_pObj)
  150. {
  151. m_pObj->Release();
  152. m_pObj = NULL;
  153. }
  154. throw;
  155. }
  156. if (hRecord)
  157. g_fpMsiCloseHandle(hRecord);
  158. if (hView)
  159. {
  160. g_fpMsiViewClose(hView);
  161. g_fpMsiCloseHandle(hView);
  162. }
  163. msidata.CloseDatabase ();
  164. }
  165. }
  166. if ( dynBuffer )
  167. {
  168. delete [] dynBuffer;
  169. dynBuffer = NULL;
  170. }
  171. return hr;
  172. }