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.

316 lines
8.8 KiB

  1. // ShortcutSAP.cpp: implementation of the CShortcutSAP class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include "ShortcutSAP.h"
  8. #include "ExtendString.h"
  9. #include "ExtendQuery.h"
  10. //////////////////////////////////////////////////////////////////////
  11. // Construction/Destruction
  12. //////////////////////////////////////////////////////////////////////
  13. CShortcutSAP::CShortcutSAP(CRequestObject *pObj, IWbemServices *pNamespace,
  14. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  15. {
  16. }
  17. CShortcutSAP::~CShortcutSAP()
  18. {
  19. }
  20. HRESULT CShortcutSAP::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  21. {
  22. HRESULT hr = WBEM_S_NO_ERROR;
  23. MSIHANDLE hView = NULL;
  24. MSIHANDLE hRecord = NULL;
  25. MSIHANDLE hSEView = NULL;
  26. MSIHANDLE hSERecord = NULL;
  27. int i = -1;
  28. WCHAR wcBuf[BUFF_SIZE];
  29. WCHAR wcCommand[BUFF_SIZE];
  30. WCHAR wcProductCode[39];
  31. #if !defined(_UNICODE)
  32. WCHAR wcTmp[BUFF_SIZE];
  33. #endif
  34. DWORD dwBufSize;
  35. bool bMatch = false;
  36. UINT uiStatus;
  37. WCHAR wcShortcut[BUFF_SIZE];
  38. WCHAR wcTestCode[39];
  39. bool bShortcut = false;
  40. CRequestObject *pActionData = NULL;
  41. if(atAction != ACTIONTYPE_ENUM)
  42. {
  43. // we are doing GetObject so we need to be reinitialized
  44. hr = WBEM_E_NOT_FOUND;
  45. int j;
  46. //GetObject optimizations
  47. CHeap_Exception he(CHeap_Exception::E_ALLOCATION_ERROR);
  48. for(j = 0; j < m_pRequest->m_iPropCount; j++){
  49. if(_wcsicmp(m_pRequest->m_Property[j], L"Action") == 0){
  50. pActionData = new CRequestObject();
  51. if(!pActionData) throw he;
  52. pActionData->Initialize(m_pNamespace);
  53. pActionData->ParsePath(m_pRequest->m_Value[j]);
  54. break;
  55. }
  56. }
  57. if(pActionData){
  58. for(j = 0; j < pActionData->m_iPropCount; j++){
  59. if(_wcsicmp(pActionData->m_Property[j], L"ActionID") == 0){
  60. if ( ::SysStringLen ( pActionData->m_Value[j] ) < BUFF_SIZE )
  61. {
  62. //Get the action we're looking for
  63. wcscpy(wcBuf, pActionData->m_Value[j]);
  64. // safe operation if wcslen ( wcBuf ) > 38
  65. if ( wcslen ( wcBuf ) > 38 )
  66. {
  67. wcscpy(wcTestCode, &(wcBuf[(wcslen(wcBuf) - 38)]));
  68. }
  69. else
  70. {
  71. // we are not good to go, they have sent us longer string
  72. throw hr;
  73. }
  74. // safe because lenght has been tested already in condition
  75. RemoveFinalGUID(pActionData->m_Value[j], wcShortcut);
  76. bShortcut = true;
  77. break;
  78. }
  79. else
  80. {
  81. // we are not good to go, they have sent us longer string
  82. throw hr;
  83. }
  84. }
  85. }
  86. pActionData->Cleanup();
  87. delete pActionData;
  88. pActionData = NULL;
  89. }
  90. }
  91. //These will change from class to class
  92. bool bDriver, bAttribute;
  93. CStringExt wcProp;
  94. Query wcQuery;
  95. wcQuery.Append ( 1, L"select distinct `Shortcut`, `Component_` from Shortcut" );
  96. //optimize for GetObject
  97. if ( bShortcut )
  98. {
  99. wcQuery.Append ( 3, L" where `Shortcut`=\'", wcShortcut, L"\'" );
  100. }
  101. QueryExt wcQuery1 ( L"select distinct `ComponentId` from Component where `Component`=\'" );
  102. LPWSTR Buffer = NULL;
  103. LPWSTR dynBuffer = NULL;
  104. DWORD dwDynBuffer = 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) ||
  111. (bShortcut && (_wcsicmp(wcTestCode, wcProductCode) == 0))){
  112. //Open our database
  113. try
  114. {
  115. if ( GetView ( &hView, wcProductCode, wcQuery, L"Shortcut", TRUE, FALSE ) )
  116. {
  117. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  118. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  119. CheckMSI(uiStatus);
  120. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  121. //----------------------------------------------------
  122. dwBufSize = BUFF_SIZE;
  123. GetBufferToPut ( hRecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  124. if ( Buffer && Buffer [ 0 ] != 0 )
  125. {
  126. // safe operation
  127. wcProp.Copy ( L"Win32_ShortcutAction.ActionID=\"" );
  128. wcProp.Append ( 3, Buffer, wcProductCode, L"\"" );
  129. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  130. {
  131. dynBuffer [ 0 ] = 0;
  132. }
  133. PutKeyProperty(m_pObj, pAction, wcProp, &bDriver, m_pRequest);
  134. dwBufSize = BUFF_SIZE;
  135. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  136. // make query on fly
  137. wcQuery1.Append ( 2, Buffer, L"\'" );
  138. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  139. {
  140. dynBuffer [ 0 ] = 0;
  141. }
  142. CheckMSI(g_fpMsiDatabaseOpenViewW( msidata.GetDatabase (), wcQuery1, &hSEView));
  143. CheckMSI(g_fpMsiViewExecute(hSEView, 0));
  144. try{
  145. uiStatus = g_fpMsiViewFetch(hSEView, &hSERecord);
  146. if(uiStatus != ERROR_NO_MORE_ITEMS){
  147. dwBufSize = BUFF_SIZE;
  148. GetBufferToPut ( hSERecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  149. if ( ValidateComponentID ( Buffer, wcProductCode ) )
  150. {
  151. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  152. {
  153. dynBuffer [ 0 ] = 0;
  154. }
  155. INSTALLSTATE piInstalled;
  156. dwBufSize = BUFF_SIZE;
  157. piInstalled = g_fpMsiGetComponentPathW(wcProductCode, wcBuf, wcCommand, &dwBufSize);
  158. if ( ( wcscmp(wcCommand, L"") != 0 ) &&
  159. (piInstalled != INSTALLSTATE_UNKNOWN) &&
  160. (piInstalled != INSTALLSTATE_ABSENT) )
  161. {
  162. if ( wcCommand [ dwBufSize-1 ] == L'\\' )
  163. {
  164. wcCommand [ dwBufSize-1 ] = L'\0';
  165. }
  166. wcBuf [ 0 ] = L'\0';
  167. EscapeStringW ( wcCommand, wcBuf );
  168. if ( wcBuf [ 0 ] != L'\0' )
  169. {
  170. // safe operation
  171. wcProp.Copy ( L"Win32_CommandLineAccess.Name=\"" );
  172. wcProp.Append ( 2, wcBuf, L"\"" );
  173. PutKeyProperty(m_pObj, pElement, wcProp, &bAttribute, m_pRequest);
  174. if(bDriver && bAttribute)
  175. {
  176. bMatch = true;
  177. }
  178. if((atAction != ACTIONTYPE_GET) || bMatch)
  179. {
  180. hr = pHandler->Indicate(1, &m_pObj);
  181. }
  182. }
  183. }
  184. }
  185. else
  186. {
  187. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  188. {
  189. dynBuffer [ 0 ] = 0;
  190. }
  191. }
  192. }
  193. }catch(...){
  194. g_fpMsiViewClose(hSEView);
  195. g_fpMsiCloseHandle(hSEView);
  196. g_fpMsiCloseHandle(hSERecord);
  197. throw;
  198. }
  199. g_fpMsiViewClose(hSEView);
  200. g_fpMsiCloseHandle(hSEView);
  201. g_fpMsiCloseHandle(hSERecord);
  202. }
  203. m_pObj->Release();
  204. m_pObj = NULL;
  205. g_fpMsiCloseHandle(hRecord);
  206. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  207. }
  208. }
  209. }
  210. catch(...)
  211. {
  212. if ( dynBuffer )
  213. {
  214. delete [] dynBuffer;
  215. dynBuffer = NULL;
  216. }
  217. g_fpMsiCloseHandle(hRecord);
  218. g_fpMsiViewClose(hView);
  219. g_fpMsiCloseHandle(hView);
  220. msidata.CloseDatabase ();
  221. if(m_pObj)
  222. {
  223. m_pObj->Release();
  224. m_pObj = NULL;
  225. }
  226. throw;
  227. }
  228. g_fpMsiCloseHandle(hRecord);
  229. g_fpMsiViewClose(hView);
  230. g_fpMsiCloseHandle(hView);
  231. msidata.CloseDatabase ();
  232. }
  233. }
  234. if ( dynBuffer )
  235. {
  236. delete [] dynBuffer;
  237. dynBuffer = NULL;
  238. }
  239. return hr;
  240. }