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.

1018 lines
29 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. MAINDLL.CPP
  5. Abstract:
  6. Contains DLL entry points. Also has code that controls
  7. when the DLL can be unloaded by tracking the number of
  8. objects and locks.
  9. History:
  10. a-davj 15-Aug-96 Created.
  11. --*/
  12. #include "precomp.h"
  13. #include <initguid.h>
  14. #include <wbemidl.h>
  15. #include <winver.h>
  16. #include <cominit.h>
  17. #include <wbemutil.h>
  18. #include <wbemprov.h>
  19. #include <wbemint.h>
  20. #include <stdio.h>
  21. #include <reg.h>
  22. #include <genutils.h>
  23. #include "comobj.h"
  24. #include "mofout.h"
  25. #include "mofcomp.h"
  26. #include "mofparse.h"
  27. #include "mofdata.h"
  28. #include "bmof.h"
  29. #include "cbmofout.h"
  30. #include "trace.h"
  31. #include "strings.h"
  32. #include <arrtempl.h>
  33. #include <helper.h>
  34. #include <autoptr.h>
  35. HINSTANCE ghModule;
  36. //***************************************************************************
  37. //
  38. // BOOL WINAPI DllMain
  39. //
  40. // DESCRIPTION:
  41. //
  42. // Entry point for DLL. Good place for initialization.
  43. //
  44. // PARAMETERS:
  45. //
  46. // hInstance instance handle
  47. // ulReason why we are being called
  48. // pvReserved reserved
  49. //
  50. // RETURN VALUE:
  51. //
  52. // TRUE if OK.
  53. //
  54. //***************************************************************************
  55. BOOL WINAPI DllMain(
  56. IN HINSTANCE hInstance,
  57. IN ULONG ulReason,
  58. LPVOID pvReserved)
  59. {
  60. if (DLL_PROCESS_DETACH == ulReason)
  61. {
  62. }
  63. else if (DLL_PROCESS_ATTACH == ulReason)
  64. {
  65. ghModule = hInstance;
  66. }
  67. return TRUE;
  68. }
  69. static ULONG g_cObj = 0;
  70. ULONG g_cLock = 0;
  71. void ObjectCreated()
  72. {
  73. InterlockedIncrement((LONG *) &g_cObj);
  74. }
  75. void ObjectDestroyed()
  76. {
  77. InterlockedDecrement((LONG *) &g_cObj);
  78. }
  79. //***************************************************************************
  80. //
  81. // STDAPI DllGetClassObject
  82. //
  83. // DESCRIPTION:
  84. //
  85. // Called when Ole wants a class factory. Return one only if it is the sort
  86. // of class this DLL supports.
  87. //
  88. // PARAMETERS:
  89. //
  90. // rclsid CLSID of the object that is desired.
  91. // riid ID of the desired interface.
  92. // ppv Set to the class factory.
  93. //
  94. // RETURN VALUE:
  95. //
  96. // S_OK all is well
  97. // E_FAILED not something we support
  98. //
  99. //***************************************************************************
  100. STDAPI DllGetClassObject(
  101. IN REFCLSID rclsid,
  102. IN REFIID riid,
  103. OUT LPVOID * ppv)
  104. {
  105. HRESULT hr = WBEM_E_FAILED;
  106. IClassFactory * pFactory = NULL;
  107. if (CLSID_WinmgmtMofCompiler == rclsid)
  108. pFactory = new CGenFactory<CWinmgmtMofComp>();
  109. else if (CLSID_MofCompiler == rclsid)
  110. pFactory = new CGenFactory<CMofComp>();
  111. else if (CLSID_MofCompilerOOP == rclsid)
  112. pFactory = new CGenFactory<CMofCompOOP>();
  113. if(pFactory == NULL)
  114. return E_FAIL;
  115. hr=pFactory->QueryInterface(riid, ppv);
  116. if (FAILED(hr))
  117. delete pFactory;
  118. return hr;
  119. }
  120. //***************************************************************************
  121. //
  122. // STDAPI DllCanUnloadNow
  123. //
  124. // DESCRIPTION:
  125. //
  126. // Answers if the DLL can be freed, that is, if there are no
  127. // references to anything this DLL provides.
  128. //
  129. // RETURN VALUE:
  130. //
  131. // S_OK if it is OK to unload
  132. // S_FALSE if still in use
  133. //
  134. //***************************************************************************
  135. STDAPI DllCanUnloadNow(void)
  136. {
  137. SCODE sc;
  138. //It is OK to unload if there are no objects or locks on the
  139. // class factory.
  140. sc=(0L==g_cObj && 0L==g_cLock) ? S_OK : S_FALSE;
  141. return sc;
  142. }
  143. //***************************************************************************
  144. //
  145. // DllRegisterServer
  146. //
  147. // Purpose: Called during setup or by regsvr32.
  148. //
  149. // Return: NOERROR if registration successful, error otherwise.
  150. //***************************************************************************
  151. STDAPI DllRegisterServer(void)
  152. {
  153. RegisterDLL(ghModule, CLSID_MofCompiler, __TEXT("MOF Compiler"), __TEXT("Both"), NULL);
  154. RegisterDLL(ghModule, CLSID_WinmgmtMofCompiler, __TEXT("Winmgmt MOF Compiler"), __TEXT("Both"), NULL);
  155. RegisterDllAppid(ghModule,CLSID_MofCompilerOOP,__TEXT("Winmgmt MOF Compiler OOP"),
  156. __TEXT("Both"),
  157. __TEXT("O:SYG:SYD:(D;;0x1;;;BU)(A;;0x1;;;SY)"),
  158. __TEXT("O:SYG:SYD:(D;;0x1;;;BU)(A;;0x1;;;SY)"));
  159. return NOERROR;
  160. }
  161. //***************************************************************************
  162. //
  163. // DllUnregisterServer
  164. //
  165. // Purpose: Called when it is time to remove the registry entries.
  166. //
  167. // Return: NOERROR if registration successful, error otherwise.
  168. //***************************************************************************
  169. STDAPI DllUnregisterServer(void)
  170. {
  171. UnRegisterDLL(CLSID_MofCompiler,NULL);
  172. UnRegisterDLL(CLSID_WinmgmtMofCompiler,NULL);
  173. UnregisterDllAppid(CLSID_MofCompilerOOP);
  174. return NOERROR;
  175. }
  176. //***************************************************************************
  177. //
  178. // bool IsValidMulti
  179. //
  180. // DESCRIPTION:
  181. //
  182. // Does a sanity check on a multstring.
  183. //
  184. // PARAMETERS:
  185. //
  186. // pMultStr Multistring to test.
  187. // dwSize size of multistring
  188. //
  189. // RETURN:
  190. //
  191. // true if OK
  192. //
  193. //***************************************************************************
  194. bool IsValidMulti(TCHAR * pMultStr, DWORD dwSize)
  195. {
  196. if(pMultStr && dwSize >= 2 && pMultStr[dwSize-2]==0 && pMultStr[dwSize-1]==0)
  197. return true;
  198. return false;
  199. }
  200. //***************************************************************************
  201. //
  202. // bool IsStringPresent
  203. //
  204. // DESCRIPTION:
  205. //
  206. // Searches a multstring for the presense of a string.
  207. //
  208. // PARAMETERS:
  209. //
  210. // pTest String to look for.
  211. // pMultStr Multistring to test.
  212. //
  213. // RETURN:
  214. //
  215. // true if string is found
  216. //
  217. //***************************************************************************
  218. bool IsStringPresent(TCHAR * pTest, TCHAR * pMultStr)
  219. {
  220. TCHAR * pTemp;
  221. for(pTemp = pMultStr; *pTemp; pTemp += lstrlen(pTemp) + 1)
  222. if(!lstrcmpi(pTest, pTemp))
  223. return true;
  224. return false;
  225. }
  226. //***************************************************************************
  227. //
  228. // void AddToAutoRecoverList
  229. //
  230. // DESCRIPTION:
  231. //
  232. // Adds the file to the autocompile list, if it isnt already on it.
  233. //
  234. // PARAMETERS:
  235. //
  236. // pFileName File to add
  237. //
  238. //***************************************************************************
  239. void AddToAutoRecoverList(TCHAR * pFileName)
  240. {
  241. TCHAR cFullFileName[MAX_PATH+1];
  242. TCHAR * lpFile;
  243. DWORD dwSize;
  244. TCHAR * pNew = NULL;
  245. TCHAR * pTest;
  246. DWORD dwNewSize = 0;
  247. DWORD dwNumChar = 0;
  248. // Get the full file name
  249. long lRet = GetFullPathName(pFileName, MAX_PATH, cFullFileName, &lpFile);
  250. if(lRet == 0)
  251. return;
  252. bool bFound = false;
  253. Registry r(WBEM_REG_WINMGMT);
  254. TCHAR *pMulti = r.GetMultiStr(TEXT("Autorecover MOFs"), dwSize);
  255. dwNumChar = dwSize / sizeof(TCHAR);
  256. // Ignore the empty string case
  257. if(dwSize == 1)
  258. {
  259. delete pMulti;
  260. pMulti = NULL;
  261. }
  262. if(pMulti)
  263. {
  264. CDeleteMe<TCHAR> dm(pMulti);
  265. if(!IsValidMulti(pMulti, dwNumChar))
  266. {
  267. return; // bail out, messed up multistring
  268. }
  269. bFound = IsStringPresent(cFullFileName, pMulti);
  270. if(!bFound)
  271. {
  272. // The registry entry does exist, but doesnt have this name
  273. // Make a new multistring with the file name at the end
  274. dwNewSize = dwNumChar + lstrlen(cFullFileName) + 1;
  275. pNew = new TCHAR[dwNewSize];
  276. if(!pNew)
  277. return;
  278. memcpy(pNew, pMulti, dwSize);
  279. // Find the double null
  280. for(pTest = pNew; pTest[0] || pTest[1]; pTest++); // intentional semi
  281. // Tack on the path and ensure a double null;
  282. pTest++;
  283. StringCchCopyW(pTest, dwNewSize - (pTest - pNew), cFullFileName);
  284. pTest+= lstrlen(cFullFileName)+1;
  285. *pTest = 0; // add second numm
  286. }
  287. }
  288. else
  289. {
  290. // The registry entry just doesnt exist. Create it with a value equal to our name
  291. dwNewSize = lstrlen(cFullFileName) + 2; // note extra char for double null
  292. pNew = new TCHAR[dwNewSize];
  293. if(!pNew)
  294. return;
  295. StringCchCopyW(pNew, dwNewSize, cFullFileName);
  296. pTest = pNew + lstrlen(pNew) + 1;
  297. *pTest = 0; // add second null
  298. }
  299. if(pNew)
  300. {
  301. r.SetMultiStr(TEXT("Autorecover MOFs"), pNew, dwNewSize*sizeof(TCHAR));
  302. delete pNew;
  303. }
  304. FILETIME ftCurTime;
  305. LARGE_INTEGER liCurTime;
  306. TCHAR szBuff[50];
  307. GetSystemTimeAsFileTime(&ftCurTime);
  308. liCurTime.LowPart = ftCurTime.dwLowDateTime;
  309. liCurTime.HighPart = ftCurTime.dwHighDateTime;
  310. _ui64tow(liCurTime.QuadPart, szBuff, 10);
  311. r.SetStr(TEXT("Autorecover MOFs timestamp"), szBuff);
  312. }
  313. //
  314. //
  315. ////////////////////////////////////////////////
  316. VOID inline Hex2Char(BYTE Byte,TCHAR * &pOut)
  317. {
  318. BYTE HiNibble = (Byte&0xF0) >> 4;
  319. BYTE LoNibble = Byte & 0xF;
  320. *pOut = (HiNibble<10)?(__TEXT('0')+HiNibble):(__TEXT('A')+HiNibble-10);
  321. pOut++;
  322. *pOut = (LoNibble<10)?(__TEXT('0')+LoNibble):(__TEXT('A')+LoNibble-10);
  323. pOut++;
  324. }
  325. // returns "string" representation of a buffer as a HEX number
  326. VOID Buffer2String(BYTE * pStart,DWORD dwSize,TCHAR * pOut)
  327. {
  328. for (DWORD i=0;i<dwSize;i++) Hex2Char(pStart[i],pOut);
  329. }
  330. //
  331. // given the pathname d:\folder1\folder2\foo.mof
  332. // it returns
  333. // ppHash = MD5 Hash of the UPPERCASE UNICODE Path + '.mof'
  334. // call delete [] on return values
  335. //
  336. //////////////////////////////////////////////
  337. DWORD ComposeName(WCHAR * pFullLongName, WCHAR **ppHash)
  338. {
  339. if (NULL == ppHash ) return ERROR_INVALID_PARAMETER;
  340. DWORD dwLen = wcslen(pFullLongName);
  341. WCHAR * pConvert = pFullLongName;
  342. for (DWORD i=0;i<dwLen;i++) pConvert[i] = wbem_towupper(pConvert[i]);
  343. wmilib::auto_buffer<WCHAR> pHash(new WCHAR[32 + 4 + 1]);
  344. if (NULL == pHash.get()) return ERROR_OUTOFMEMORY;
  345. MD5 md5;
  346. BYTE aSignature[16];
  347. md5.Transform( pFullLongName, dwLen * sizeof(WCHAR), aSignature );
  348. Buffer2String(aSignature,16,pHash.get());
  349. StringCchCopy(&pHash[32],5 ,__TEXT(".mof"));
  350. *ppHash = pHash.release();
  351. return ERROR_SUCCESS;
  352. }
  353. DWORD g_FileSD[] = {
  354. 0x80040001, 0x00000000, 0x00000000, 0x00000000,
  355. 0x00000014, 0x00340002, 0x00000002, 0x00140000,
  356. FILE_ALL_ACCESS, 0x00000101, 0x05000000, 0x00000012,
  357. 0x00180000, FILE_ALL_ACCESS, 0x00000201, 0x05000000,
  358. 0x00000020, 0x00000220
  359. };
  360. //
  361. //
  362. // pFileName is already assumed to be the full path
  363. //
  364. /////////////////////////////////////////////////////
  365. DWORD
  366. CopyFileToAutorecover(TCHAR * pFileNameRegistry, TCHAR * pFileNameAutoRecover,BOOL bIsBMOF)
  367. {
  368. // get the AutoRecover
  369. HKEY hKey;
  370. LONG lRet;
  371. lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE,WBEM_REG_WINMGMT,0,
  372. KEY_READ,&hKey);
  373. if (ERROR_SUCCESS != lRet) return lRet;
  374. OnDelete<HKEY,LONG(*)(HKEY),RegCloseKey> cmReg(hKey);
  375. DWORD dwType;
  376. DWORD dwReq = 0;
  377. lRet = RegQueryValueExW(hKey,L"Working Directory",0,
  378. &dwType,NULL,&dwReq);
  379. if (!(ERROR_SUCCESS == lRet && REG_EXPAND_SZ == dwType)) return lRet;
  380. if (0 == dwReq ) return lRet;
  381. wmilib::auto_buffer<WCHAR> pWorkDir(new WCHAR[dwReq /sizeof(WCHAR)]);
  382. if (NULL == pWorkDir.get()) return ERROR_OUTOFMEMORY;
  383. lRet = RegQueryValueExW(hKey,L"Working Directory",0,
  384. &dwType,(BYTE *)pWorkDir.get(),&dwReq);
  385. if (ERROR_SUCCESS != lRet || REG_EXPAND_SZ != dwType) return lRet;
  386. DWORD cchReq = ExpandEnvironmentStrings(pWorkDir.get(),NULL,0);
  387. size_t cchTot = cchReq + sizeof("\\AutoRecover\\") + 4 + 32 + 1;
  388. wmilib::auto_buffer<WCHAR> pWorkDirExpand(new WCHAR[cchTot]);
  389. if (NULL == pWorkDirExpand.get()) return ERROR_OUTOFMEMORY;
  390. ExpandEnvironmentStrings(pWorkDir.get(),pWorkDirExpand.get(),cchTot);
  391. WCHAR * pHashedName = NULL;
  392. lRet = ComposeName(pFileNameRegistry,&pHashedName);
  393. if (ERROR_SUCCESS != lRet) return lRet;
  394. wmilib::auto_buffer<WCHAR> DelMe(pHashedName);
  395. StringCchCat(pWorkDirExpand.get(),cchTot,L"\\AutoRecover\\");
  396. StringCchCat(pWorkDirExpand.get(),cchTot,pHashedName);
  397. HANDLE hSrcFile = CreateFile(pFileNameAutoRecover,GENERIC_READ,FILE_SHARE_READ,NULL,
  398. OPEN_EXISTING,0,NULL);
  399. if (INVALID_HANDLE_VALUE == hSrcFile) return GetLastError();
  400. OnDelete<HANDLE,BOOL(*)(HANDLE),CloseHandle> cmSrc(hSrcFile);
  401. DWORD dwSize = GetFileSize(hSrcFile,NULL);
  402. HANDLE hFileMapSrc = CreateFileMapping(hSrcFile,
  403. NULL,
  404. PAGE_READONLY,
  405. 0,0, // the entire file
  406. NULL);
  407. if (NULL == hFileMapSrc) return GetLastError();
  408. OnDelete<HANDLE,BOOL(*)(HANDLE),CloseHandle> cmMapSrc(hFileMapSrc);
  409. VOID * pData = MapViewOfFile(hFileMapSrc,FILE_MAP_READ,0,0,0);
  410. if (NULL == pData) return GetLastError();
  411. OnDelete<PVOID,BOOL(*)(LPCVOID),UnmapViewOfFile> UnMap(pData);
  412. SECURITY_ATTRIBUTES SecAttr = {sizeof(SecAttr),g_FileSD,FALSE};
  413. HANDLE hDest = CreateFile(pWorkDirExpand.get(),GENERIC_WRITE,0,&SecAttr,
  414. CREATE_ALWAYS,0,NULL);
  415. if (INVALID_HANDLE_VALUE == hDest) return GetLastError();
  416. OnDelete<HANDLE,BOOL(*)(HANDLE),CloseHandle> cmDest(hDest);
  417. DWORD dwWritten;
  418. if (!bIsBMOF)
  419. {
  420. WORD UnicodeSign = 0xFEFF;
  421. if (FALSE == WriteFile(hDest,&UnicodeSign,sizeof(UnicodeSign),&dwWritten,NULL)) return GetLastError();
  422. }
  423. if (FALSE == WriteFile(hDest,pData,dwSize,&dwWritten,NULL)) return GetLastError();
  424. return ERROR_SUCCESS;
  425. }
  426. //***************************************************************************
  427. //
  428. // void AddToAutoRecoverList2
  429. //
  430. // DESCRIPTION:
  431. //
  432. // The intent is to add to the AutoRecover List
  433. // first of all, create a copy of the pre-processed file into the AutoRecover Folder
  434. // the file name will the the MD5 hash of the uppercase FULL name
  435. // Adds the file to the autocompile list, if it isnt already on it.
  436. //
  437. //
  438. // PARAMETERS:
  439. //
  440. // pFileName File to add
  441. //
  442. //***************************************************************************
  443. void AddToAutoRecoverList2(TCHAR * pFileName,
  444. TCHAR * pAutoRecoverFileName,
  445. BOOL CopyFileOnly,
  446. BOOL bIsBMOF)
  447. {
  448. TCHAR cFullFileName[MAX_PATH+1];
  449. TCHAR * lpFile;
  450. DWORD dwSize;
  451. TCHAR * pNew = NULL;
  452. TCHAR * pTest;
  453. DWORD dwNewSize = 0;
  454. DWORD dwNumChar = 0;
  455. // Get the full file name
  456. long lRet = GetFullPathName(pFileName, MAX_PATH, cFullFileName, &lpFile);
  457. if(lRet == 0)
  458. return;
  459. if (ERROR_SUCCESS != (lRet = CopyFileToAutorecover(cFullFileName,pAutoRecoverFileName,bIsBMOF)))
  460. {
  461. ERRORTRACE((LOG_MOFCOMP,"Error %d adding file %S to AutoRecover",lRet,pFileName));
  462. return;
  463. }
  464. if (CopyFileOnly) return;
  465. bool bFound = false;
  466. Registry r(WBEM_REG_WINMGMT);
  467. TCHAR *pMulti = r.GetMultiStr(TEXT("Autorecover MOFs"), dwSize);
  468. dwNumChar = dwSize / sizeof(TCHAR);
  469. // Ignore the empty string case
  470. if(dwSize == 1)
  471. {
  472. delete pMulti;
  473. pMulti = NULL;
  474. }
  475. if(pMulti)
  476. {
  477. CDeleteMe<TCHAR> dm(pMulti);
  478. if(!IsValidMulti(pMulti, dwNumChar))
  479. {
  480. return; // bail out, messed up multistring
  481. }
  482. bFound = IsStringPresent(cFullFileName, pMulti);
  483. if(!bFound)
  484. {
  485. // The registry entry does exist, but doesnt have this name
  486. // Make a new multistring with the file name at the end
  487. dwNewSize = dwNumChar + lstrlen(cFullFileName) + 1;
  488. pNew = new TCHAR[dwNewSize];
  489. if(!pNew)
  490. return;
  491. memcpy(pNew, pMulti, dwSize);
  492. // Find the double null
  493. for(pTest = pNew; pTest[0] || pTest[1]; pTest++); // intentional semi
  494. // Tack on the path and ensure a double null;
  495. pTest++;
  496. StringCchCopy(pTest,dwNewSize - (pTest - pNew),cFullFileName);
  497. pTest+= lstrlen(cFullFileName)+1;
  498. *pTest = 0; // add second numm
  499. }
  500. }
  501. else
  502. {
  503. // The registry entry just doesnt exist. Create it with a value equal to our name
  504. dwNewSize = lstrlen(cFullFileName) + 2; // note extra char for double null
  505. pNew = new TCHAR[dwNewSize];
  506. if(!pNew)
  507. return;
  508. StringCchCopy(pNew,dwNewSize,cFullFileName);
  509. pTest = pNew + lstrlen(pNew) + 1;
  510. *pTest = 0; // add second null
  511. }
  512. if(pNew)
  513. {
  514. r.SetMultiStr(TEXT("Autorecover MOFs"), pNew, dwNewSize*sizeof(TCHAR));
  515. delete pNew;
  516. }
  517. FILETIME ftCurTime;
  518. LARGE_INTEGER liCurTime;
  519. TCHAR szBuff[50];
  520. GetSystemTimeAsFileTime(&ftCurTime);
  521. liCurTime.LowPart = ftCurTime.dwLowDateTime;
  522. liCurTime.HighPart = ftCurTime.dwHighDateTime;
  523. _ui64tow(liCurTime.QuadPart, szBuff, 10);
  524. r.SetStr(TEXT("Autorecover MOFs timestamp"), szBuff);
  525. }
  526. //***************************************************************************
  527. //
  528. // int Trace
  529. //
  530. // DESCRIPTION:
  531. //
  532. // Allows for the output function (printf in this case) to be overridden.
  533. //
  534. // PARAMETERS:
  535. //
  536. // *fmt format string. Ex "%s hello %d"
  537. // ... argument list. Ex cpTest, 23
  538. //
  539. // RETURN VALUE:
  540. //
  541. // size of output in characters.
  542. //***************************************************************************
  543. int Trace(bool bError, PDBG pDbg,DWORD dwID, ...)
  544. {
  545. IntString is(dwID);
  546. TCHAR * fmt = is;
  547. TCHAR *buffer = new TCHAR[2048];
  548. if(buffer == NULL)
  549. return 0;
  550. char *buffer2 = new char[4096];
  551. if(buffer2 == NULL)
  552. {
  553. delete buffer;
  554. return 0;
  555. }
  556. va_list argptr;
  557. int cnt;
  558. va_start(argptr, dwID);
  559. cnt = StringCchVPrintfW(buffer, 2048, fmt, argptr);
  560. va_end(argptr);
  561. CharToOem(buffer, buffer2);
  562. if(pDbg && pDbg->m_bPrint)
  563. printf("%s", buffer2);
  564. if(bError)
  565. ERRORTRACE((LOG_MOFCOMP,"%s", buffer2));
  566. else
  567. DEBUGTRACE((LOG_MOFCOMP,"%s", buffer2));
  568. delete buffer;
  569. delete buffer2;
  570. return cnt;
  571. }
  572. //***************************************************************************
  573. //
  574. // HRESULT StoreBMOF
  575. //
  576. // DESCRIPTION:
  577. //
  578. // This stores the intermediate data as a BINARY MOF instead of storing it to
  579. // the WBEM database.
  580. //
  581. // PARAMETERS:
  582. //
  583. // pObjects The intermediate data
  584. // bWMICheck If true, the the wmi checker program is automatically started
  585. // BMOFFileName file name to store the data to.
  586. //
  587. // RETURN VALUE:
  588. //
  589. // 0 if OK, otherwise an error code
  590. //
  591. //***************************************************************************
  592. HRESULT StoreBMOF(CMofParser & Parser, CPtrArray * pObjects, BOOL bWMICheck, LPTSTR BMOFFileName, PDBG pDbg)
  593. {
  594. int i;
  595. {
  596. CBMOFOut BMof(BMOFFileName, pDbg);
  597. // Go through all the objects and add them to the database
  598. // =======================================================
  599. for(i = 0; i < pObjects->GetSize(); i++)
  600. {
  601. CMObject* pObject = (CMObject*)(*pObjects)[i];
  602. pObject->Reflate(Parser);
  603. BMof.AddClass(pObject, FALSE); // possibly add to the BMOF output buffer
  604. pObject->Deflate(false);
  605. }
  606. if(!BMof.WriteFile())
  607. {
  608. return WBEM_E_FAILED;
  609. }
  610. }
  611. if(bWMICheck)
  612. {
  613. PROCESS_INFORMATION pi;
  614. STARTUPINFO si;
  615. si.cb = sizeof(si);
  616. si.lpReserved = 0;
  617. si.lpDesktop = NULL;
  618. si.lpTitle = NULL;
  619. si.dwFlags = 0;
  620. si.cbReserved2 = 0;
  621. si.lpReserved2 = 0;
  622. TCHAR App[MAX_PATH];
  623. StringCchCopyW(App, MAX_PATH, TEXT("wmimofck "));
  624. StringCchCatW(App, MAX_PATH, BMOFFileName);
  625. BOOL bRes = CreateProcess(NULL,
  626. App,
  627. NULL,
  628. NULL,
  629. FALSE,
  630. 0,
  631. NULL,
  632. NULL,
  633. &si,
  634. &pi);
  635. if(bRes == 0)
  636. {
  637. DWORD dwError = GetLastError();
  638. Trace(true, pDbg, WMI_LAUNCH_ERROR, dwError);
  639. return dwError;
  640. }
  641. }
  642. return WBEM_NO_ERROR;
  643. }
  644. void SetInfo(WBEM_COMPILE_STATUS_INFO *pInfo, long lPhase, HRESULT hRes)
  645. {
  646. if(pInfo)
  647. {
  648. pInfo->lPhaseError = lPhase;
  649. pInfo->hRes = hRes;
  650. }
  651. }
  652. HRESULT ExtractAmendment(CMofParser & Parser, WCHAR * wszBmof)
  653. {
  654. // if this is being used for splitting, then possibly get the amendment value
  655. // It would be passed in the wszBmof string and would be found after
  656. // the characters ",a". For example, the string might be ",aMS_409,fFileName.mof"
  657. if(wszBmof == NULL || wszBmof[0] != L',')
  658. return S_OK; // not a problem, is usual case
  659. // make a copy of the string
  660. DWORD dwLen = wcslen(wszBmof)+1;
  661. WCHAR *pTemp = new WCHAR[dwLen];
  662. if(pTemp == NULL)
  663. return WBEM_E_OUT_OF_MEMORY;
  664. CDeleteMe<WCHAR> dm1(pTemp);
  665. StringCchCopyW(pTemp, dwLen, wszBmof);
  666. // use wcstok to do a seach
  667. WCHAR * token = wcstok( pTemp, L"," );
  668. while( token != NULL )
  669. {
  670. if(token[0] == L'a')
  671. {
  672. return Parser.SetAmendment(token+1);
  673. }
  674. token = wcstok( NULL, L"," );
  675. }
  676. return S_OK;
  677. }
  678. SCODE Compile(CMofParser & Parser, IWbemServices *pOverride, IWbemContext * pCtx,
  679. long lOptionFlags, long lClassFlags, long lInstanceFlags,
  680. WCHAR * wszDefault, WCHAR *UserName, WCHAR *pPassword , WCHAR *Authority,
  681. WCHAR * wszBmof, bool bInProc, WBEM_COMPILE_STATUS_INFO *pInfo)
  682. {
  683. // do flag validity check
  684. if((lOptionFlags & WBEM_FLAG_DONT_ADD_TO_LIST) && (lOptionFlags & WBEM_FLAG_AUTORECOVER))
  685. {
  686. SetInfo(pInfo, 1, WBEM_E_INVALID_PARAMETER);
  687. return S_FALSE;
  688. }
  689. long lValid = WBEM_FLAG_DONT_ADD_TO_LIST | WBEM_FLAG_AUTORECOVER |
  690. WBEM_FLAG_CHECK_ONLY | WBEM_FLAG_WMI_CHECK |
  691. WBEM_FLAG_SPLIT_FILES | WBEM_FLAG_CONSOLE_PRINT |
  692. WBEM_FLAG_CONNECT_REPOSITORY_ONLY | WBEM_FLAG_CONNECT_PROVIDERS;
  693. if(lOptionFlags & ~lValid)
  694. {
  695. SetInfo(pInfo, 1, WBEM_E_INVALID_PARAMETER);
  696. return S_FALSE;
  697. }
  698. // Init buffers for command line args.
  699. // ===================================
  700. HRESULT hres;
  701. // This scope is defined so that the local variables, such as the PARSE
  702. // object are destroyed before CoUninitialize is called.
  703. TCHAR cBMOFOutputName[MAX_PATH] = TEXT("");
  704. if(wszBmof)
  705. CopyOrConvert(cBMOFOutputName, wszBmof, MAX_PATH);
  706. // Parse command line arguments
  707. // ============================
  708. BOOL bCheckOnly = lOptionFlags & WBEM_FLAG_CHECK_ONLY;
  709. BOOL bWMICheck = lOptionFlags & WBEM_FLAG_WMI_CHECK;
  710. bool bAutoRecover = (lOptionFlags & WBEM_FLAG_AUTORECOVER) != 0;
  711. if(wszDefault && wcslen(wszDefault) > 0)
  712. {
  713. hres = Parser.SetDefaultNamespace(wszDefault);
  714. if(FAILED(hres))
  715. return hres;
  716. }
  717. hres = ExtractAmendment(Parser, wszBmof);
  718. if(FAILED(hres))
  719. return hres;
  720. Parser.SetOtherDefaults(lClassFlags, lInstanceFlags, bAutoRecover);
  721. if(!Parser.Parse())
  722. {
  723. int nLine = 0, nCol = 0, nError;
  724. TCHAR Msg[1000];
  725. WCHAR * pErrorFile = NULL;
  726. if(Parser.GetErrorInfo(Msg, 1000, &nLine, &nCol, &nError, &pErrorFile))
  727. Trace(true, Parser.GetDbg(), ERROR_SYNTAX, pErrorFile, nLine, nError, //nLine+1,
  728. Msg);
  729. SetInfo(pInfo, 2, nError);
  730. return S_FALSE;
  731. }
  732. Parser.SetToNotScopeCheck();
  733. // Autorecover is not compatible with certain flags
  734. if( ((lOptionFlags & WBEM_FLAG_DONT_ADD_TO_LIST) == 0 ) &&
  735. (Parser.GetAutoRecover() || bAutoRecover) &&
  736. ((lInstanceFlags & ~WBEM_FLAG_OWNER_UPDATE) || (lClassFlags & ~WBEM_FLAG_OWNER_UPDATE) ||
  737. (wszDefault && wszDefault[0] != 0) || Parser.GetRemotePragmaPaths()))
  738. {
  739. Trace(true, Parser.GetDbg(), INVALID_AUTORECOVER);
  740. SetInfo(pInfo, 1, 0);
  741. return S_FALSE;
  742. }
  743. Trace(false, Parser.GetDbg(), SUCCESS);
  744. if(bCheckOnly)
  745. {
  746. Trace(false, Parser.GetDbg(), SYNTAX_CHECK_COMPLETE);
  747. SetInfo(pInfo, 0, 0);
  748. return S_OK;
  749. }
  750. CMofData* pData = Parser.AccessOutput();
  751. if((lstrlen(cBMOFOutputName) > 0 && (lOptionFlags & WBEM_FLAG_SPLIT_FILES)) ||
  752. Parser.GetAmendment())
  753. {
  754. hres = pData->Split(Parser, wszBmof, pInfo, Parser.IsUnicode(), Parser.GetAutoRecover(),
  755. Parser.GetAmendment());
  756. if(hres != S_OK)
  757. {
  758. SetInfo(pInfo, 3, hres);
  759. return S_FALSE;
  760. }
  761. else
  762. {
  763. SetInfo(pInfo, 0, 0);
  764. return S_OK;
  765. }
  766. }
  767. else if(lstrlen(cBMOFOutputName))
  768. {
  769. if(Parser.IsntBMOFCompatible())
  770. {
  771. Trace(true, Parser.GetDbg(), BMOF_INCOMPATIBLE);
  772. SetInfo(pInfo, 3, WBEM_E_INVALID_PARAMETER);
  773. return S_FALSE;
  774. }
  775. Trace(false, Parser.GetDbg(), STORING_BMOF, cBMOFOutputName);
  776. CPtrArray * pObjArray = pData->GetObjArrayPtr();
  777. SCODE sc = StoreBMOF(Parser, pObjArray, bWMICheck, cBMOFOutputName, Parser.GetDbg());
  778. if(sc != S_OK)
  779. {
  780. SetInfo(pInfo, 3, sc);
  781. return S_FALSE;
  782. }
  783. else
  784. {
  785. SetInfo(pInfo, 0, 0);
  786. return S_OK;
  787. }
  788. }
  789. IWbemLocator* pLocator = NULL;
  790. hres = CoCreateInstance(
  791. (bInProc) ? CLSID_WbemAdministrativeLocator : CLSID_WbemLocator,
  792. NULL, CLSCTX_ALL, IID_IWbemLocator,
  793. (void**)&pLocator);
  794. if(FAILED(hres))
  795. {
  796. SetInfo(pInfo, 3, hres);
  797. return S_FALSE;
  798. }
  799. Trace(false, Parser.GetDbg(), STORING_DATA);
  800. hres = pData->Store(Parser, pLocator, pOverride, TRUE,UserName, pPassword , Authority, pCtx,
  801. (bInProc) ? CLSID_WbemAdministrativeLocator : CLSID_WbemLocator,
  802. pInfo,
  803. lClassFlags & WBEM_FLAG_OWNER_UPDATE,
  804. lInstanceFlags & WBEM_FLAG_OWNER_UPDATE,
  805. lOptionFlags & (WBEM_FLAG_CONNECT_PROVIDERS|WBEM_FLAG_CONNECT_REPOSITORY_ONLY));
  806. if(pLocator != NULL)
  807. pLocator->Release();
  808. if(hres != S_OK)
  809. {
  810. SetInfo(pInfo, 3, hres);
  811. return S_FALSE;
  812. }
  813. else
  814. {
  815. if(Parser.GetFileName() && wcslen(Parser.GetFileName()))
  816. ERRORTRACE((LOG_MOFCOMP,"Finished compiling file:%ls\n", Parser.GetFileName()));
  817. _variant_t VarDoStore = false;
  818. BOOL OverrideAutoRecover = FALSE;
  819. if (pCtx) pCtx->GetValue(L"__MOFD_DO_STORE",0,&VarDoStore);
  820. if (VT_BOOL == V_VT(&VarDoStore) && (VARIANT_TRUE == V_BOOL(&VarDoStore)))
  821. {
  822. OverrideAutoRecover = TRUE;
  823. }
  824. if(Parser.GetAutoRecover() || OverrideAutoRecover)
  825. {
  826. if(lOptionFlags & WBEM_FLAG_DONT_ADD_TO_LIST)
  827. {
  828. if(pInfo)
  829. pInfo->dwOutFlags |= AUTORECOVERY_REQUIRED;
  830. }
  831. //Call MOF Compiler with (pszMofs);
  832. _variant_t Var = false;
  833. if (pCtx) pCtx->GetValue(L"__MOFD_NO_STORE",0,&Var);
  834. if (VT_BOOL == V_VT(&Var) && (VARIANT_TRUE == V_BOOL(&Var)))
  835. {
  836. }
  837. else
  838. {
  839. AddToAutoRecoverList2(Parser.GetFileName(),
  840. Parser.GetAutoRecoverFileName(),
  841. lOptionFlags & WBEM_FLAG_DONT_ADD_TO_LIST,
  842. Parser.IsBMOF());
  843. }
  844. }
  845. SetInfo(pInfo, 0, 0);
  846. return S_OK;
  847. }
  848. }