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.

337 lines
11 KiB

  1. /****************************************************************************/
  2. /* */
  3. /* CONVGRP.C - */
  4. /* */
  5. /* Conversion from Windows NT 1.0 program group format with ANSI */
  6. /* strings to Windows NT 1.0a group format with UNICODE strings. */
  7. /* */
  8. /* Created: 09-10-93 Johanne Caron */
  9. /* */
  10. /****************************************************************************/
  11. #include "progman.h"
  12. #include "convgrp.h"
  13. /*--------------------------------------------------------------------------*/
  14. /* */
  15. /* CreateNewGroupFromAnsiGroup() - */
  16. /* */
  17. /* This function creates a new, empty group. */
  18. /* */
  19. /*--------------------------------------------------------------------------*/
  20. HANDLE CreateNewGroupFromAnsiGroup(LPGROUPDEF_A lpGroupORI)
  21. {
  22. HANDLE hT = NULL;
  23. LPGROUPDEF lpgd;
  24. int i;
  25. int cb;
  26. int cItems; // number of items in 16bit group
  27. LPSTR pGroupName; // 32bit group name
  28. LPTSTR pGroupNameUNI = NULL; // 32bit UNICODE group name
  29. INT wGroupNameLen; // length of pGroupName DWORD aligned.
  30. INT cchWideChar = 0; //character count of resultant unicode string
  31. INT cchMultiByte = 0;
  32. pGroupName = (LPSTR)PTR(lpGroupORI, lpGroupORI->pName);
  33. //
  34. // convert pGroupName to unicode here
  35. //
  36. cchMultiByte=MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pGroupName, -1, pGroupNameUNI, cchWideChar);
  37. pGroupNameUNI = LocalAlloc(LPTR,(++cchMultiByte)*sizeof(TCHAR));
  38. if (pGroupNameUNI)
  39. {
  40. MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED, pGroupName, -1, pGroupNameUNI, cchMultiByte);
  41. wGroupNameLen = MyDwordAlign(sizeof(TCHAR)*(lstrlen(pGroupNameUNI) + 1));
  42. cItems = lpGroupORI->cItems;
  43. cb = sizeof(GROUPDEF) + (cItems * sizeof(DWORD)) + wGroupNameLen;
  44. //
  45. // In CreateNewGroup before GlobalAlloc.
  46. //
  47. hT = GlobalAlloc(GHND, (DWORD)cb);
  48. if (hT)
  49. {
  50. lpgd = (LPGROUPDEF)GlobalLock(hT);
  51. //
  52. // use the NT 1.0 group settings for what we can.
  53. //
  54. lpgd->nCmdShow = lpGroupORI->nCmdShow;
  55. lpgd->wIconFormat = lpGroupORI->wIconFormat;
  56. lpgd->cxIcon = lpGroupORI->cxIcon;
  57. lpgd->cyIcon = lpGroupORI->cyIcon;
  58. lpgd->ptMin.x = (INT)lpGroupORI->ptMin.x;
  59. lpgd->ptMin.y = (INT)lpGroupORI->ptMin.y;
  60. CopyRect(&(lpgd->rcNormal),&(lpGroupORI->rcNormal));
  61. lpgd->dwMagic = GROUP_UNICODE;
  62. lpgd->cbGroup = (DWORD)cb;
  63. lpgd->pName = sizeof(GROUPDEF) + cItems * sizeof(DWORD);
  64. lpgd->Reserved1 = (WORD)-1;
  65. lpgd->Reserved2 = (DWORD)-1;
  66. lpgd->cItems = (WORD)cItems;
  67. for (i = 0; i < cItems; i++)
  68. {
  69. lpgd->rgiItems[i] = 0;
  70. }
  71. lstrcpy((LPTSTR)((LPSTR)lpgd + sizeof(GROUPDEF) + cItems * sizeof(DWORD)),
  72. pGroupNameUNI); // lhb tracks
  73. LocalFree(pGroupNameUNI);
  74. GlobalUnlock(hT);
  75. }
  76. }
  77. return hT;
  78. }
  79. DWORD AddThing_A(HANDLE hGroup, LPSTR lpStuff, WORD cbStuff)
  80. {
  81. LPTSTR lpStuffUNI = NULL;
  82. BOOL bAlloc = FALSE;
  83. DWORD cb;
  84. if (cbStuff == 0xFFFF) {
  85. return 0xFFFF;
  86. }
  87. if (!cbStuff) {
  88. INT cchMultiByte;
  89. INT cchWideChar = 0;
  90. bAlloc = TRUE;
  91. cchMultiByte=MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpStuff,
  92. -1,lpStuffUNI,cchWideChar) ;
  93. lpStuffUNI = LocalAlloc(LPTR,(++cchMultiByte)*sizeof(TCHAR)) ;
  94. MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpStuff,
  95. -1,lpStuffUNI,cchMultiByte) ;
  96. cbStuff = (WORD)sizeof(TCHAR)*(1 + lstrlen(lpStuffUNI)); // lhb tracks
  97. } else {
  98. lpStuffUNI = (LPTSTR)lpStuff;
  99. }
  100. cb = AddThing(hGroup, lpStuffUNI, cbStuff);
  101. if (bAlloc)
  102. LocalFree(lpStuffUNI);
  103. return(cb);
  104. }
  105. /*--------------------------------------------------------------------------*/
  106. /* */
  107. /* ConvertToUnicodeGroup() - */
  108. /* */
  109. /* returns the size of the new unicode group. */
  110. /* */
  111. /*--------------------------------------------------------------------------*/
  112. int ConvertToUnicodeGroup(LPGROUPDEF_A lpGroupORI, LPHANDLE lphNewGroup)
  113. {
  114. HANDLE hNewGroup;
  115. LPGROUPDEF lpgd;
  116. LPITEMDEF lpid;
  117. LPBYTE lpid_A;
  118. LPPMTAG lptag_A;
  119. LPSTR lpTagValue;
  120. WORD wTagId;
  121. LPSTR lpT;
  122. DWORD offset;
  123. int cb;
  124. int i;
  125. INT cchMultiByte;
  126. INT cchWideChar;
  127. LPTSTR lpTagValueUNI;
  128. BOOL bAlloc = FALSE;
  129. hNewGroup = CreateNewGroupFromAnsiGroup(lpGroupORI);
  130. if (!hNewGroup) {
  131. return(0);
  132. }
  133. //
  134. // Add all items to the new formatted group.
  135. //
  136. for (i = 0; (i < (int)lpGroupORI->cItems) && (i < CITEMSMAX); i++) {
  137. //
  138. // Get the pointer to the 16bit item
  139. //
  140. lpid_A = (LPBYTE)ITEM(lpGroupORI, i);
  141. if (lpGroupORI->rgiItems[i]) {
  142. //
  143. // Create the item.
  144. //
  145. offset = AddThing(hNewGroup, NULL, sizeof(ITEMDEF));
  146. if (!offset) {
  147. KdPrint(("ConvGrp: Addthing ITEMDEF failed for item %d \n", i));
  148. goto QuitThis;
  149. }
  150. lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
  151. lpgd->rgiItems[i] = offset;
  152. lpid = ITEM(lpgd, i);
  153. //
  154. // Set the item's position.
  155. //
  156. lpid->pt.x = ((LPITEMDEF_A)lpid_A)->pt.x;
  157. lpid->pt.y = ((LPITEMDEF_A)lpid_A)->pt.y;
  158. //
  159. // Add the item's Name.
  160. //
  161. GlobalUnlock(hNewGroup);
  162. lpT = (LPSTR)PTR(lpGroupORI,((LPITEMDEF_A)lpid_A)->pName);
  163. offset = AddThing_A(hNewGroup, lpT, 0);
  164. if (!offset) {
  165. KdPrint(("ConvGrp: Addthing pName failed for item %d \n", i));
  166. goto PuntCreation;
  167. }
  168. lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
  169. lpid = ITEM(lpgd, i);
  170. lpid->pName = offset;
  171. //
  172. // Add the item's Command line.
  173. //
  174. GlobalUnlock(hNewGroup);
  175. lpT = (LPSTR)PTR(lpGroupORI, ((LPITEMDEF_A)lpid_A)->pCommand);
  176. offset = AddThing_A(hNewGroup, lpT, 0);
  177. if (!offset) {
  178. KdPrint(("ConvGrp: Addthing pCommand failed for item %d \n", i));
  179. goto PuntCreation;
  180. }
  181. lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
  182. lpid = ITEM(lpgd, i);
  183. lpid->pCommand = offset;
  184. //
  185. // Add the item's Icon path.
  186. //
  187. GlobalUnlock(hNewGroup);
  188. lpT = (LPSTR)PTR(lpGroupORI, ((LPITEMDEF_A)lpid_A)->pIconPath);
  189. offset = AddThing_A(hNewGroup, lpT, 0);
  190. if (!offset) {
  191. KdPrint(("ConvGrp: Addthing pIconPath failed for item %d \n", i));
  192. goto PuntCreation;
  193. }
  194. lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
  195. lpid = ITEM(lpgd, i);
  196. lpid->pIconPath = offset;
  197. //
  198. // Get the item's icon resource using the Icon path and the icon index.
  199. // And add the item's Icon resource.
  200. //
  201. lpid->iIcon = ((LPITEMDEF_A)lpid_A)->idIcon;
  202. lpid->cbIconRes = ((LPITEMDEF_A)lpid_A)->cbIconRes;
  203. lpid->wIconVer = ((LPITEMDEF_A)lpid_A)->wIconVer;
  204. GlobalUnlock(hNewGroup);
  205. lpT = (LPBYTE)PTR(lpGroupORI, ((LPITEMDEF_A)lpid_A)->pIconRes);
  206. offset = AddThing_A(hNewGroup, (LPSTR)lpT, lpid->cbIconRes);
  207. if (!offset) {
  208. KdPrint(("ConvGrp: AddThing pIconRes failed for item %d \n", i));
  209. goto PuntCreation;
  210. }
  211. lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
  212. lpid = ITEM(lpgd, i);
  213. lpid->pIconRes = offset;
  214. GlobalUnlock(hNewGroup);
  215. }
  216. }
  217. /*
  218. * Copy all the tags to the new group format.
  219. */
  220. lptag_A = (LPPMTAG)((LPSTR)lpGroupORI + lpGroupORI->cbGroup); // lhb tracks
  221. if (lptag_A->wID == ID_MAGIC &&
  222. lptag_A->wItem == (int)0xFFFF &&
  223. *(LONG FAR *)lptag_A->rgb == PMTAG_MAGIC) {
  224. //
  225. // This is the first tag id, goto start of item tags.
  226. //
  227. (LPBYTE)lptag_A += lptag_A->cb;
  228. while (lptag_A->wID != ID_LASTTAG) {
  229. wTagId = lptag_A->wID;
  230. cb = lptag_A->cb - (3 * sizeof(DWORD)); // cb - sizeof tag
  231. if (wTagId == ID_MINIMIZE) {
  232. lpTagValueUNI = NULL;
  233. }
  234. else {
  235. lpTagValue = lptag_A->rgb ;
  236. if (wTagId != ID_HOTKEY) {
  237. bAlloc = TRUE;
  238. cchWideChar = 0;
  239. cchMultiByte=MultiByteToWideChar(CP_ACP,
  240. MB_PRECOMPOSED,lpTagValue,
  241. -1,lpTagValueUNI,cchWideChar) ;
  242. lpTagValueUNI = LocalAlloc(LPTR,(++cchMultiByte)*sizeof(TCHAR)) ;
  243. MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpTagValue,
  244. -1,lpTagValueUNI,cchMultiByte) ;
  245. cb = sizeof(TCHAR)*(lstrlen(lpTagValueUNI) + 1); // lhb tracks
  246. }
  247. else {
  248. lpTagValueUNI = (LPTSTR)lpTagValue;
  249. }
  250. }
  251. if (! AddTag( hNewGroup,
  252. lptag_A->wItem, // wItem
  253. wTagId, // wID
  254. lpTagValueUNI, // rgb : tag value
  255. cb
  256. )) {
  257. KdPrint(("ConvGrp: AddTag wItem=%d, wID=%d failed \n",
  258. lptag_A->wItem ,
  259. lptag_A->wID));
  260. }
  261. if (bAlloc && lpTagValueUNI) {
  262. LocalFree(lpTagValueUNI);
  263. bAlloc = FALSE;
  264. }
  265. (LPBYTE)lptag_A += lptag_A->cb ; // go to next tag
  266. }
  267. }
  268. lpgd = GlobalLock(hNewGroup);
  269. cb = SizeofGroup(lpgd);
  270. GlobalUnlock(hNewGroup);
  271. *lphNewGroup = hNewGroup;
  272. return(cb);
  273. PuntCreation:
  274. QuitThis:
  275. if (hNewGroup) {
  276. GlobalFree(hNewGroup);
  277. }
  278. return(0);
  279. }