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.

860 lines
27 KiB

  1. /****************************************************************************/
  2. /* */
  3. /* CONVGRP.H - */
  4. /* */
  5. /* Conversion from Win3.1 16 bit .grp file to NT 32bit .grp files for */
  6. /* the Program Manager */
  7. /* */
  8. /* Created: 10-15-92 Johanne Caron */
  9. /* */
  10. /****************************************************************************/
  11. #include "convgrp.h"
  12. #include <shellapi.h>
  13. #include <shlapip.h>
  14. #if DBG
  15. void DbgPrint(char *, ...);
  16. #define KdPrint(_x_) DbgPrint _x_
  17. #else
  18. #define KdPrint(_x_)
  19. #endif
  20. /*--------------------------------------------------------------------------*/
  21. /* */
  22. /* MyDwordAlign() - */
  23. /* */
  24. /*--------------------------------------------------------------------------*/
  25. WORD MyDwordAlign(int wStrLen)
  26. {
  27. return ((WORD)((wStrLen + 3) & ~3));
  28. }
  29. /*--------------------------------------------------------------------------*/
  30. /* */
  31. /* SizeofGroup() - */
  32. /* */
  33. /*--------------------------------------------------------------------------*/
  34. DWORD SizeofGroup(LPGROUPDEF lpgd)
  35. {
  36. LPPMTAG lptag;
  37. WORD cbSeg;
  38. WORD cb;
  39. cbSeg = (WORD)GlobalSize(lpgd);
  40. lptag = (LPPMTAG)((LPSTR)lpgd+lpgd->cbGroup);
  41. if ((WORD)((PCHAR)lptag - (PCHAR)lpgd +MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb))+4) <= cbSeg
  42. && lptag->wID == ID_MAGIC
  43. && lptag->wItem == (int)0xFFFF
  44. && lptag->cb == (WORD)(MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb)) + 4)
  45. && *(PLONG)lptag->rgb == PMTAG_MAGIC)
  46. {
  47. while ((cb = (WORD)((PCHAR)lptag - (PCHAR)lpgd + MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb)))) <= cbSeg)
  48. {
  49. if (lptag->wID == ID_LASTTAG)
  50. return (DWORD)cb;
  51. (LPSTR)lptag += lptag->cb;
  52. }
  53. }
  54. return lpgd->cbGroup;
  55. }
  56. /*--------------------------------------------------------------------------*/
  57. /* */
  58. /* AddUpGroupFile() - */
  59. /* */
  60. /* Calculates the group file's checksum. */
  61. /*--------------------------------------------------------------------------*/
  62. WORD AddUpGroupFile(LPGROUPDEF lpgd)
  63. {
  64. LPINT lpW;
  65. LPINT save_lpW;
  66. DWORD wSum = 0;
  67. DWORD cbFile;
  68. cbFile = SizeofGroup(lpgd);
  69. for (save_lpW = lpW = (LPINT)lpgd, cbFile >>= 2; cbFile; cbFile--, lpW++)
  70. wSum += *lpW;
  71. return (WORD)((DWORD_PTR)lpW - (DWORD_PTR)save_lpW);
  72. }
  73. /*--------------------------------------------------------------------------*/
  74. /* */
  75. /* AddThing() - */
  76. /* */
  77. /* in: */
  78. /* hGroup group handle, must not be discardable */
  79. /* lpStuff pointer to data or NULL to init data to zero */
  80. /* cbStuff count of item (may be 0) if lpStuff is a string */
  81. /* */
  82. /* Adds an object to the group segment and returns its offset. Will */
  83. /* reallocate the segment if necessary. */
  84. /* */
  85. /* Handle passed in must not be discardable */
  86. /* */
  87. /* returns: */
  88. /* 0 failure */
  89. /* > 0 offset to thing in the segment */
  90. /* */
  91. /*--------------------------------------------------------------------------*/
  92. WORD AddThing(HANDLE hGroup, LPSTR lpStuff, WORD cbStuff)
  93. {
  94. WORD cb;
  95. LPGROUPDEF lpgd;
  96. WORD offset;
  97. LPSTR lpT;
  98. WORD cbStuffSize;
  99. WORD cbGroupSize;
  100. WORD myOffset;
  101. if (cbStuff == 0xFFFF) {
  102. return 0xFFFF;
  103. }
  104. if (!cbStuff) {
  105. cbStuff = (WORD)(1 + lstrlen(lpStuff));
  106. }
  107. cbStuffSize = (WORD)MyDwordAlign((int)cbStuff);
  108. lpgd = (LPGROUPDEF)GlobalLock(hGroup);
  109. cb = (WORD)SizeofGroup(lpgd);
  110. cbGroupSize = (WORD)MyDwordAlign((int)cb);
  111. offset = lpgd->cbGroup;
  112. myOffset = (WORD)MyDwordAlign((int)offset);
  113. GlobalUnlock(hGroup);
  114. if (!GlobalReAlloc(hGroup,(DWORD)(cbGroupSize + cbStuffSize), GMEM_MOVEABLE))
  115. return 0;
  116. lpgd = (LPGROUPDEF)GlobalLock(hGroup);
  117. /*
  118. * Slide the tags up
  119. */
  120. memmove((LPSTR)lpgd + myOffset + cbStuffSize, (LPSTR)lpgd + myOffset,
  121. (WORD)(cbGroupSize - myOffset));
  122. lpgd->cbGroup += cbStuffSize;
  123. lpT = (LPSTR)((LPSTR)lpgd + myOffset);
  124. if (lpStuff) {
  125. memmove(lpT, lpStuff, cbStuff);
  126. } else {
  127. /*
  128. * Zero it
  129. */
  130. while (cbStuffSize--) {
  131. *lpT++ = 0;
  132. }
  133. }
  134. GlobalUnlock(hGroup);
  135. return myOffset;
  136. }
  137. /*--------------------------------------------------------------------------*/
  138. /* */
  139. /* FindTag() - */
  140. /* */
  141. /*--------------------------------------------------------------------------*/
  142. LPPMTAG FindTag(LPGROUPDEF lpgd, int item, WORD id)
  143. {
  144. LPPMTAG lptag;
  145. int cbSeg;
  146. int cb;
  147. cbSeg = (int)GlobalSize(lpgd);
  148. lptag = (LPPMTAG)((LPSTR)lpgd+lpgd->cbGroup);
  149. if ((PCHAR)lptag - (PCHAR)lpgd + MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb)) + 4 <= cbSeg
  150. && lptag->wID == ID_MAGIC
  151. && lptag->wItem == (int)0xFFFF
  152. && lptag->cb == (WORD)(MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb)) +4)
  153. && *(LONG FAR *)lptag->rgb == PMTAG_MAGIC) {
  154. while ((cb = (int)((PCHAR)lptag - (PCHAR)lpgd) + MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb))) <= cbSeg)
  155. {
  156. if ((item == lptag->wItem)
  157. && (id == 0 || id == lptag->wID)) {
  158. return lptag;
  159. }
  160. if (lptag->wID == ID_LASTTAG)
  161. return NULL;
  162. (LPSTR)lptag += lptag->cb;
  163. }
  164. }
  165. return NULL;
  166. }
  167. /*--------------------------------------------------------------------------*/
  168. /* */
  169. /* AddTag() - */
  170. /* */
  171. /* in: */
  172. /* h group handle, must not be discardable! */
  173. /* */
  174. /* returns: */
  175. /* 0 failure */
  176. /* 1 success */
  177. /*--------------------------------------------------------------------------*/
  178. INT AddTag(HANDLE h, int item, WORD id, LPSTR lpbuf, int cb)
  179. {
  180. LPPMTAG lptag;
  181. WORD fAddFirst;
  182. LPGROUPDEF lpgd;
  183. int cbNew;
  184. int cbMyLen;
  185. LPGROUPDEF lpgdOld;
  186. if (!cb && lpbuf) {
  187. cb = lstrlen(lpbuf) + 1;
  188. }
  189. cbMyLen = MyDwordAlign(cb);
  190. if (!lpbuf) {
  191. cb = 0;
  192. cbMyLen = 0;
  193. }
  194. lpgd = (LPGROUPDEF)GlobalLock(h);
  195. lptag = FindTag(lpgd, (int)0xFFFF, (WORD)ID_LASTTAG);
  196. if (!lptag) {
  197. /*
  198. * In this case, there are no tags at all, and we have to add
  199. * the first tag, the interesting tag, and the last tag
  200. */
  201. cbNew = 3 * (MyDwordAlign(sizeof(PMTAG)) - MyDwordAlign(sizeof(lptag->rgb))) + 4 + cbMyLen;
  202. fAddFirst = TRUE;
  203. lptag = (LPPMTAG)((LPSTR)lpgd + lpgd->cbGroup);
  204. } else {
  205. /*
  206. * In this case, only the interesting tag needs to be added
  207. * but we count in the last because the delta is from lptag
  208. */
  209. cbNew = 2 * (MyDwordAlign(sizeof(PMTAG)) - MyDwordAlign(sizeof(lptag->rgb))) + cbMyLen;
  210. fAddFirst = FALSE;
  211. }
  212. cbNew += (int)((PCHAR)lptag -(PCHAR)lpgd);
  213. lpgdOld = lpgd;
  214. GlobalUnlock(h);
  215. if (!GlobalReAlloc(h, (DWORD)cbNew, GMEM_MOVEABLE)) {
  216. return 0;
  217. }
  218. lpgd = (LPGROUPDEF)GlobalLock(h);
  219. lptag = (LPPMTAG)((LPSTR)lpgd + ((LPSTR)lptag - (LPSTR)lpgdOld));
  220. if (fAddFirst) {
  221. /*
  222. * Add the first tag
  223. */
  224. lptag->wID = ID_MAGIC;
  225. lptag->wItem = (int)0xFFFF;
  226. *(LONG FAR *)lptag->rgb = PMTAG_MAGIC;
  227. lptag->cb = (WORD)(MyDwordAlign(sizeof(PMTAG)) - MyDwordAlign(sizeof(lptag->rgb)) + 4);
  228. (LPSTR)lptag += lptag->cb;
  229. }
  230. /*
  231. * Add the tag
  232. */
  233. lptag->wID = id;
  234. lptag->wItem = item;
  235. lptag->cb = (WORD)(MyDwordAlign(sizeof(PMTAG)) - MyDwordAlign(sizeof(lptag->rgb)) + cbMyLen);
  236. if (lpbuf) {
  237. memmove(lptag->rgb, lpbuf, (WORD)cb);
  238. }
  239. (LPSTR)lptag += lptag->cb;
  240. /*
  241. * Add the end tag
  242. */
  243. lptag->wID = ID_LASTTAG;
  244. lptag->wItem = (int)0xFFFF;
  245. lptag->cb = 0;
  246. GlobalUnlock(h);
  247. return 1;
  248. }
  249. /*--------------------------------------------------------------------------*/
  250. /* */
  251. /* AddItemIconResource() - */
  252. /* */
  253. /* Adds the icon resource to the group item. Returns TRUE if the icon */
  254. /* resource was extracted ok and it was added ok. */
  255. /* */
  256. /*--------------------------------------------------------------------------*/
  257. BOOL AddItemIconResource(HANDLE hNewGroup, LPITEMDEF lpid, WORD iItem, LPSTR lpIconPath)
  258. {
  259. LPGROUPDEF lpgd;
  260. LPBYTE lpIconRes = NULL;
  261. HANDLE hIconRes;
  262. HANDLE hModule;
  263. HICON hIcon;
  264. CHAR szIconExe[MAX_PATH];
  265. WORD id;
  266. WORD offset;
  267. DWORD OldErrorMode;
  268. lpid->cbIconRes = 0;
  269. id = lpid->indexIcon;
  270. lstrcpy(szIconExe, lpIconPath);
  271. CharLower(szIconExe);
  272. if (id > 7 && strstr(szIconExe, "progman")) {
  273. //
  274. // There's one more icon in the NT progman.exe than in the Win3.1
  275. // progman.exe and it's inserted at the 8th icon position. So if
  276. // the icon index is 9 in Win3.1 then it will be the 10th icon in
  277. // NT progman.exe, etc
  278. //
  279. id++;
  280. }
  281. hIcon = ExtractAssociatedIcon(hInst, szIconExe, &id);
  282. if (!hIcon) {
  283. goto Failed;
  284. }
  285. DestroyIcon(hIcon);
  286. lpid->idIcon = id;
  287. OldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  288. if (hModule = LoadLibrary(szIconExe)) {
  289. SetErrorMode(OldErrorMode);
  290. //
  291. // It's a 32bit .exe
  292. //
  293. hIconRes = FindResource(hModule, MAKEINTRESOURCE(id), MAKEINTRESOURCE(RT_ICON));
  294. if (hIconRes) {
  295. lpid->wIconVer = 3; // resource version is windows 3.x
  296. lpid->cbIconRes = (WORD)SizeofResource(hModule, hIconRes);
  297. if (hIconRes = LoadResource(hModule, hIconRes))
  298. lpIconRes = LockResource(hIconRes);
  299. }
  300. }
  301. else {
  302. SetErrorMode(OldErrorMode);
  303. //
  304. // It's a 16bit .exe
  305. //
  306. if (lpid->wIconVer = ExtractIconResInfo(hInst,
  307. szIconExe,
  308. lpid->indexIcon,
  309. &lpid->cbIconRes,
  310. &hIconRes)){
  311. lpIconRes = GlobalLock(hIconRes);
  312. }
  313. }
  314. //
  315. // Add the item's Icon resource.
  316. //
  317. if (!lpid->cbIconRes) {
  318. goto Failed;
  319. }
  320. offset = AddThing(hNewGroup, lpIconRes, lpid->cbIconRes);
  321. GlobalUnlock(hIconRes);
  322. GlobalFree(hIconRes);
  323. lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
  324. lpid = ITEM(lpgd, iItem);
  325. if (!offset) {
  326. GlobalUnlock(hNewGroup);
  327. KdPrint(("ConvGrp: AddThing lpIconRes failed for item %d \n", iItem));
  328. goto Failed;
  329. }
  330. lpid->pIconRes = offset;
  331. GlobalUnlock(hNewGroup);
  332. return(TRUE);
  333. Failed:
  334. KdPrint(("ConvGrp: AddItemIconResource failed to extract icon for item %d \n", iItem));
  335. return(FALSE);
  336. }
  337. /*--------------------------------------------------------------------------*/
  338. /* */
  339. /* CreateNewGroup() - */
  340. /* */
  341. /* This function creates a new, empty group. */
  342. /* */
  343. /*--------------------------------------------------------------------------*/
  344. HANDLE CreateNewGroup(LPGROUPDEF16 lpGroup16)
  345. {
  346. HANDLE hT;
  347. LPGROUPDEF lpgd;
  348. int i;
  349. int cb;
  350. int cItems; // number of items in 16bit group
  351. LPSTR pGroupName; // 16bit group name
  352. INT wGroupNameLen; //length of pGroupName DWORD aligned.
  353. pGroupName = PTR(lpGroup16, lpGroup16->pName);
  354. wGroupNameLen = MyDwordAlign(lstrlen(pGroupName) + 1);
  355. cItems = lpGroup16->cItems;
  356. cb = sizeof(GROUPDEF) + (cItems * sizeof(WORD)) + wGroupNameLen;
  357. //
  358. // In CreateNewGroup before GlobalAlloc.
  359. //
  360. hT = GlobalAlloc(GHND, (DWORD)cb);
  361. if (!hT) {
  362. return NULL;
  363. }
  364. lpgd = (LPGROUPDEF)GlobalLock(hT);
  365. //
  366. // use the 16bit .grp file settings for what we can.
  367. //
  368. lpgd->nCmdShow = lpGroup16->nCmdShow;
  369. lpgd->wIconFormat = lpGroup16->wIconFormat;
  370. lpgd->cxIcon = lpGroup16->cxIcon;
  371. lpgd->cyIcon = lpGroup16->cyIcon;
  372. lpgd->ptMin.x = (INT)lpGroup16->ptMin.x;
  373. lpgd->ptMin.y = (INT)lpGroup16->ptMin.y;
  374. SetRect(&(lpgd->rcNormal),
  375. (INT)lpGroup16->rcNormal.Left,
  376. (INT)lpGroup16->rcNormal.Top,
  377. (INT)lpGroup16->rcNormal.Right,
  378. (INT)lpGroup16->rcNormal.Bottom);
  379. lpgd->dwMagic = GROUP_MAGIC;
  380. lpgd->wCheckSum = 0; /* adjusted later... */
  381. lpgd->cbGroup = (WORD)cb;
  382. lpgd->pName = sizeof(GROUPDEF) + cItems * sizeof(WORD);
  383. lpgd->cItems = (WORD)cItems;
  384. for (i = 0; i < cItems; i++) {
  385. lpgd->rgiItems[i] = 0;
  386. }
  387. lstrcpy((LPSTR)lpgd + sizeof(GROUPDEF) + cItems * sizeof(WORD),
  388. pGroupName);
  389. lpgd->wCheckSum = -(AddUpGroupFile(lpgd));
  390. GlobalUnlock(hT);
  391. return(hT);
  392. }
  393. /*--------------------------------------------------------------------------*/
  394. /* */
  395. /* Create32bitGroupFormat() - */
  396. /*
  397. /* returns the size of the new 32bit group.
  398. /* */
  399. /*--------------------------------------------------------------------------*/
  400. int Create32bitGroupFormat(LPGROUPDEF16 lpGroup16,
  401. int cbGroup16Size,
  402. LPHANDLE lphNewGroup)
  403. {
  404. HANDLE hNewGroup;
  405. LPGROUPDEF lpgd;
  406. LPITEMDEF lpid;
  407. LPBYTE lpid16;
  408. LPBYTE lptag16;
  409. LPSTR lpTagValue;
  410. WORD wTagId;
  411. LPSTR lpT;
  412. WORD offset;
  413. int cb;
  414. int i;
  415. hNewGroup = CreateNewGroup(lpGroup16);
  416. if (!hNewGroup) {
  417. return(0);
  418. }
  419. //
  420. // Add all items to the new formatted group.
  421. //
  422. for (i = 0; (i < (int)lpGroup16->cItems) && (i < CITEMSMAX); i++) {
  423. //
  424. // Get the pointer to the 16bit item
  425. //
  426. lpid16 = ITEM16(lpGroup16, i);
  427. //
  428. // Create the item.
  429. //
  430. offset = AddThing(hNewGroup, NULL, sizeof(ITEMDEF));
  431. if (!offset) {
  432. KdPrint(("ConvGrp: Addthing ITEMDEF failed for item %d \n", i));
  433. goto QuitThis;
  434. }
  435. lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
  436. lpgd->rgiItems[i] = offset;
  437. lpid = ITEM(lpgd, i);
  438. //
  439. // Set the item's position.
  440. //
  441. lpid->pt.x = *(LPWORD)lpid16;
  442. lpid->pt.y = *((LPWORD)lpid16 + 1);
  443. //
  444. // Add the item's Name.
  445. //
  446. GlobalUnlock(hNewGroup);
  447. lpT = PTR(lpGroup16, *((LPWORD)lpid16 + 9));
  448. offset = AddThing(hNewGroup, lpT, 0);
  449. if (!offset) {
  450. KdPrint(("ConvGrp: Addthing pName failed for item %d \n", i));
  451. goto PuntCreation;
  452. }
  453. lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
  454. lpid = ITEM(lpgd, i);
  455. lpid->pName = offset;
  456. //
  457. // Add the item's Command line.
  458. //
  459. GlobalUnlock(hNewGroup);
  460. lpT = PTR(lpGroup16, *((LPWORD)lpid16 + 10));
  461. offset = AddThing(hNewGroup, lpT, 0);
  462. if (!offset) {
  463. KdPrint(("ConvGrp: Addthing pCommand failed for item %d \n", i));
  464. goto PuntCreation;
  465. }
  466. lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
  467. lpid = ITEM(lpgd, i);
  468. lpid->pCommand = offset;
  469. //
  470. // Add the item's Icon path.
  471. //
  472. GlobalUnlock(hNewGroup);
  473. lpT = PTR(lpGroup16, *((LPWORD)lpid16 + 11));
  474. offset = AddThing(hNewGroup, lpT, 0);
  475. if (!offset) {
  476. KdPrint(("ConvGrp: Addthing pIconPath failed for item %d \n", i));
  477. goto PuntCreation;
  478. }
  479. lpgd = (LPGROUPDEF)GlobalLock(hNewGroup);
  480. lpid = ITEM(lpgd, i);
  481. lpid->pIconPath = offset;
  482. //
  483. // Get the item's icon resource using the Icon path and the icon index.
  484. // And add the item's Icon resource.
  485. //
  486. GlobalUnlock(hNewGroup);
  487. lpid->indexIcon = *((LPWORD)lpid16 + 2);
  488. if (!AddItemIconResource(hNewGroup, lpid, (WORD)i, lpT)) {
  489. KdPrint(("ConvGrp: AddItemIconResource failed for item %d \n", i));
  490. goto PuntCreation;
  491. }
  492. }
  493. /*
  494. * Copy all the tags to the new group format.
  495. */
  496. lptag16 = (LPSTR)lpGroup16 + lpGroup16->cbGroup;
  497. if (*(UNALIGNED WORD *)lptag16 == ID_MAGIC &&
  498. *((UNALIGNED WORD *)(lptag16+1)) == 0xFFFF &&
  499. *(UNALIGNED DWORD *)((UNALIGNED WORD *)(lptag16+3)) == PMTAG_MAGIC) {
  500. //
  501. // This is the first tag id, goto start of item tags.
  502. //
  503. lptag16 += *((LPWORD)lptag16+2);
  504. while (*(LPWORD)lptag16 != ID_LASTTAG) {
  505. wTagId = *(LPWORD)lptag16;
  506. if (wTagId == ID_MINIMIZE) {
  507. lpTagValue = NULL;
  508. }
  509. else {
  510. lpTagValue = (LPSTR)((LPWORD)lptag16 + 3);
  511. }
  512. if (! AddTag( hNewGroup,
  513. (int)*((LPWORD)lptag16 + 1), // wItem
  514. wTagId, // wID
  515. lpTagValue, // rgb : tag value
  516. *((LPWORD)lptag16 + 2) - (3 * sizeof(WORD)) // cb - sizeof tag
  517. )) {
  518. KdPrint(("ConvGrp: AddTag wItem=%d, wID=%d failed \n",
  519. *((LPWORD)lptag16 + 1),
  520. *(LPWORD)lptag16));
  521. }
  522. lptag16 += *((LPWORD)lptag16 + 2); // go to next tag
  523. }
  524. }
  525. lpgd = GlobalLock(hNewGroup);
  526. cb = SizeofGroup(lpgd);
  527. GlobalUnlock(hNewGroup);
  528. *lphNewGroup = hNewGroup;
  529. return(cb);
  530. PuntCreation:
  531. QuitThis:
  532. if (hNewGroup) {
  533. GlobalFree(hNewGroup);
  534. }
  535. return(0);
  536. }
  537. /*--------------------------------------------------------------------------*/
  538. /* */
  539. /* ReadGroup() - */
  540. /* */
  541. /* Read in the 16bit group file. */
  542. /* */
  543. /*--------------------------------------------------------------------------*/
  544. int ReadGroup(LPSTR pszPath, LPHANDLE lphGroup)
  545. {
  546. HANDLE hGroup;
  547. LPBYTE lpgd;
  548. int cbGroup;
  549. int fh;
  550. PSTR psz;
  551. //
  552. // Find and open the group file.
  553. //
  554. fh = _open(pszPath, O_RDONLY | O_BINARY);
  555. if (fh == -1) {
  556. KdPrint(("ConvGrp: Could NOT open file %s \n", pszPath));
  557. fprintf(stderr, "ConvGrp: Could NOT open file %s \n", pszPath);
  558. goto LGError1;
  559. }
  560. //
  561. // Find the size of the file by seeking to the end.
  562. //
  563. cbGroup = (WORD)_lseek(fh, 0L, SEEK_END);
  564. if (cbGroup < sizeof(GROUPDEF)) {
  565. KdPrint(("ConvGrp: bad group file - %s\n", pszPath));
  566. fprintf(stderr, "ConvGrp: bad group file - %s\n", pszPath);
  567. goto LGError2;
  568. }
  569. _lseek(fh, 0L, SEEK_SET);
  570. //
  571. // Allocate some memory for the thing.
  572. //
  573. if (!(hGroup = GlobalAlloc(GMEM_MOVEABLE|GMEM_DISCARDABLE, (DWORD)cbGroup))) {
  574. KdPrint(("ConvGrp: Alloc failed for input file %s\n", pszPath));
  575. psz = NULL;
  576. goto LGError2;
  577. }
  578. lpgd = (LPBYTE)GlobalLock(hGroup);
  579. //
  580. // Read the whole group file into memory.
  581. //
  582. if (_read(fh, (PSTR)lpgd, cbGroup) != cbGroup) {
  583. fprintf(stderr, "ConvGrp: Could NOT read file %s\n", pszPath);
  584. goto LGError3;
  585. }
  586. //
  587. // Validate the group file by checking the magic bytes and the checksum.
  588. //
  589. if (*((LPWORD)lpgd + 3) > (WORD)cbGroup) {
  590. fprintf(stderr, "ConvGrp: Invalid group file - %s\n", pszPath);
  591. goto LGError3;
  592. }
  593. if (*(LPDWORD)lpgd != GROUP_MAGIC) {
  594. fprintf(stderr, "ConvGrp: Invalid group file - %s\n", pszPath);
  595. goto LGError3;
  596. }
  597. //
  598. // Test if this is an NT .grp file
  599. //
  600. if ( (((LPGROUPDEF)lpgd)->rcNormal.left == (INT)(SHORT)((LPGROUPDEF)lpgd)->rcNormal.left) &&
  601. (((LPGROUPDEF)lpgd)->rcNormal.right == (INT)(SHORT)((LPGROUPDEF)lpgd)->rcNormal.right) &&
  602. (((LPGROUPDEF)lpgd)->rcNormal.top == (INT)(SHORT)((LPGROUPDEF)lpgd)->rcNormal.top) &&
  603. (((LPGROUPDEF)lpgd)->rcNormal.bottom == (INT)(SHORT)((LPGROUPDEF)lpgd)->rcNormal.bottom) ){
  604. //
  605. // it's an NT .grp file, not valid for conversion
  606. //
  607. fprintf(stderr, "ConvGrp: Invalid group file - %s\n", pszPath);
  608. goto LGError3;
  609. }
  610. _close(fh);
  611. GlobalUnlock(hGroup);
  612. *lphGroup = hGroup;
  613. return(cbGroup);
  614. LGError3:
  615. GlobalUnlock(hGroup);
  616. GlobalDiscard(hGroup);
  617. LGError2:
  618. _close(fh);
  619. LGError1:
  620. *lphGroup = NULL;
  621. return(0);
  622. }
  623. #define S_IREAD 0000400 /* read permission, owner */
  624. #define S_IWRITE 0000200 /* write permission, owner */
  625. /*--------------------------------------------------------------------------*/
  626. /* */
  627. /* Write32bitGroup() - */
  628. /* */
  629. /* Write out the 32bit group file. */
  630. /* */
  631. /*--------------------------------------------------------------------------*/
  632. BOOL Write32bitGroup(LPGROUPDEF lpgd, int cbGroup, LPSTR pszPath)
  633. {
  634. int fh;
  635. DWORD Error = 0;
  636. fh = _open(pszPath, O_CREAT | O_WRONLY | O_BINARY, S_IREAD | S_IWRITE);
  637. if (fh == -1) {
  638. Error = GetLastError();
  639. fprintf(stderr, "ConvGrp: Could NOT open output file - %s\n", pszPath);
  640. goto Exit1;
  641. }
  642. if (_write(fh, (PSTR)lpgd, cbGroup) != (int)cbGroup) {
  643. Error = GetLastError();
  644. fprintf(stderr, "ConvGrp: Could NOT write to output file - %s\n", pszPath);
  645. }
  646. _write(fh, NULL, 0); // truncate if getting smaller
  647. _close(fh);
  648. Exit1:
  649. if (Error) {
  650. KdPrint((" Error = %d \n", Error));
  651. }
  652. return (Error == 0);
  653. }
  654. int __cdecl main(
  655. int argc,
  656. char *argv[],
  657. char *envp[])
  658. {
  659. HANDLE h16bitGroup;
  660. HANDLE h32bitGroup;
  661. LPGROUPDEF16 lp16bitGroup;
  662. LPGROUPDEF lp32bitGroup;
  663. LPSTR lp16bitGroupFile;
  664. LPSTR lp32bitGroupFile;
  665. int cbGroup;
  666. BOOL bRet = FALSE;
  667. hInst = GetModuleHandle(NULL);
  668. //
  669. // We need the name of the 16bit .grp file and the name of the
  670. // 32bit .grp file. The first being the 16bit .grp file
  671. if (argc != 3) {
  672. fprintf(stderr, "ConvGrp: Invalid number of paramters, should have 2 filenames\n");
  673. fprintf(stderr, "\nusage: convgrp <Win3.1 .grp filename> <NT .grp filename>\n");
  674. return(FALSE);
  675. }
  676. //
  677. // The first argument is the name of the 16bit group file,
  678. // the second argument is the filename for the 32bit group file.
  679. //
  680. //
  681. lp16bitGroupFile = argv[1];
  682. lp32bitGroupFile = argv[2];
  683. cbGroup = ReadGroup(lp16bitGroupFile, &h16bitGroup);
  684. if (!cbGroup) {
  685. return(FALSE);
  686. }
  687. if (!(lp16bitGroup = (LPGROUPDEF16)GlobalLock(h16bitGroup))) {
  688. KdPrint(("ConvGrp: GlobalLock failed on %s\n", "h16bitGroup"));
  689. goto Exit;;
  690. }
  691. cbGroup = Create32bitGroupFormat(lp16bitGroup, cbGroup, &h32bitGroup);
  692. if (cbGroup) {
  693. lp32bitGroup = (LPGROUPDEF)GlobalLock(h32bitGroup);
  694. bRet = Write32bitGroup(lp32bitGroup, cbGroup, lp32bitGroupFile);
  695. GlobalUnlock(h32bitGroup);
  696. GlobalFree(h32bitGroup);
  697. }
  698. Exit:
  699. if (h16bitGroup) {
  700. GlobalFree(h16bitGroup);
  701. }
  702. if (bRet) {
  703. fprintf(stderr, "ConvGrp: group successfully converted\n");
  704. }
  705. return(bRet);
  706. }