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.

300 lines
9.2 KiB

  1. // ClassInfoAction.cpp: implementation of the CClassInfoAction class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "ClassInfoAction.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CClassInfoAction::CClassInfoAction(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CClassInfoAction::~CClassInfoAction()
  18. {
  19. }
  20. HRESULT CClassInfoAction::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  21. {
  22. HRESULT hr = WBEM_S_NO_ERROR;
  23. MSIHANDLE hView = NULL;
  24. MSIHANDLE hRecord = NULL;
  25. MSIHANDLE hSView = NULL;
  26. MSIHANDLE hSRecord = NULL;
  27. int i = -1;
  28. WCHAR wcBuf[BUFF_SIZE];
  29. WCHAR wcQuery1[BUFF_SIZE];
  30. WCHAR wcProductCode[39];
  31. WCHAR wcCLSID[BUFF_SIZE];
  32. DWORD dwBufSize;
  33. bool bMatch = false;
  34. UINT uiStatus;
  35. bool bGotID = false;
  36. WCHAR wcAction[BUFF_SIZE];
  37. WCHAR wcTestCode[39];
  38. //These will change from class to class
  39. bool bCheck;
  40. SetSinglePropertyPath(L"ActionID");
  41. //improve getobject performance by optimizing the query
  42. if(atAction != ACTIONTYPE_ENUM)
  43. {
  44. // we are doing GetObject so we need to be reinitialized
  45. hr = WBEM_E_NOT_FOUND;
  46. BSTR bstrCompare;
  47. int iPos = -1;
  48. bstrCompare = SysAllocString ( L"ActionID" );
  49. if ( bstrCompare )
  50. {
  51. if(FindIn(m_pRequest->m_Property, bstrCompare, &iPos))
  52. {
  53. if ( ::SysStringLen ( m_pRequest->m_Value[iPos] ) < BUFF_SIZE )
  54. {
  55. //Get the action we're looking for
  56. wcscpy(wcBuf, m_pRequest->m_Value[iPos]);
  57. // safe operation if wcslen ( wcBuf ) > 38
  58. if ( wcslen ( wcBuf ) > 38 )
  59. {
  60. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  61. }
  62. else
  63. {
  64. // we are not good to go, they have sent us longer string
  65. SysFreeString ( bstrCompare );
  66. throw hr;
  67. }
  68. // safe because lenght has been tested already in condition
  69. GetFirstGUID(m_pRequest->m_Value[iPos], wcAction);
  70. bGotID = true;
  71. }
  72. else
  73. {
  74. // we are not good to go, they have sent us longer string
  75. SysFreeString ( bstrCompare );
  76. throw hr;
  77. }
  78. }
  79. SysFreeString ( bstrCompare );
  80. }
  81. else
  82. {
  83. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  84. }
  85. }
  86. CStringExt wcProp;
  87. Query wcQuery;
  88. wcQuery.Append ( 1, L"select distinct `Component_`, `CLSID`, `Context`, `ProgId_Default`, `Description`, `AppId_`, `FileTypeMask`, `DefInprocHandler`, `Argument` from Class" );
  89. if ( bGotID )
  90. {
  91. wcQuery.Append ( 3, L" where `CLSID`=\'", wcAction, L"\'" );
  92. }
  93. LPWSTR Buffer = NULL;
  94. LPWSTR dynBuffer = NULL;
  95. DWORD dwDynBuffer = 0L;
  96. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  97. {
  98. // safe operation:
  99. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  100. wcscpy(wcProductCode, m_pRequest->Package(i));
  101. if((atAction == ACTIONTYPE_ENUM) || (bGotID && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  102. //Open our database
  103. try
  104. {
  105. if ( GetView ( &hView, wcProductCode, wcQuery, L"Class", TRUE, FALSE ) )
  106. {
  107. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  108. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  109. CheckMSI(uiStatus);
  110. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  111. //----------------------------------------------------
  112. dwBufSize = BUFF_SIZE;
  113. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  114. if ( ValidateComponentName ( msidata.GetDatabase (), wcProductCode, Buffer ) )
  115. {
  116. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  117. {
  118. dynBuffer [ 0 ] = 0;
  119. }
  120. dwBufSize = 39;
  121. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 2, wcCLSID, &dwBufSize));
  122. PutProperty(m_pObj, pCLSID, wcCLSID);
  123. PutProperty(m_pObj, pName, wcCLSID);
  124. dwBufSize = BUFF_SIZE;
  125. GetBufferToPut ( hRecord, 3, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  126. PutProperty(m_pObj, pContext, Buffer);
  127. wcProp.Append ( 3, wcCLSID, Buffer, wcProductCode );
  128. PutKeyProperty(m_pObj, pActionID, wcProp, &bCheck, m_pRequest);
  129. wcProp.Clear ( );
  130. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  131. {
  132. dynBuffer [ 0 ] = 0;
  133. }
  134. //====================================================
  135. dwBufSize = BUFF_SIZE;
  136. PutPropertySpecial ( hRecord, 4, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pProgID, FALSE );
  137. dwBufSize = BUFF_SIZE;
  138. PutPropertySpecial ( hRecord, 5, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, FALSE, 2, pDescription, pCaption );
  139. dwBufSize = 39;
  140. CheckMSI(g_fpMsiRecordGetStringW(hRecord, 6, wcBuf, &dwBufSize));
  141. PutProperty(m_pObj, pAppID, wcBuf);
  142. dwBufSize = BUFF_SIZE;
  143. PutPropertySpecial ( hRecord, 7, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pFileTypeMask, FALSE );
  144. dwBufSize = BUFF_SIZE;
  145. PutPropertySpecial ( hRecord, 8, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pDefInprocHandler, FALSE );
  146. dwBufSize = BUFF_SIZE;
  147. PutPropertySpecial ( hRecord, 9, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pArgument, FALSE );
  148. // safe operation
  149. // lenght of wcCLSID is 39 and lenght of wcQuery1 is BUFF_SIZE ( 512 )
  150. wcscpy(wcQuery1, L"select `RemoteName`, `Insertable` from Class where `CLSID`=\'");
  151. wcscat(wcQuery1, wcCLSID);
  152. wcscat(wcQuery1, L"\'");
  153. if((uiStatus = g_fpMsiDatabaseOpenViewW(msidata.GetDatabase (), wcQuery1, &hSView)) !=
  154. ERROR_BAD_QUERY_SYNTAX){
  155. CheckMSI(uiStatus);
  156. CheckMSI(g_fpMsiViewExecute(hSView, 0));
  157. try{
  158. uiStatus = g_fpMsiViewFetch(hSView, &hSRecord);
  159. if(uiStatus != ERROR_NO_MORE_ITEMS){
  160. CheckMSI(uiStatus);
  161. dwBufSize = BUFF_SIZE;
  162. PutPropertySpecial ( hSRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pRemoteName, FALSE );
  163. PutProperty(m_pObj, pInsertable, g_fpMsiRecordGetInteger(hSRecord, 2));
  164. }
  165. }catch(...){
  166. g_fpMsiViewClose(hSView);
  167. g_fpMsiCloseHandle(hSView);
  168. g_fpMsiCloseHandle(hSRecord);
  169. throw;
  170. }
  171. g_fpMsiViewClose(hSView);
  172. g_fpMsiCloseHandle(hSView);
  173. g_fpMsiCloseHandle(hSRecord);
  174. }
  175. //----------------------------------------------------
  176. if(bCheck) bMatch = true;
  177. if((atAction != ACTIONTYPE_GET) || bMatch){
  178. hr = pHandler->Indicate(1, &m_pObj);
  179. }
  180. }
  181. else
  182. {
  183. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  184. {
  185. dynBuffer [ 0 ] = NULL;
  186. }
  187. }
  188. m_pObj->Release();
  189. m_pObj = NULL;
  190. g_fpMsiCloseHandle(hRecord);
  191. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  192. }
  193. }
  194. }
  195. catch(...)
  196. {
  197. if ( dynBuffer )
  198. {
  199. delete [] dynBuffer;
  200. dynBuffer = NULL;
  201. }
  202. g_fpMsiCloseHandle(hRecord);
  203. g_fpMsiViewClose(hView);
  204. g_fpMsiCloseHandle(hView);
  205. msidata.CloseDatabase ();
  206. if(m_pObj)
  207. {
  208. m_pObj->Release();
  209. m_pObj = NULL;
  210. }
  211. throw;
  212. }
  213. g_fpMsiCloseHandle(hRecord);
  214. g_fpMsiViewClose(hView);
  215. g_fpMsiCloseHandle(hView);
  216. msidata.CloseDatabase ();
  217. }
  218. }
  219. if ( dynBuffer )
  220. {
  221. delete [] dynBuffer;
  222. dynBuffer = NULL;
  223. }
  224. return hr;
  225. }