Source code of Windows XP (NT5)
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.

640 lines
16 KiB

  1. //-----------------------------------------------------------------------------
  2. //
  3. // File: Sampres.CPP
  4. //
  5. // Implementation of the sample CRecObj
  6. //
  7. // Copyright (c) 1995 - 1997, Microsoft Corporation. All rights reserved.
  8. //
  9. //-----------------------------------------------------------------------------
  10. #include "stdafx.h"
  11. #include "resource.h"
  12. #include "impbin.h"
  13. #include "impresob.h"
  14. #include "sampres.h"
  15. #include "dllvars.h"
  16. #include <parseman.h>
  17. #include "misc.h"
  18. #include <bmfmisc.h>
  19. //
  20. //Local helper functions
  21. //
  22. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  23. //
  24. // Constructor and member data init
  25. //
  26. //------------------------------------------------------------------------------
  27. CSampleResObj::CSampleResObj(
  28. CLocItem *pLocItem,
  29. DWORD dwSize,
  30. void *pvHeader)
  31. {
  32. m_dwSize = dwSize;
  33. m_pvHeader = pvHeader;
  34. m_pLocItem = pLocItem;
  35. m_fKeepLocItems = FALSE;
  36. }
  37. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  38. // Cleanup for CSampleResObj
  39. //
  40. //
  41. //-----------------------------------------------------------------------------
  42. CSampleResObj::~CSampleResObj()
  43. {
  44. if (m_pvHeader)
  45. {
  46. delete m_pvHeader;
  47. }
  48. if (!m_fKeepLocItems)
  49. {
  50. delete m_pLocItem;
  51. }
  52. //TODO: any special processing
  53. }
  54. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  55. // If it is more efficient to read and write this resounce together
  56. // during a generate then return TRUE here
  57. //------------------------------------------------------------------------------
  58. BOOL
  59. CSampleResObj::CanReadWrite()
  60. {
  61. return TRUE;
  62. }
  63. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  64. // TODO: Implement if you return TRUE from CanReadWrite
  65. //------------------------------------------------------------------------------
  66. BOOL
  67. CSampleResObj::ReadWrite(
  68. C32File* p32FileSrc,
  69. C32File* p32FileTgt)
  70. {
  71. return ReadWriteHelper(p32FileSrc, p32FileTgt, TRUE);
  72. }
  73. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  74. //
  75. // Read the resource from native format and build CLocItems
  76. //
  77. //------------------------------------------------------------------------------
  78. BOOL
  79. CSampleResObj::Read(C32File *p32File)
  80. {
  81. return ReadWriteHelper(p32File, NULL, FALSE);
  82. }
  83. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  84. // Write the resource items
  85. //------------------------------------------------------------------------------
  86. BOOL
  87. CSampleResObj::Write(C32File *)
  88. {
  89. LTASSERT(0 && "CSampleResObj::Write is not implemented");
  90. return FALSE;
  91. }
  92. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  93. // Create a short form res header for use with the Res Editor
  94. // The only information that is important is the Type and Res Id
  95. //------------------------------------------------------------------------------
  96. void
  97. CSampleResObj::MakeRes32Header(LangId nLangId)
  98. {
  99. if (m_pvHeader)
  100. {
  101. delete m_pvHeader;
  102. m_pvHeader = NULL;
  103. }
  104. //TODO: If the type ID of this object is not the same
  105. //as the type of Win32 type you want, set it do some other
  106. //Win32 type and set ESP_CHAR_USEARRAYVALUE
  107. //
  108. //
  109. //Example...
  110. //CLocTypeId lIDDialog;
  111. //lIDDialog.SetLocTypeId((DWORD)RT_DIALOG);
  112. //m_pvHeader = W32MakeRes32Header(lIDDialog,
  113. m_pvHeader = W32MakeRes32Header(m_pLocItem->GetUniqueId().GetTypeId(),
  114. m_pLocItem->GetUniqueId().GetResId(),
  115. nLangId,
  116. ESP_CHAR_USEARRAYVALUE);
  117. //The ESP_CHAR_USEARRAYVALUE constant tells Win32 to use
  118. //the values from the real Locitem when cracking the resource
  119. //instead of using the ID from the res file.
  120. }
  121. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  122. // Set the buffer size
  123. //------------------------------------------------------------------------------
  124. void
  125. CSampleResObj::SetBufferSize(DWORD dwSize)
  126. {
  127. m_dwSize = dwSize;
  128. }
  129. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  130. // Return the loc item
  131. //------------------------------------------------------------------------------
  132. CLocItem*
  133. CSampleResObj::GetLocItem()
  134. {
  135. return m_pLocItem;
  136. }
  137. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  138. // Return the keep item state
  139. //------------------------------------------------------------------------------
  140. BOOL
  141. CSampleResObj::IsKeepLocItems()
  142. {
  143. return m_fKeepLocItems;
  144. }
  145. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  146. // Set the keep item state
  147. //------------------------------------------------------------------------------
  148. void
  149. CSampleResObj::SetKeepLocItems(BOOL fKeep)
  150. {
  151. m_fKeepLocItems = fKeep;
  152. }
  153. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  154. // Read the resource from Res32 format
  155. //------------------------------------------------------------------------------
  156. BOOL
  157. CSampleResObj::ReadRes32(C32File *p32File)
  158. {
  159. //TODO: if your file formats are different than
  160. // RES32 then do unique processing here.
  161. return Read(p32File);
  162. }
  163. //-----------------------------------------------------------------------------
  164. //
  165. // Worker function to read or write the ini file
  166. //
  167. //-----------------------------------------------------------------------------
  168. BOOL
  169. CSampleResObj::ReadWriteHelper(
  170. C32File* SourceFile,
  171. C32File* TargetFile,
  172. BOOL GenerateTarget
  173. )
  174. /*++
  175. Routine Description:
  176. Helper routine for resource object read and write routines
  177. Arguments:
  178. SourceFile is the source file object. This has the original
  179. resource data.
  180. TargetFile is the target file object. The localized information
  181. will be written into this file. If fGenerate is FALSE then
  182. p32FileTgt is NULL
  183. GenerateTarget is TRUE then a localized resource will be generated
  184. Return Value:
  185. TRUE if successful else FALSE
  186. --*/
  187. {
  188. BOOL ReturnStatus = TRUE;
  189. TCHAR TempPath[MAX_PATH];
  190. TCHAR SourceMofFile[MAX_PATH];
  191. TCHAR EnglishMofFile[MAX_PATH];
  192. CFileSpec fs;
  193. CPascalString pasTempFileSrc;
  194. TCHAR TargetMofFile[MAX_PATH];
  195. TCHAR TargetBmfFile[MAX_PATH];
  196. CLocLangId langIdTgt;
  197. try
  198. {
  199. //
  200. // Read in the resource from the source so that we can generate
  201. // the corresponding unicode text mof from it and then hand off
  202. // the text mof to the WBEM MFL parser.
  203. //
  204. CByteArray baResource;
  205. baResource.SetSize(m_dwSize);
  206. if (m_dwSize != SourceFile->Read(baResource.GetData(), m_dwSize))
  207. {
  208. AfxThrowFileException(CFileException::endOfFile);
  209. }
  210. //
  211. // Create a temp file to generate the unicode mof text
  212. //
  213. if (0 == GetTempPath(MAX_PATH, TempPath))
  214. {
  215. AfxThrowUserException();
  216. }
  217. if (0 == GetTempFileName(TempPath, _T("mof"), 0, SourceMofFile))
  218. {
  219. AfxThrowUserException();
  220. }
  221. if (GenerateTarget)
  222. {
  223. if (0 == GetTempFileName(TempPath, _T("mof"), 0, EnglishMofFile))
  224. {
  225. AfxThrowUserException();
  226. }
  227. } else {
  228. *EnglishMofFile = 0;
  229. }
  230. //
  231. // Generate MOF from baResource into a temp file
  232. //
  233. if (ConvertBmfToMof(baResource.GetData(),
  234. SourceMofFile,
  235. EnglishMofFile))
  236. {
  237. #if 0
  238. OutputDebugString(SourceMofFile);
  239. OutputDebugString("\n");
  240. OutputDebugString(EnglishMofFile);
  241. OutputDebugString("\n");
  242. DebugBreak();
  243. #endif
  244. //
  245. // Leverage the WMI MOF loc parser to do the hard work
  246. //
  247. pasTempFileSrc.SetString(SourceMofFile,
  248. strlen(SourceMofFile),
  249. CP_ACP);
  250. fs.SetFileName(pasTempFileSrc);
  251. fs.SetFileId(SourceFile->GetFileDBID());
  252. SmartRef<ILocFile> scIniFile;
  253. BOOL bFile = CLocParserManager::GetLocFile(fs,
  254. pidWMI,
  255. ftUnknown,
  256. scIniFile,
  257. *SourceFile->GetHandler());
  258. if (bFile)
  259. {
  260. // Set the parent node in the unique ID of the item
  261. SetParent(m_pLocItem, SourceFile);
  262. m_pLocItem->SetIconType(CIT::Expandable);
  263. m_pLocItem->SetFDisplayable(TRUE);
  264. m_pLocItem->SetFExpandable(TRUE);
  265. CLocItemSet setItems(FALSE);
  266. setItems.Add(m_pLocItem);
  267. if (!SourceFile->GetHandler()->HandleItemSet(setItems))
  268. {
  269. //Espresso failed the update - this could be due to
  270. //duplicate IDs, user clicking cancel, or other reasons.
  271. //Just throw an exception, destructors will do all
  272. //the clean up
  273. ThrowItemSetException();
  274. }
  275. LTASSERT(!scIniFile.IsNull());
  276. CLocLangId langIdSrc;
  277. langIdSrc.SetLanguageId(SourceFile->GetLangId());
  278. if (GenerateTarget)
  279. {
  280. //
  281. // We need to generate a localized binary mof. First we
  282. // generate the unicode MOF text from the WMI loc
  283. // parser and then convert it back into binary into
  284. // another file. Finally we read the binary mof and
  285. // write it into the resource.
  286. //
  287. langIdTgt.SetLanguageId(TargetFile->GetLangId());
  288. if (0 == GetTempFileName(TempPath,
  289. _T("mof"),
  290. 0,
  291. TargetMofFile))
  292. {
  293. AfxThrowUserException();
  294. }
  295. CPascalString pasTempFileTgt;
  296. pasTempFileTgt.SetString(TargetMofFile,
  297. strlen(TargetMofFile),
  298. CP_ACP);
  299. BOOL bGen = scIniFile->GenerateFile(pasTempFileTgt,
  300. *SourceFile->GetHandler(),
  301. langIdSrc,
  302. langIdTgt,
  303. m_pLocItem->GetMyDatabaseId());
  304. if (bGen)
  305. {
  306. //
  307. // Generate the BMF from the localized unicode text MOF
  308. //
  309. if (0 == GetTempFileName(TempPath, _T("bmf"), 0,
  310. TargetBmfFile))
  311. {
  312. AfxThrowUserException();
  313. }
  314. //
  315. // Do MOF to binary mof conversion
  316. //
  317. if (ConvertMofToBmf(TargetMofFile,
  318. EnglishMofFile,
  319. TargetBmfFile))
  320. {
  321. CPascalString pasTempFileBmfTgt;
  322. pasTempFileBmfTgt.SetString(TargetBmfFile,
  323. strlen(TargetBmfFile),
  324. CP_ACP);
  325. //
  326. // Copy the BMF information from the binary mof
  327. // file and into the resource
  328. //
  329. CFile fTemp;
  330. fTemp.Open(TargetBmfFile, CFile::modeRead);
  331. CByteArray baData;
  332. int nDataLen = fTemp.GetLength();
  333. baData.SetSize(nDataLen);
  334. fTemp.Read(baData.GetData(), nDataLen);
  335. fTemp.Close();
  336. TargetFile->PreWriteResource(this);
  337. TargetFile->Write(baData.GetData(), nDataLen);
  338. TargetFile->PostWriteResource(this);
  339. } else {
  340. TargetFile->SetDelayedFailure(TRUE);
  341. }
  342. CFile::Remove(TargetBmfFile);
  343. CFile::Remove(TargetMofFile);
  344. } else {
  345. TargetFile->SetDelayedFailure(TRUE);
  346. }
  347. }
  348. else
  349. {
  350. if (!scIniFile->EnumerateFile(*SourceFile->GetHandler(),
  351. langIdSrc, m_pLocItem->GetMyDatabaseId()))
  352. {
  353. SourceFile->SetDelayedFailure(TRUE);
  354. }
  355. }
  356. scIniFile->Release();
  357. scIniFile.Extract();
  358. }
  359. else
  360. {
  361. // Issue some message about the parser not being there
  362. CContext ctx(g_hDll, IDS_IMP_PARSER_DESC,
  363. SourceFile->GetFileDBID(), otFile, vProjWindow);
  364. SourceFile->GetHandler()->IssueMessage(esError, ctx,
  365. g_hDll, IDS_NO_INI_PARSE);
  366. // TODO if you want to fail the update because of this reason
  367. // set bRet to FALSE and change the IssueMessage to be
  368. // esError instead of esWarning.
  369. ReturnStatus = FALSE;
  370. }
  371. } else {
  372. ReturnStatus = FALSE;
  373. }
  374. CFile::Remove(SourceMofFile);
  375. }
  376. catch (CException* pE)
  377. {
  378. ReturnStatus = FALSE;
  379. ReportException(pE, TargetFile, m_pLocItem, SourceFile->GetHandler());
  380. pE->Delete();
  381. }
  382. return(ReturnStatus);
  383. }
  384. //
  385. //TODO: Remove if not needed
  386. //
  387. //Example function to set the parent ID from
  388. //a display node.
  389. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  390. // Set the parent item.
  391. // The C32File is holding on to a Map of Ids to CLocItems for us.
  392. //
  393. //-----------------------------------------------------------------------------
  394. void
  395. CSampleResObj::SetParent(
  396. CLocItem* pLocItem,
  397. C32File* pFile)
  398. {
  399. //TODO: Change to the real parser ID
  400. CLocItem* pParentItem = (CLocItem*)pFile->GetSubData(pidBMOF);
  401. if (pParentItem != NULL)
  402. {
  403. LTASSERTONLY(pParentItem->AssertValid());
  404. pLocItem->GetUniqueId().SetParentId(pParentItem->GetMyDatabaseId());
  405. }
  406. else
  407. {
  408. //need to create and send one
  409. CPascalString pasStrName;
  410. pasStrName = L"Binary MOF";
  411. SmartPtr<CLocItem> spParentItem = new CLocItem;
  412. CLocUniqueId uid;
  413. uid.GetResId().SetId(pasStrName);
  414. uid.GetTypeId().SetId((ULONG)0);
  415. uid.SetParentId(pFile->GetMasterDBID());
  416. spParentItem->SetUniqueId(uid);
  417. spParentItem->SetFDisplayable(TRUE);
  418. spParentItem->SetFNoResTable(TRUE);
  419. spParentItem->SetIconType(CIT::Expandable);
  420. spParentItem->SetFExpandable(TRUE);
  421. CLocItemSet itemSet(FALSE);
  422. itemSet.Add(spParentItem.GetPointer());
  423. BOOL bHandle = pFile->GetHandler()->HandleItemSet(itemSet);
  424. if (!bHandle)
  425. {
  426. LTTRACE("Dummy Node value not handled");
  427. ThrowItemSetException();
  428. }
  429. pLocItem->GetUniqueId().SetParentId(spParentItem->GetMyDatabaseId());
  430. pFile->SetSubData(pidBMOF, spParentItem.Extract());
  431. }
  432. }
  433. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  434. // Write the object in Res32 Format
  435. //------------------------------------------------------------------------------
  436. BOOL
  437. CSampleResObj::WriteRes32(C32File *p32File)
  438. {
  439. //TODO: if your file formats are different than
  440. // RES32 then do unique processing here.
  441. return Write(p32File);
  442. }
  443. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  444. // Read the items passed and hold onto them.
  445. //
  446. //------------------------------------------------------------------------------
  447. BOOL
  448. CSampleResObj::ReadRgLocItem(CLocItemPtrArray * pRgLocItem, int nSelItem)
  449. {
  450. UNREFERENCED_PARAMETER(pRgLocItem);
  451. UNREFERENCED_PARAMETER(nSelItem);
  452. m_fKeepLocItems = TRUE; //The loc items don't belong to us
  453. //TODO save the items if needed.
  454. return TRUE;
  455. }
  456. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  457. // update the loc items in the array with the data from the loc items
  458. // in this object.
  459. // Only the coordinants and the tab order are copied.
  460. //
  461. // The dialog is always the first item in the array.
  462. //
  463. // The Win32 parser calls this function in responce to CrackRes32Image
  464. //------------------------------------------------------------------------------
  465. BOOL
  466. CSampleResObj::WriteRgLocItem(
  467. CLocItemPtrArray * pRgLocItem,
  468. CReporter*)
  469. {
  470. UNREFERENCED_PARAMETER(pRgLocItem);
  471. BOOL bRet = TRUE;
  472. try
  473. {
  474. LTASSERT(0 != pRgLocItem->GetSize());
  475. //TODO: implement
  476. //Transfer the binary from my item to the database item.
  477. pRgLocItem->GetAt(0)->TransferBinary(m_pLocItem);
  478. }
  479. catch (...)
  480. {
  481. bRet = FALSE;
  482. }
  483. return bRet;
  484. }
  485. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  486. // Return Buffer pointer
  487. //------------------------------------------------------------------------------
  488. const void*
  489. CSampleResObj::GetBufferPointer(void)
  490. {
  491. return m_pvHeader;
  492. }
  493. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  494. // Return buffer size
  495. //------------------------------------------------------------------------------
  496. DWORD
  497. CSampleResObj::GetBufferSize(void)
  498. {
  499. return m_dwSize;
  500. }
  501. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  502. // Get mnemonics in resource
  503. //------------------------------------------------------------------------------
  504. BOOL
  505. CSampleResObj::GetMnemonics(
  506. CMnemonicsMap &, /*mapMnemonics*/
  507. CReporter* ) //pReporter
  508. {
  509. return TRUE;
  510. }
  511. //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  512. //
  513. // Assert the object is valid
  514. //
  515. //------------------------------------------------------------------------------
  516. void
  517. CSampleResObj::AssertValid(void) const
  518. {
  519. #ifdef LTASSERT_ACTIVE
  520. CObject::AssertValid();
  521. LTASSERT(m_dwSize > 0);
  522. LTASSERT(m_pvHeader != NULL);
  523. LTASSERT(m_pLocItem != NULL);
  524. //TODO any other asserts?
  525. #endif
  526. }