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.

295 lines
8.8 KiB

  1. // CommandLineAccess.cpp: implementation of the CCommandLineAccess class.
  2. //
  3. // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
  4. //
  5. //////////////////////////////////////////////////////////////////////
  6. #include "precomp.h"
  7. #include <tchar.h>
  8. #include "CommandLineAccess.h"
  9. #include "ExtendString.h"
  10. #include "ExtendQuery.h"
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. CCommandLineAccess::CCommandLineAccess(CRequestObject *pObj, IWbemServices *pNamespace,
  15. IWbemContext *pCtx):CGenericClass(pObj, pNamespace, pCtx)
  16. {
  17. }
  18. CCommandLineAccess::~CCommandLineAccess()
  19. {
  20. }
  21. HRESULT CCommandLineAccess::CreateObject(IWbemObjectSink *pHandler, ACTIONTYPE atAction)
  22. {
  23. HRESULT hr = WBEM_S_NO_ERROR;
  24. MSIHANDLE hView = NULL;
  25. MSIHANDLE hRecord = NULL;
  26. MSIHANDLE hSEView = NULL;
  27. MSIHANDLE hSERecord = NULL;
  28. int i = -1;
  29. WCHAR wcBuf[BUFF_SIZE];
  30. WCHAR wcQuery1[BUFF_SIZE];
  31. WCHAR wcCommand[BUFF_SIZE];
  32. WCHAR *wcDone[MSI_MAX_APPLICATIONS];
  33. WCHAR wcProductCode[39];
  34. #if !defined(_UNICODE)
  35. WCHAR wcTmp[BUFF_SIZE];
  36. #endif
  37. DWORD dwBufSize;
  38. bool bMatch = false;
  39. UINT uiStatus;
  40. TCHAR cBuf[MAX_COMPUTERNAME_LENGTH + 1];
  41. //These will change from class to class
  42. bool bName, bRepeat;
  43. INSTALLSTATE piInstalled;
  44. if ( atAction != ACTIONTYPE_ENUM )
  45. {
  46. // we are doing GetObject so we need to be reinitialized
  47. hr = WBEM_E_NOT_FOUND;
  48. }
  49. Initialize(wcDone);
  50. // safe operation
  51. // lenght is smaller than BUFF_SIZE ( 512 )
  52. wcscpy(wcQuery1, L"select distinct `Shortcut`, `Component_`, `Arguments` from Shortcut");
  53. QueryExt wcQuery ( L"select distinct `ComponentId` from Component where `Component`=\'" );
  54. LPWSTR Buffer = NULL;
  55. LPWSTR dynBuffer = NULL;
  56. DWORD dwDynBuffer = 0L;
  57. while(!bMatch && m_pRequest->Package(++i) && (hr != WBEM_E_CALL_CANCELLED))
  58. {
  59. // safe operation:
  60. // Package ( i ) returns NULL ( tested above ) or valid WCHAR [39]
  61. wcscpy(wcProductCode, m_pRequest->Package(i));
  62. //Open our database
  63. try
  64. {
  65. if ( GetView ( &hView, wcProductCode, wcQuery1, L"Shortcut", TRUE, FALSE ) )
  66. {
  67. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  68. while(!bMatch && (uiStatus != ERROR_NO_MORE_ITEMS) && (hr != WBEM_E_CALL_CANCELLED)){
  69. CheckMSI(uiStatus);
  70. bRepeat = false;
  71. if(FAILED(hr = SpawnAnInstance(&m_pObj))) throw hr;
  72. //----------------------------------------------------
  73. PutProperty(m_pObj, pCreationClassName, L"Win32_CommandLineAccess");
  74. PutProperty(m_pObj, pSystemCreationClassName, L"Win32_ComputerSystem");
  75. dwBufSize = MAX_COMPUTERNAME_LENGTH+1;
  76. if(!GetComputerName(cBuf, &dwBufSize)) throw WBEM_E_FAILED;
  77. #ifndef UNICODE
  78. WCHAR wcComputer[MAX_COMPUTERNAME_LENGTH + 1];
  79. mbstowcs(wcComputer, cBuf, MAX_COMPUTERNAME_LENGTH + 1);
  80. PutProperty(m_pObj, pSystemName, wcComputer);
  81. #else UNICODE
  82. PutProperty(m_pObj, pSystemName, cBuf);
  83. #endif UNICODE
  84. //====================================================
  85. dwBufSize = BUFF_SIZE;
  86. GetBufferToPut ( hRecord, 2, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  87. // make query on fly
  88. wcQuery.Append ( 2, Buffer, L"\'" );
  89. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  90. {
  91. dynBuffer [ 0 ] = 0;
  92. }
  93. CheckMSI(g_fpMsiDatabaseOpenViewW(msidata.GetDatabase (), wcQuery, &hSEView));
  94. CheckMSI(g_fpMsiViewExecute(hSEView, 0));
  95. try{
  96. uiStatus = g_fpMsiViewFetch(hSEView, &hSERecord);
  97. if(uiStatus != ERROR_NO_MORE_ITEMS){
  98. dwBufSize = BUFF_SIZE;
  99. GetBufferToPut ( hSERecord, 1, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  100. if ( ValidateComponentID ( Buffer, wcProductCode ) )
  101. {
  102. dwBufSize = BUFF_SIZE;
  103. piInstalled = g_fpMsiGetComponentPathW(wcProductCode, Buffer, wcCommand, &dwBufSize);
  104. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  105. {
  106. dynBuffer [ 0 ] = 0;
  107. }
  108. if ( (wcscmp(wcCommand, L"") != 0) &&
  109. (piInstalled != INSTALLSTATE_UNKNOWN) &&
  110. (piInstalled != INSTALLSTATE_ABSENT) )
  111. {
  112. if ( wcCommand [ dwBufSize-1 ] == L'\\' )
  113. {
  114. wcCommand [ dwBufSize-1 ] = L'\0';
  115. }
  116. int i = 0;
  117. while(wcDone[i]){
  118. if(wcscmp(wcDone[i], wcCommand) == 0){
  119. bRepeat = true;
  120. break;
  121. }
  122. i++;
  123. }
  124. if(!bRepeat){
  125. if ( ( wcDone[i] = new WCHAR [ wcslen ( wcCommand ) + 1 ] ) == NULL )
  126. {
  127. Cleanup(wcDone);
  128. throw CHeap_Exception(CHeap_Exception::E_ALLOCATION_ERROR);
  129. }
  130. wcscpy(wcDone[i], wcCommand);
  131. }
  132. PutKeyProperty(m_pObj, pName, wcCommand, &bName, m_pRequest);
  133. PutProperty(m_pObj, pCaption, wcCommand);
  134. PutProperty(m_pObj, pDescription, wcCommand);
  135. dwBufSize = BUFF_SIZE;
  136. GetBufferToPut ( hRecord, 3, dwBufSize, wcBuf, dwDynBuffer, dynBuffer, Buffer );
  137. if ( Buffer && Buffer [0] != 0 )
  138. {
  139. PutProperty ( m_pObj, pCommandLine, wcCommand, 2, L" ", Buffer );
  140. }
  141. else
  142. {
  143. PutProperty(m_pObj, pCommandLine, wcCommand);
  144. }
  145. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  146. {
  147. dynBuffer [ 0 ] = 0;
  148. }
  149. //----------------------------------------------------
  150. if(bName) bMatch = true;
  151. if(((atAction != ACTIONTYPE_GET) || bMatch) && !bRepeat){
  152. hr = pHandler->Indicate(1, &m_pObj);
  153. }
  154. }
  155. }
  156. else
  157. {
  158. if ( dynBuffer && dynBuffer [ 0 ] != 0 )
  159. {
  160. dynBuffer [ 0 ] = 0;
  161. }
  162. }
  163. }
  164. }catch(...){
  165. g_fpMsiCloseHandle(hSERecord);
  166. g_fpMsiViewClose(hSEView);
  167. g_fpMsiCloseHandle(hSEView);
  168. throw;
  169. }
  170. if(m_pObj){
  171. m_pObj->Release();
  172. m_pObj = NULL;
  173. }
  174. g_fpMsiCloseHandle(hSERecord);
  175. g_fpMsiViewClose(hSEView);
  176. g_fpMsiCloseHandle(hSEView);
  177. g_fpMsiCloseHandle(hRecord);
  178. uiStatus = g_fpMsiViewFetch(hView, &hRecord);
  179. }
  180. }
  181. }
  182. catch(...)
  183. {
  184. if ( dynBuffer )
  185. {
  186. delete [] dynBuffer;
  187. dynBuffer = NULL;
  188. }
  189. g_fpMsiCloseHandle(hRecord);
  190. g_fpMsiViewClose(hView);
  191. g_fpMsiCloseHandle(hView);
  192. msidata.CloseDatabase ();
  193. if(m_pObj){
  194. m_pObj->Release();
  195. m_pObj = NULL;
  196. }
  197. Cleanup(wcDone);
  198. throw;
  199. }
  200. g_fpMsiCloseHandle(hRecord);
  201. g_fpMsiViewClose(hView);
  202. g_fpMsiCloseHandle(hView);
  203. msidata.CloseDatabase ();
  204. }
  205. if ( dynBuffer )
  206. {
  207. delete [] dynBuffer;
  208. dynBuffer = NULL;
  209. }
  210. Cleanup(wcDone);
  211. return hr;
  212. }
  213. void CCommandLineAccess::Cleanup(WCHAR * wcList[])
  214. {
  215. int i = 0;
  216. while(wcList[i]) delete wcList[i++];
  217. }
  218. void CCommandLineAccess::Initialize(WCHAR * wcList[])
  219. {
  220. for(int i = 0; i < MSI_MAX_APPLICATIONS; i++) wcList[i] = NULL;
  221. }