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.

371 lines
12 KiB

  1. // ExtensionInfoAction.cpp: implementation of the CExtensionInfoAction class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "ExtensionInfoAction.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CExtensionInfoAction::CExtensionInfoAction(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CExtensionInfoAction::~CExtensionInfoAction()
  18. {
  19. }
  20. HRESULT CExtensionInfoAction::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  21. {
  22. HRESULT hr = WBEM_S_NO_ERROR;
  23. MSIHANDLE hView = NULL;
  24. MSIHANDLE hVView = NULL;
  25. MSIHANDLE hSView = NULL;
  26. MSIHANDLE hMView = NULL;
  27. MSIHANDLE hRecord = NULL;
  28. MSIHANDLE hVRecord= NULL;
  29. MSIHANDLE hSRecord= NULL;
  30. MSIHANDLE hMRecord= NULL;
  31. int i = -1;
  32. WCHAR wcBuf[BUFF_SIZE];
  33. WCHAR wcExtension[BUFF_SIZE];
  34. WCHAR wcProductCode[39];
  35. DWORD dwBufSize;
  36. bool bMatch = false;
  37. UINT uiStatus;
  38. bool bGotID = false;
  39. WCHAR wcAction[BUFF_SIZE];
  40. WCHAR wcTestCode[39];
  41. //These will change from class to class
  42. bool bActionID;
  43. SetSinglePropertyPath(L"ActionID");
  44. //improve getobject performance by optimizing the query
  45. if(atAction != ACTIONTYPE_ENUM)
  46. {
  47. // we are doing GetObject so we need to be reinitialized
  48. hr = WBEM_E_NOT_FOUND;
  49. BSTR bstrCompare;
  50. int iPos = -1;
  51. bstrCompare = SysAllocString ( L"ActionID" );
  52. if ( bstrCompare )
  53. {
  54. if(FindIn(m_pRequest->m_Property, bstrCompare, &iPos))
  55. {
  56. if ( ::SysStringLen ( m_pRequest->m_Value[iPos] ) < BUFF_SIZE )
  57. {
  58. //Get the action we're looking for
  59. wcscpy(wcBuf, m_pRequest->m_Value[iPos]);
  60. // safe operation if wcslen ( wcBuf ) > 38
  61. if ( wcslen ( wcBuf ) > 38 )
  62. {
  63. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  64. }
  65. else
  66. {
  67. // we are not good to go, they have sent us longer string
  68. SysFreeString ( bstrCompare );
  69. throw hr;
  70. }
  71. // safe because lenght has been tested already in condition
  72. RemoveFinalGUID(m_pRequest->m_Value[iPos], wcAction);
  73. bGotID = true;
  74. }
  75. else
  76. {
  77. // we are not good to go, they have sent us longer string
  78. SysFreeString ( bstrCompare );
  79. throw hr;
  80. }
  81. }
  82. SysFreeString ( bstrCompare );
  83. }
  84. else
  85. {
  86. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  87. }
  88. }
  89. Query wcQuery;
  90. wcQuery.Append ( 1, L"select distinct `Extension`, `Component_`, `ProgId_` from Extension" );
  91. //optimize for GetObject
  92. if ( bGotID )
  93. {
  94. wcQuery.Append ( 3, L" where `Extension`=\'", wcAction, L"\'" );
  95. }
  96. QueryExt wcQuery1 ( L"select distinct `Verb`, `Command`, `Argument` from Verb where `Extension_`=\'" );
  97. QueryExt wcQuery2 ( L"select `ShellNew`, `ShellNewValue` from Extension where `Extension`=\'" );
  98. QueryExt wcQuery3 ( L"select `MIME_` from Extension where `Extension`=\'" );
  99. LPWSTR Buffer = NULL;
  100. LPWSTR dynBuffer = NULL;
  101. DWORD dwDynBuffer = 0L;
  102. LPWSTR BufExtension = NULL;
  103. LPWSTR dynBufExtension = NULL;
  104. DWORD dwdynBufExtension = 0L;
  105. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  106. {
  107. // safe operation:
  108. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  109. wcscpy(wcProductCode, m_pRequest->Package(i));
  110. if((atAction == ACTIONTYPE_ENUM) || (bGotID && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  111. //Open our database
  112. try
  113. {
  114. if ( GetView ( &hView, wcProductCode, wcQuery, L"Extension", TRUE, FALSE ) )
  115. {
  116. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  117. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  118. CheckMSI(uiStatus);
  119. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  120. //----------------------------------------------------
  121. dwBufSize = BUFF_SIZE;
  122. GetBufferToPut ( hRecord, 1, dwBufSize, wcExtension, dwdynBufExtension, dynBufExtension, BufExtension );
  123. PutProperty(m_pObj, pExtension, BufExtension);
  124. // make query on fly
  125. wcQuery1.Append ( 2, BufExtension, L"\'" );
  126. PutKeyProperty ( m_pObj, pActionID, BufExtension, &bActionID, m_pRequest, 1, wcProductCode );
  127. //====================================================
  128. dwBufSize = BUFF_SIZE;
  129. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  130. if ( ValidateComponentName ( msidata.GetDatabase (),
  131. wcProductCode,
  132. Buffer
  133. )
  134. )
  135. {
  136. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  137. {
  138. dynBuffer [ 0 ] = 0;
  139. }
  140. dwBufSize = BUFF_SIZE;
  141. PutPropertySpecial ( hRecord, 3, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, FALSE, 4, pProgID, pName, pCaption, pDescription );
  142. CheckMSI(g_fpMsiDatabaseOpenViewW(msidata.GetDatabase (), wcQuery1, &hVView));
  143. CheckMSI(g_fpMsiViewExecute(hVView, 0));
  144. try{
  145. uiStatus = g_fpMsiViewFetch(hVView, &hVRecord);
  146. if(uiStatus != ERROR_NO_MORE_ITEMS){
  147. CheckMSI(uiStatus);
  148. dwBufSize = BUFF_SIZE;
  149. PutPropertySpecial ( hVRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pVerb );
  150. dwBufSize = BUFF_SIZE;
  151. PutPropertySpecial ( hVRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pCommand );
  152. dwBufSize = BUFF_SIZE;
  153. PutPropertySpecial ( hVRecord, 3, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pArgument );
  154. }
  155. // make query on fly
  156. wcQuery2.Append ( 2, BufExtension, L"\'" );
  157. if((uiStatus = g_fpMsiDatabaseOpenViewW(msidata.GetDatabase (), wcQuery2, &hSView)) !=
  158. ERROR_BAD_QUERY_SYNTAX){
  159. CheckMSI(uiStatus);
  160. CheckMSI(g_fpMsiViewExecute(hSView, 0));
  161. try{
  162. uiStatus = g_fpMsiViewFetch(hSView, &hSRecord);
  163. if(uiStatus != ERROR_NO_MORE_ITEMS){
  164. CheckMSI(uiStatus);
  165. dwBufSize = BUFF_SIZE;
  166. PutPropertySpecial ( hSRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pShellNew );
  167. dwBufSize = BUFF_SIZE;
  168. PutPropertySpecial ( hSRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pShellNewValue );
  169. }
  170. }catch(...){
  171. g_fpMsiViewClose(hSView);
  172. g_fpMsiCloseHandle(hSView);
  173. g_fpMsiCloseHandle(hSRecord);
  174. throw;
  175. }
  176. g_fpMsiViewClose(hSView);
  177. g_fpMsiCloseHandle(hSView);
  178. g_fpMsiCloseHandle(hSRecord);
  179. }
  180. else
  181. {
  182. // make query on fly
  183. wcQuery3.Append ( 2, BufExtension, L"\'" );
  184. if((uiStatus = g_fpMsiDatabaseOpenViewW(msidata.GetDatabase (), wcQuery3, &hMView)) !=
  185. ERROR_BAD_QUERY_SYNTAX){
  186. CheckMSI(uiStatus);
  187. CheckMSI(g_fpMsiViewExecute(hMView, 0));
  188. try{
  189. uiStatus = g_fpMsiViewFetch(hMView, &hMRecord);
  190. if(uiStatus != ERROR_NO_MORE_ITEMS){
  191. CheckMSI(uiStatus);
  192. dwBufSize = BUFF_SIZE;
  193. PutPropertySpecial ( hMRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, pMIME );
  194. }
  195. }catch(...){
  196. g_fpMsiViewClose(hMView);
  197. g_fpMsiCloseHandle(hMView);
  198. g_fpMsiCloseHandle(hMRecord);
  199. throw;
  200. }
  201. g_fpMsiViewClose(hMView);
  202. g_fpMsiCloseHandle(hMView);
  203. g_fpMsiCloseHandle(hMRecord);
  204. }
  205. }
  206. if ( dynBufExtension && dynBufExtension [ 0 ] != 0 )
  207. {
  208. dynBufExtension [ 0 ] = 0;
  209. }
  210. }catch(...){
  211. g_fpMsiViewClose(hVView);
  212. g_fpMsiCloseHandle(hVView);
  213. g_fpMsiCloseHandle(hVRecord);
  214. throw;
  215. }
  216. g_fpMsiViewClose(hVView);
  217. g_fpMsiCloseHandle(hVView);
  218. g_fpMsiCloseHandle(hVRecord);
  219. //----------------------------------------------------
  220. if(bActionID) bMatch = true;
  221. if((atAction != ACTIONTYPE_GET) || bMatch){
  222. hr = pHandler->Indicate(1, &m_pObj);
  223. }
  224. }
  225. else
  226. {
  227. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  228. {
  229. dynBuffer [ 0 ] = 0;
  230. }
  231. }
  232. m_pObj->Release();
  233. m_pObj = NULL;
  234. g_fpMsiCloseHandle(hRecord);
  235. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  236. }
  237. }
  238. }
  239. catch(...)
  240. {
  241. if ( dynBuffer )
  242. {
  243. delete [] dynBuffer;
  244. dynBuffer = NULL;
  245. }
  246. if ( dynBufExtension )
  247. {
  248. delete [] dynBufExtension;
  249. dynBufExtension = NULL;
  250. }
  251. g_fpMsiCloseHandle(hRecord);
  252. g_fpMsiViewClose(hView);
  253. g_fpMsiCloseHandle(hView);
  254. msidata.CloseDatabase ();
  255. if(m_pObj)
  256. {
  257. m_pObj->Release();
  258. m_pObj = NULL;
  259. }
  260. throw;
  261. }
  262. g_fpMsiCloseHandle(hRecord);
  263. g_fpMsiViewClose(hView);
  264. g_fpMsiCloseHandle(hView);
  265. msidata.CloseDatabase ();
  266. }
  267. }
  268. if ( dynBuffer )
  269. {
  270. delete [] dynBuffer;
  271. dynBuffer = NULL;
  272. }
  273. if ( dynBufExtension )
  274. {
  275. delete [] dynBufExtension;
  276. dynBufExtension = NULL;
  277. }
  278. return hr;
  279. }