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.

484 lines
13 KiB

  1. ////////////////////////////////////////
  2. // token.cpp
  3. ////////////////////////////////////////
  4. //
  5. // This file handle all the token strings
  6. //
  7. ////////////////////////////////////////
  8. #include "token.h"
  9. #include "main.h"
  10. extern CMainApp theApp;
  11. #define MAX_TOKEN 8192
  12. CToken::CToken()
  13. {
  14. m_uiTypeID = 0;
  15. m_uiResID = 0;
  16. m_uiItemID = 0;
  17. m_uiFlags = 0;
  18. m_uiStatusFlags = 0;
  19. m_uiLastError = 0;
  20. m_strItemName = "";
  21. m_strSrcText = "";
  22. m_strTgtText = "";
  23. }
  24. int CToken::Parse(CString strSrc, CString strTgt)
  25. {
  26. CString strSrcTokenID;
  27. int pos;
  28. if(!strSrc.IsEmpty())
  29. {
  30. pos = strSrc.Find('=');
  31. if(pos==-1)
  32. {
  33. theApp.WriteCon(CONERR, "Invalid token [equal sign missing]\t%s\r\n", strSrc);
  34. theApp.SetReturn(ERROR_RET_INVALID_TOKEN);
  35. return CMainApp::ERR_TOKEN_WRONGFORMAT;
  36. }
  37. strSrcTokenID = strSrc.Left(pos-3);
  38. m_strSrcText = strSrc.Right(strSrc.GetLength()-++pos);
  39. pos = m_strSrcText.Find('\n');
  40. if(pos!=-1)
  41. m_strSrcText = m_strSrcText.Left(pos);
  42. }
  43. else
  44. m_strSrcText = "";
  45. pos = strTgt.Find('=');
  46. if(pos==-1)
  47. {
  48. theApp.WriteCon(CONERR, "Invalid token [equal sign missing]\t%s\r\n", strTgt);
  49. theApp.SetReturn(ERROR_RET_INVALID_TOKEN);
  50. return CMainApp::ERR_TOKEN_WRONGFORMAT;
  51. }
  52. if(pos<=3)
  53. {
  54. theApp.WriteCon(CONERR, "Invalid token [token corruption]\t%s\r\n", strTgt);
  55. theApp.SetReturn(ERROR_RET_INVALID_TOKEN);
  56. return CMainApp::ERR_TOKEN_WRONGFORMAT;
  57. }
  58. m_strTokenID = strTgt.Left(pos-3);
  59. m_strTgtText = strTgt.Right(strTgt.GetLength()-++pos);
  60. //pos = m_strTgtText.Find('\n');
  61. //if(pos!=-1)
  62. // m_strTgtText = m_strTgtText.Left(pos);
  63. //
  64. // On FE platforms, "Find" could not find the
  65. // ending \n when the last char is a High ansi because it is leadbyte.
  66. char * pStr = m_strTgtText.GetBuffer(0);
  67. pos = 0;
  68. while (*pStr){
  69. if(*pStr == '\n'){
  70. m_strTgtText = m_strTgtText.Left(pos);
  71. break;
  72. }
  73. if (IsDBCSLeadByteEx(theApp.GetUICodePage(), *pStr))
  74. {
  75. pos+=2;
  76. }
  77. else
  78. {
  79. pos++;
  80. }
  81. pStr = CharNextExA((WORD)theApp.GetUICodePage(), pStr, 0);
  82. }
  83. if(5>sscanf(m_strTokenID, TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]"),
  84. &m_uiTypeID,
  85. &m_uiResID,
  86. &m_uiItemID,
  87. &m_uiFlags,
  88. &m_uiStatusFlags,
  89. m_strItemName.GetBuffer(128)))
  90. {
  91. theApp.WriteCon(CONERR, "Invalid token [not enough arguments converted]\t%s\"]]\r\n", m_strTokenID);
  92. theApp.SetReturn(ERROR_RET_INVALID_TOKEN);
  93. return CMainApp::ERR_TOKEN_WRONGFORMAT;
  94. }
  95. // Special case the Menu Popup
  96. if(m_uiTypeID==4 && (m_uiFlags & ISPOPUP)==ISPOPUP && (m_uiFlags & OLD_POPUP_ID)==OLD_POPUP_ID)
  97. {
  98. m_uiItemID = MAKELONG( 0xFFFF, LOWORD(m_uiItemID) );
  99. }
  100. m_strItemName.ReleaseBuffer();
  101. m_strItemName = m_strTokenID.Mid(m_strTokenID.Find("|\"")+2);
  102. if(!strSrc.IsEmpty())
  103. {
  104. // Perform a consistency check on the token files
  105. unsigned int uiTypeID = 0;
  106. unsigned int uiResID = 0;
  107. unsigned int uiItemID = 0;
  108. unsigned int uiFlags = 0;
  109. unsigned int uiStatusFlags = 0;
  110. CString strItemName = "";
  111. sscanf(strSrcTokenID, TEXT("[[%u|%u|%u|%u|%u|\"%s\"]]"),
  112. &uiTypeID,
  113. &uiResID,
  114. &uiItemID,
  115. &uiFlags,
  116. &uiStatusFlags,
  117. strItemName.GetBuffer(128));
  118. strItemName.ReleaseBuffer();
  119. strItemName = strSrcTokenID.Mid(strSrcTokenID.Find("|\"")+2);
  120. // Special case the Menu Popup
  121. if(uiTypeID==4 && (uiFlags & ISPOPUP)==ISPOPUP && (m_uiFlags & OLD_POPUP_ID)==OLD_POPUP_ID)
  122. {
  123. uiItemID = MAKELONG( 0xFFFF, LOWORD(uiItemID) );
  124. }
  125. // Compare token ID
  126. if(!((uiTypeID == m_uiTypeID) &&
  127. (uiResID == m_uiResID) &&
  128. (uiItemID == m_uiItemID) &&
  129. (uiFlags == m_uiFlags) &&
  130. (strItemName == m_strItemName)))
  131. {
  132. theApp.WriteCon(CONERR, "Token ID mismatch\t%s\"]]\t%s\"]]\r\n", strSrcTokenID.GetBuffer(0), m_strTokenID.GetBuffer(0));
  133. theApp.SetReturn(ERROR_RET_TOKEN_MISMATCH);
  134. return CMainApp::ERR_TOKEN_MISMATCH;
  135. }
  136. }
  137. return 0;
  138. }
  139. BOOL CToken::GetTgtSize(WORD * px, WORD * py,WORD * pcx, WORD * pcy)
  140. {
  141. return sscanf(m_strTgtText, TEXT("%hu %hu %hu %hu"),
  142. px,
  143. py,
  144. pcx,
  145. pcy);
  146. }
  147. BOOL CToken::GetSrcSize(WORD * px, WORD * py,WORD * pcx, WORD * pcy)
  148. {
  149. return sscanf(m_strSrcText, TEXT("%hu %hu %hu %hu"),
  150. px,
  151. py,
  152. pcx,
  153. pcy);
  154. }
  155. /////////////////////////////////////////////////////////////////////////
  156. CTokenFile::CTokenFile()
  157. {
  158. m_Tokens.SetSize(0, 10);
  159. m_iLastPos = 0;
  160. m_iUpperBound = -1;
  161. m_strSrcFile = "";
  162. m_strTgtFile = "";
  163. }
  164. CTokenFile::~CTokenFile()
  165. {
  166. for(INT_PTR at=0; at<=m_iUpperBound; at++)
  167. delete (m_Tokens.GetAt(at));
  168. m_Tokens.RemoveAll();
  169. }
  170. int CTokenFile::Open(CString strSrcFile, CString strTgtFile)
  171. {
  172. int iErr = CMainApp::ERR_NOERROR;
  173. // Open the files
  174. CStdioFile SrcFile;
  175. CStdioFile TgtFile;
  176. // If we are doing an UPDATE we need both src and tgt files
  177. // while if we are not it is enough the tgt file.
  178. // If only the tgt file is given no consistency will be done.
  179. if(theApp.IsFlag(CMainApp::UPDATE))
  180. if(!SrcFile.Open(strSrcFile, CFile::modeRead | CFile::shareDenyWrite))
  181. {
  182. theApp.WriteCon(CONERR, "Cannot open file: %s\r\n", strSrcFile);
  183. return CMainApp::ERR_FILE_OPEN;
  184. }
  185. if(!TgtFile.Open(strTgtFile, CFile::modeRead | CFile::shareDenyWrite))
  186. {
  187. theApp.WriteCon(CONERR, "Cannot open file: %s\r\n", strTgtFile);
  188. return CMainApp::ERR_FILE_OPEN;
  189. }
  190. CString strSrc = "";
  191. CString strTgt = "";
  192. INT_PTR at;
  193. while(TgtFile.ReadString(strTgt.GetBuffer(MAX_TOKEN), MAX_TOKEN))
  194. {
  195. if(theApp.IsFlag(CMainApp::UPDATE))
  196. if(!SrcFile.ReadString(strSrc.GetBuffer(MAX_TOKEN), MAX_TOKEN))
  197. {
  198. theApp.WriteCon(CONERR, "The file %s has more tokens than the file %s!\r\n", strTgtFile, strSrcFile);
  199. theApp.SetReturn(ERROR_RET_TOKEN_MISMATCH);
  200. return CMainApp::ERR_TOKEN_MISMATCH;
  201. }
  202. strSrc.ReleaseBuffer();
  203. strTgt.ReleaseBuffer();
  204. at = m_Tokens.Add(new CToken());
  205. if(iErr = ((CToken*)m_Tokens.GetAt(at))->Parse(strSrc,strTgt))
  206. {
  207. goto close;
  208. }
  209. }
  210. m_iUpperBound = m_Tokens.GetUpperBound();
  211. close:
  212. if(theApp.IsFlag(CMainApp::UPDATE))
  213. SrcFile.Close();
  214. TgtFile.Close();
  215. return iErr;
  216. }
  217. const CToken * CTokenFile::GetTokenSize(CToken * pToken, WORD * px, WORD * py,
  218. WORD * pcx, WORD * pcy)
  219. {
  220. if((pToken!=NULL) && (pToken->m_uiTypeID!=5))
  221. return NULL;
  222. CToken * pTokenSize = (CToken *)m_Tokens.GetAt(m_iLastPos++);
  223. if(pTokenSize==NULL)
  224. return NULL;
  225. WORD x, y, cx, cy;
  226. pTokenSize->GetSrcSize(&x, &y, &cx, &cy);
  227. // check if the size changed
  228. if(!theApp.IsFlag(CMainApp::UPDATE) ||
  229. (x==*px &&
  230. y==*py &&
  231. cx==*pcx &&
  232. cy==*pcy) )
  233. {
  234. pTokenSize->GetTgtSize(px, py, pcx, pcy);
  235. }
  236. else
  237. {
  238. theApp.WriteCon(CONWRN, "Item Resized\t%s\"]]\r\n", pTokenSize->m_strTokenID);
  239. theApp.AddResized();
  240. }
  241. return pTokenSize;
  242. }
  243. const CToken * CTokenFile::GetTokenSize(unsigned int TypeID,
  244. unsigned int ResID,
  245. unsigned int ItemID,
  246. CString strItemName,
  247. WORD * px, WORD * py,
  248. WORD * pcx, WORD * pcy)
  249. {
  250. if(TypeID!=5)
  251. return NULL;
  252. BOOL bMatch = FALSE;
  253. ASSERT(m_iUpperBound!=-1);
  254. if(m_iLastPos>m_iUpperBound)
  255. m_iLastPos = 0;
  256. CToken * pToken = NULL;
  257. INT_PTR iLastPos = m_iLastPos;
  258. while(!bMatch)
  259. {
  260. pToken = (CToken*)m_Tokens.GetAt(m_iLastPos++);
  261. if(pToken==NULL)
  262. return NULL;
  263. while(pToken->m_uiTypeID!=TypeID && !bMatch) {
  264. if(m_iLastPos>m_iUpperBound) {
  265. m_iLastPos = 0;
  266. bMatch = TRUE;
  267. }
  268. pToken = (CToken*)m_Tokens.GetAt(m_iLastPos++);
  269. if(pToken==NULL)
  270. return NULL;
  271. }
  272. // Let's see if we have at least some parameter to find the token
  273. if(pToken->m_uiTypeID==TypeID &&
  274. pToken->m_uiResID==ResID &&
  275. pToken->m_uiItemID==ItemID &&
  276. pToken->m_strItemName==strItemName &&
  277. (pToken->m_uiFlags & ISCOR)) // to be compatible with rlman token ids
  278. {
  279. WORD x, y, cx, cy;
  280. pToken->GetSrcSize(&x, &y, &cx, &cy);
  281. // check if the size changed
  282. if(!theApp.IsFlag(CMainApp::UPDATE) ||
  283. (x==*px &&
  284. y==*py &&
  285. cx==*pcx &&
  286. cy==*pcy) )
  287. {
  288. pToken->GetTgtSize(px, py, pcx, pcy);
  289. }
  290. else
  291. {
  292. theApp.WriteCon(CONWRN, "Item Resized\t%s\"]]\r\n", pToken->m_strTokenID);
  293. theApp.AddResized();
  294. }
  295. return pToken;
  296. }
  297. else if(pToken->m_uiTypeID!=TypeID)
  298. {
  299. m_iLastPos = iLastPos;
  300. return NULL;
  301. }
  302. if(m_iLastPos>m_iUpperBound)
  303. return NULL;
  304. }
  305. return NULL;
  306. }
  307. const CToken * CTokenFile::GetToken(unsigned int TypeID,
  308. unsigned int ResID,
  309. unsigned int ItemID,
  310. CString strText,
  311. CString strItemName)
  312. {
  313. if(strText.IsEmpty() && (TypeID != 5L)) // Allow Dialog Strings to be NULL
  314. return NULL;
  315. BOOL bMatch = FALSE;
  316. ASSERT(m_iUpperBound!=-1);
  317. if(m_iLastPos>m_iUpperBound)
  318. m_iLastPos = 0;
  319. CToken * pToken = NULL;
  320. INT_PTR iLastPos = m_iLastPos;
  321. while(!bMatch)
  322. {
  323. pToken = (CToken*)m_Tokens.GetAt(m_iLastPos++);
  324. if(pToken==NULL)
  325. return NULL;
  326. while(pToken->m_uiTypeID!=TypeID && !bMatch) {
  327. if(m_iLastPos>m_iUpperBound) {
  328. m_iLastPos = 0;
  329. bMatch = TRUE;
  330. }
  331. pToken = (CToken*)m_Tokens.GetAt(m_iLastPos++);
  332. if(pToken==NULL)
  333. return NULL;
  334. }
  335. // Let's see if we have at least some parameter to find the token
  336. if(pToken->m_uiTypeID==TypeID &&
  337. pToken->m_uiResID==ResID &&
  338. pToken->m_uiItemID==ItemID &&
  339. pToken->m_strItemName==strItemName &&
  340. !(pToken->m_uiFlags & ISCOR)) // to be compatible with rlman token ids
  341. {
  342. if(!theApp.IsFlag(CMainApp::FONTS) && (pToken->m_uiFlags & ISDLGFONTNAME) || (pToken->m_uiFlags & ISDLGFONTSIZE))
  343. return pToken;
  344. else if(!theApp.IsFlag(CMainApp::UPDATE) || pToken->m_strSrcText==strText)
  345. return pToken;
  346. else
  347. {
  348. theApp.WriteCon(CONWRN, "Context changed\t%s\"]]\r\n", pToken->m_strTokenID);
  349. theApp.AddChanged();
  350. pToken->m_uiLastError = 1;
  351. return pToken;
  352. }
  353. }
  354. else if(pToken->m_uiTypeID!=TypeID) {
  355. m_iLastPos = iLastPos;
  356. return NULL;
  357. }
  358. if(m_iLastPos>m_iUpperBound)
  359. return NULL;
  360. }
  361. return NULL;
  362. }
  363. const CToken * CTokenFile::GetNoCaptionToken(unsigned int TypeID,
  364. unsigned int ResID,
  365. unsigned int ItemID,
  366. CString strItemName)
  367. {
  368. BOOL bMatch = FALSE;
  369. ASSERT(m_iUpperBound!=-1);
  370. if(m_iLastPos>m_iUpperBound)
  371. m_iLastPos = 0;
  372. CToken * pToken = NULL;
  373. INT_PTR iLastPos = m_iLastPos;
  374. while(!bMatch)
  375. {
  376. pToken = (CToken*)m_Tokens.GetAt(m_iLastPos++);
  377. if(pToken==NULL)
  378. return NULL;
  379. while(pToken->m_uiTypeID!=TypeID && !bMatch) {
  380. if(m_iLastPos>m_iUpperBound) {
  381. m_iLastPos = 0;
  382. bMatch = TRUE;
  383. }
  384. pToken = (CToken*)m_Tokens.GetAt(m_iLastPos++);
  385. if(pToken==NULL)
  386. return NULL;
  387. }
  388. // Let's see if we have at least some parameter to find the token
  389. if(pToken->m_uiTypeID==TypeID &&
  390. pToken->m_uiResID==ResID &&
  391. pToken->m_uiItemID==ItemID &&
  392. pToken->m_strItemName==strItemName && // to be compatible with rlman token ids
  393. (!pToken->m_strSrcText || TypeID !=4)) // Some binaries like shell32.dll uses the same id 0 as MENU SEPARATOR. Filter those out.
  394. {
  395. return pToken;
  396. }
  397. else if(pToken->m_uiTypeID!=TypeID) {
  398. m_iLastPos = iLastPos;
  399. return NULL;
  400. }
  401. if(m_iLastPos>m_iUpperBound)
  402. return NULL;
  403. }
  404. return NULL;
  405. }