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.

1009 lines
32 KiB

  1. /****************************************************************************
  2. PROGRAM: grptoreg
  3. PURPOSE: Move the Program Manager's group files (*.GRP) to the
  4. registry. Also updates the Program Manager's settings that are
  5. in progman.ini.
  6. This program needs to be run in the directory where the .grp
  7. and progman.ini files reside. It uses progman.ini to update the
  8. registry, only the group files named in progman.ini will
  9. be entered into the registry.
  10. Once this program is run, all that needs to be done is:
  11. Logoff, then logon again.
  12. FUNCTIONS:
  13. COMMENTS:
  14. Most of the functions were extracted from the Program Manager.
  15. If the group fromat changes in the Progam Manager, the same
  16. changes must be done here (and in grptoreg.h). Same thing
  17. applies where in the registry this information is to be
  18. stored/read.
  19. MODIFICATION HISTORY
  20. Created: 4/10/92 JohanneC
  21. ****************************************************************************/
  22. #include <nt.h>
  23. #include <ntrtl.h>
  24. #include <nturtl.h>
  25. #include "grptoreg.h"
  26. BOOL SaveGroupInRegistry(PGROUP pGroup, BOOL bCommonGrp, BOOL bOverwriteGroup);
  27. /*--------------------------------------------------------------------------*/
  28. /* */
  29. /* MyDwordAlign() - */
  30. /* */
  31. /*--------------------------------------------------------------------------*/
  32. INT MyDwordAlign(INT wStrLen)
  33. {
  34. return ((wStrLen + 3) & ~3);
  35. }
  36. /*--------------------------------------------------------------------------*/
  37. /* */
  38. /* SizeofGroup_U() - for unicode groups */
  39. /* */
  40. /*--------------------------------------------------------------------------*/
  41. DWORD PASCAL SizeofGroup_U(LPGROUPDEF_U lpgd)
  42. {
  43. LPPMTAG lptag;
  44. DWORD cbSeg;
  45. DWORD cb;
  46. cbSeg = GlobalSize(lpgd);
  47. lptag = (LPPMTAG)((LPSTR)lpgd+lpgd->cbGroup);
  48. if ((DWORD)((PCHAR)lptag - (PCHAR)lpgd +MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb))+4) <= cbSeg
  49. && lptag->wID == ID_MAGIC
  50. && lptag->wItem == (int)0xFFFF
  51. && lptag->cb == (WORD)(MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb)) + 4)
  52. && *(PLONG)lptag->rgb == TAG_MAGIC)
  53. {
  54. while ((cb = (DWORD)((PCHAR)lptag - (PCHAR)lpgd + MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb)))) <= cbSeg)
  55. {
  56. if (lptag->wID == ID_LASTTAG)
  57. return cb;
  58. (LPSTR)lptag += lptag->cb;
  59. }
  60. }
  61. return lpgd->cbGroup;
  62. }
  63. /*--------------------------------------------------------------------------*/
  64. /* */
  65. /* SizeofGroup() - for ansi groups */
  66. /* */
  67. /*--------------------------------------------------------------------------*/
  68. DWORD SizeofGroup(LPGROUPDEF lpgd)
  69. {
  70. LPPMTAG lptag;
  71. WORD cbSeg;
  72. WORD cb;
  73. cbSeg = (WORD)GlobalSize(lpgd);
  74. lptag = (LPPMTAG)((LPSTR)lpgd+lpgd->cbGroup);
  75. if ((WORD)((PCHAR)lptag - (PCHAR)lpgd +MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb))+4) <= cbSeg
  76. && lptag->wID == ID_MAGIC
  77. && lptag->wItem == (int)0xFFFF
  78. && lptag->cb == (WORD)(MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb)) + 4)
  79. && *(PLONG)lptag->rgb == TAG_MAGIC) {
  80. while ((cb = (WORD)((PCHAR)lptag - (PCHAR)lpgd + MyDwordAlign(sizeof(PMTAG))-MyDwordAlign(sizeof(lptag->rgb)))) <= cbSeg) {
  81. if (lptag->wID == ID_LASTTAG)
  82. return (DWORD)cb;
  83. (LPSTR)lptag += lptag->cb;
  84. }
  85. }
  86. return lpgd->cbGroup;
  87. }
  88. /*--------------------------------------------------------------------------*/
  89. /* */
  90. /* IsGroup() - */
  91. /* */
  92. /*--------------------------------------------------------------------------*/
  93. BOOL PASCAL IsGroup(PSTR p)
  94. {
  95. if (_strnicmp(p, "GROUP", CCHGROUP) != 0) {;
  96. return FALSE;
  97. }
  98. /*
  99. * Can't have 0 for first digit
  100. */
  101. if (p[5] == '0') {
  102. return FALSE;
  103. }
  104. /*
  105. * Everything else must be a number
  106. */
  107. for (p += CCHGROUP; *p; p++) {
  108. if (*p < '0' || *p > '9') {
  109. return FALSE;
  110. }
  111. }
  112. return TRUE;
  113. }
  114. /*--------------------------------------------------------------------------*/
  115. /* */
  116. /* RemoveString() - */
  117. /* */
  118. /*--------------------------------------------------------------------------*/
  119. VOID APIENTRY RemoveString(PSTR pString)
  120. {
  121. PSTR pT = pString + lstrlen(pString) + 1;
  122. while (*pT)
  123. {
  124. while (*pString++ = *pT++)
  125. ;
  126. }
  127. *pString = 0;
  128. }
  129. /*--------------------------------------------------------------------------*/
  130. /* */
  131. /* StringToEnd() - */
  132. /* */
  133. /*--------------------------------------------------------------------------*/
  134. VOID APIENTRY StringToEnd(PSTR pString)
  135. {
  136. char *pT,*pTT;
  137. for (pT = pString; *pT; )
  138. while (*pT++)
  139. ;
  140. for (pTT = pString; *pT++ = *pTT++;)
  141. ;
  142. *pT = 0;
  143. RemoveString(pString);
  144. }
  145. /*--------------------------------------------------------------------------*/
  146. /* */
  147. /* GetGroupList() - */
  148. /* */
  149. /*--------------------------------------------------------------------------*/
  150. VOID PASCAL GetGroupList(PSTR szList)
  151. {
  152. char szT[20];
  153. PSTR pT, pTT, pS;
  154. INT cGroups; // The number of Groups= lines.
  155. GetPrivateProfileString(szGroups, NULL, szNULL, szList, (CGROUPSMAX+1)*8, szINIFile);
  156. cGroups = 0;
  157. /*
  158. * Filter out anything that isn't group#.
  159. */
  160. for (pT = szList; *pT; ) {
  161. AnsiUpper(pT);
  162. if (IsGroup(pT)) {
  163. pT += lstrlen(pT) + 1;
  164. cGroups++;
  165. } else {
  166. RemoveString(pT);
  167. }
  168. }
  169. /*
  170. * Sort the groups
  171. */
  172. lstrcpy(szT, "Group");
  173. for (pT = szGroupsOrder; *pT; ) {
  174. while (*pT == ' ') {
  175. pT++;
  176. }
  177. if (*pT < '0' || *pT > '9') {
  178. break;
  179. }
  180. pTT = szT + CCHGROUP;
  181. while (*pT >= '0' && *pT <= '9') {
  182. *pTT++ = *pT++;
  183. }
  184. *pTT=0;
  185. for (pS = szList; *pS; pS += lstrlen(pS) + 1) {
  186. if (!lstrcmpi(pS,szT)) {
  187. StringToEnd(pS);
  188. cGroups--;
  189. break;
  190. }
  191. }
  192. }
  193. /*
  194. * Move any remaining groups to the end of the list so that they load
  195. * last and appear on top of everything else - keeps DOS based install
  196. * programs happy.
  197. */
  198. while (cGroups>0) {
  199. StringToEnd(szList);
  200. cGroups--;
  201. }
  202. }
  203. /*--------------------------------------------------------------------------*/
  204. /* */
  205. /* CreateGroupHandle() - */
  206. /* */
  207. /* Creates a discarded handle for use as a group handle... on the first */
  208. /* LockGroup() the file will be loaded. */
  209. /* */
  210. /*--------------------------------------------------------------------------*/
  211. HANDLE PASCAL CreateGroupHandle(void)
  212. {
  213. HANDLE hGroup;
  214. if (hGroup = GlobalAlloc(GMEM_MOVEABLE | GMEM_DISCARDABLE, 1L))
  215. GlobalDiscard(hGroup);
  216. return(hGroup);
  217. }
  218. /*--------------------------------------------------------------------------*/
  219. /* */
  220. /* LockGroup() - */
  221. /* */
  222. /*--------------------------------------------------------------------------*/
  223. LPGROUPDEF PASCAL LockGroup(PGROUP pGroup)
  224. {
  225. LPGROUPDEF lpgd;
  226. int cbGroup;
  227. int fh;
  228. PSTR psz;
  229. psz = pGroup->lpKey;
  230. /* Find and open the group file. */
  231. fh = _open(pGroup->lpKey, O_RDONLY | O_BINARY);
  232. if (fh == -1) {
  233. goto LGError1;
  234. }
  235. /* Find the size of the file by seeking to the end. */
  236. cbGroup = (WORD)_lseek(fh, 0L, SEEK_END);
  237. if (cbGroup < sizeof(GROUPDEF)) {
  238. goto LGError2;
  239. }
  240. _lseek(fh, 0L, SEEK_SET);
  241. /* Allocate some memory for the thing. */
  242. if (!(pGroup->hGroup = GlobalReAlloc(pGroup->hGroup, (DWORD)cbGroup, GMEM_MOVEABLE))) {
  243. psz = NULL;
  244. goto LGError2;
  245. }
  246. lpgd = (LPGROUPDEF)GlobalLock(pGroup->hGroup);
  247. /* Read the whole group file into memory. */
  248. if (_read(fh, (PSTR)lpgd, cbGroup) != cbGroup)
  249. goto LGError3;
  250. if (lpgd->dwMagic == GROUP_MAGIC) {
  251. /* Validate the group file by checking the magic bytes and the checksum. */
  252. if (lpgd->cbGroup > (WORD)cbGroup)
  253. goto LGError3;
  254. }
  255. else if (lpgd->dwMagic == GROUP_UNICODE) {
  256. LPGROUPDEF_U lpgd_U;
  257. lpgd_U = (LPGROUPDEF_U)lpgd;
  258. if (lpgd_U->cbGroup > (DWORD)cbGroup) {
  259. goto LGError3;
  260. }
  261. }
  262. else {
  263. goto LGError3;
  264. }
  265. /* Now return the pointer. */
  266. _close(fh);
  267. return(lpgd);
  268. LGError3:
  269. GlobalUnlock(pGroup->hGroup);
  270. GlobalDiscard(pGroup->hGroup);
  271. LGError2:
  272. _close(fh);
  273. LGError1:
  274. return(NULL);
  275. }
  276. /*--------------------------------------------------------------------------*/
  277. /* */
  278. /* UnlockGroup() - */
  279. /* */
  280. /*--------------------------------------------------------------------------*/
  281. void PASCAL UnlockGroup(PGROUP pGroup)
  282. {
  283. GlobalUnlock(pGroup->hGroup);
  284. }
  285. /*--------------------------------------------------------------------------*/
  286. /* */
  287. /* FindFreeIndex() - */
  288. /* */
  289. /*--------------------------------------------------------------------------*/
  290. WORD FindFreeIndex(BOOL bCommonGrp)
  291. {
  292. WORD wIndex;
  293. LPSTR pszT;
  294. WORD i;
  295. static BOOL bFirstTime = TRUE;
  296. DWORD cbData;
  297. if (!*szGroupsOrder) {
  298. cbData = sizeof(szGroupsOrder);
  299. if (RegQueryValueEx(hkeyPMSettings, szOrder, 0, 0, szGroupsOrder, &cbData))
  300. if (!GetPrivateProfileString(szSettings, szOrder, szNULL, szGroupsOrder, sizeof(szGroupsOrder), szINIFile)) {
  301. pGroupIndexes[1] = 1;
  302. return(1);
  303. }
  304. }
  305. if (bFirstTime) {
  306. bFirstTime = FALSE;
  307. /* Initialize the array to zero since we are 1 based */
  308. for (i = 1; i <= CGROUPSMAX; i++) {
  309. pGroupIndexes[i] = 0;
  310. }
  311. pszT = szGroupsOrder;
  312. while(*pszT) {
  313. /* Skip blanks */
  314. while (*pszT == ' ')
  315. pszT++;
  316. /* Check for NULL */
  317. if (!(*pszT))
  318. break;
  319. if ( (bCommonGrp && *pszT == 'C') ||
  320. (!bCommonGrp && *pszT != 'C') ) {
  321. if (bCommonGrp)
  322. pszT++;
  323. wIndex = 0;
  324. for (; *pszT && *pszT!=' '; pszT++) {
  325. wIndex *= 10;
  326. wIndex += *pszT - '0';
  327. }
  328. pGroupIndexes[wIndex] = wIndex;
  329. } else {
  330. /* Skip to next entry */
  331. while (*pszT && *pszT != ' ')
  332. pszT++;
  333. }
  334. }
  335. }
  336. for (i = 1; i <= CGROUPSMAX; i++) {
  337. if (pGroupIndexes[i] != i) {
  338. pGroupIndexes[i] = i;
  339. return(i);
  340. }
  341. }
  342. if (i > CGROUPSMAX) { // too many groups
  343. return((WORD)-1);
  344. }
  345. }
  346. /*--------------------------------------------------------------------------*/
  347. /* */
  348. /* RemoveBackslashFromKeyName() - */
  349. /* */
  350. /* replace the invalid characters for a key name by some valid charater. */
  351. /* the same characters that are invalid for a file name are invalid for a */
  352. /* key name. */
  353. /* */
  354. /*--------------------------------------------------------------------------*/
  355. void RemoveBackslashFromKeyName(LPSTR lpKeyName)
  356. {
  357. LPSTR lpt;
  358. for (lpt = lpKeyName; *lpt; lpt++) {
  359. if ((*lpt == '\\') || (*lpt == ':') || (*lpt == '>') || (*lpt == '<') ||
  360. (*lpt == '*') || (*lpt == '?') ){
  361. *lpt = '.';
  362. }
  363. }
  364. }
  365. /*--------------------------------------------------------------------------*/
  366. /* */
  367. /* LoadGroup() - */
  368. /* */
  369. /*--------------------------------------------------------------------------*/
  370. PGROUP PASCAL LoadGroup(PSTR pGroupFile, WORD wIndex, BOOL bCommonGrp)
  371. {
  372. PGROUP pGroup;
  373. LPGROUPDEF lpgd;
  374. char szFmt[] = " %d";
  375. char szCFmt[] = " C%d";
  376. char szIndex[5];
  377. BOOL bNewOrder = FALSE;
  378. if (!wIndex) {
  379. wIndex = FindFreeIndex(bCommonGrp);
  380. bNewOrder = TRUE;
  381. }
  382. pGroup = (PGROUP)LocalAlloc(LPTR,sizeof(GROUP));
  383. if (!pGroup) {
  384. return NULL;
  385. }
  386. pGroup->hGroup = CreateGroupHandle();
  387. pGroup->pItems = NULL;
  388. pGroup->hbm = NULL;
  389. pGroup->wIndex = wIndex;
  390. pGroup->lpKey = (PSTR)LocalAlloc(LPTR, lstrlen(pGroupFile) + 1);
  391. pGroup->fLoaded = FALSE;
  392. if (!pGroup->lpKey) {
  393. GlobalFree(pGroup->hGroup);
  394. LocalFree((HANDLE)pGroup);
  395. return NULL;
  396. }
  397. lstrcpy(pGroup->lpKey, pGroupFile);
  398. /*
  399. * Note that we're about to load a group for the first time.
  400. * NB Stting this tells LockGroup that the caller can handle the errors.
  401. */
  402. lpgd = LockGroup(pGroup);
  403. /*
  404. * The group has been loaded or at least we tried.
  405. */
  406. if (!lpgd) {
  407. LoadFail:
  408. LocalFree((HANDLE)pGroup->lpKey);
  409. GlobalFree(pGroup->hGroup);
  410. LocalFree((HANDLE)pGroup);
  411. return NULL;
  412. }
  413. /*
  414. * test if it is a Windows 3.1 group file format. If so it is not
  415. * valid in WIN32. In Windows 3.1 RECT and POINT are WORD instead of LONG.
  416. */
  417. if ( lpgd->dwMagic == GROUP_MAGIC &&
  418. ((lpgd->rcNormal.left != (INT)(SHORT)lpgd->rcNormal.left) ||
  419. (lpgd->rcNormal.right != (INT)(SHORT)lpgd->rcNormal.right) ||
  420. (lpgd->rcNormal.top != (INT)(SHORT)lpgd->rcNormal.top) ||
  421. (lpgd->rcNormal.bottom != (INT)(SHORT)lpgd->rcNormal.bottom) )){
  422. /* The group file is invalid. */
  423. UnlockGroup(pGroup);
  424. goto LoadFail;
  425. }
  426. /*
  427. * In the registry, the group's key is it's title.
  428. */
  429. if (lpgd->dwMagic == GROUP_MAGIC) {
  430. LocalFree(pGroup->lpKey);
  431. if (pGroup->lpKey = (PSTR)LocalAlloc(LPTR, lstrlen(PTR(lpgd, lpgd->pName)) + 1))
  432. lstrcpy(pGroup->lpKey, PTR(lpgd, lpgd->pName));
  433. RemoveBackslashFromKeyName(pGroup->lpKey);
  434. }
  435. else if (lpgd->dwMagic == GROUP_UNICODE){
  436. LPGROUPDEF_U lpgd_U;
  437. ANSI_STRING AnsiString;
  438. UNICODE_STRING UniString;
  439. lpgd_U = (LPGROUPDEF_U)lpgd;
  440. RtlInitUnicodeString(&UniString, (LPWSTR)(PTR(lpgd_U, lpgd_U->pName)));
  441. RtlUnicodeStringToAnsiString(&AnsiString, &UniString, TRUE);
  442. LocalFree(pGroup->lpKey);
  443. if (pGroup->lpKey = (PSTR)LocalAlloc(LPTR, lstrlen(AnsiString.Buffer) + 1))
  444. lstrcpy(pGroup->lpKey, AnsiString.Buffer);
  445. RemoveBackslashFromKeyName(pGroup->lpKey);
  446. RtlFreeAnsiString(&AnsiString);
  447. }
  448. UnlockGroup(pGroup);
  449. if (bNewOrder) {
  450. if (bCommonGrp)
  451. wsprintf(szIndex, szCFmt, wIndex);
  452. else
  453. wsprintf(szIndex, szFmt, wIndex);
  454. lstrcat(szGroupsOrder, szIndex);
  455. RegSetValueEx(hkeyPMSettings, szOrder, 0, REG_SZ, szGroupsOrder,
  456. lstrlen(szGroupsOrder)+1);
  457. }
  458. return(pGroup);
  459. }
  460. /*--------------------------------------------------------------------------*/
  461. /* */
  462. /* UnloadGroup() - */
  463. /* */
  464. /*--------------------------------------------------------------------------*/
  465. void PASCAL UnloadGroup(PGROUP pGroup)
  466. {
  467. PITEM pItem, pItemNext;
  468. // Free the group segment.
  469. GlobalFree(pGroup->hGroup);
  470. // Free the local stuff.
  471. LocalFree((HANDLE)pGroup->lpKey);
  472. // The item data.
  473. for (pItem = pGroup->pItems; pItem; pItem = pItemNext) {
  474. pItemNext = pItem->pNext;
  475. LocalFree((HANDLE) pItem);
  476. }
  477. // Lastly, free the group structure itself.
  478. LocalFree((HANDLE)pGroup);
  479. }
  480. /*--------------------------------------------------------------------------*/
  481. /* */
  482. /* LoadAllGroups() - */
  483. /* */
  484. /*--------------------------------------------------------------------------*/
  485. VOID PASCAL LoadAllGroups()
  486. {
  487. PSTR pT, pszT;
  488. char szGroupList[(CGROUPSMAX+1)*8];
  489. WORD wIndex;
  490. char szPath[120];
  491. PGROUP pGroup;
  492. pT = szGroupList;
  493. for (GetGroupList(pT); *pT; pT += (lstrlen(pT) + 1)) {
  494. if (!GetPrivateProfileString(szGroups, pT, szNULL, szPath,
  495. sizeof(szPath), szINIFile)) {
  496. continue;
  497. }
  498. wIndex = 0;
  499. for (pszT = pT + CCHGROUP; *pszT; pszT++) {
  500. wIndex *= 10;
  501. wIndex += *pszT - '0';
  502. }
  503. pGroup = LoadGroup(szPath, wIndex, FALSE);
  504. if (pGroup) {
  505. SaveGroupInRegistry(pGroup, FALSE, FALSE);
  506. UnloadGroup(pGroup);
  507. }
  508. else {
  509. bNoError = FALSE;
  510. wsprintf(szMessage, "An error has occurred reading group file %s, no registry update.\n",
  511. szPath);
  512. printf(szMessage);
  513. }
  514. }
  515. }
  516. /*--------------------------------------------------------------------------*/
  517. /* */
  518. /* SaveGroupInRegistry() - */
  519. /* */
  520. /*--------------------------------------------------------------------------*/
  521. BOOL SaveGroupInRegistry(PGROUP pGroup, BOOL bCommonGrp, BOOL bOverwriteGroup)
  522. {
  523. LPGROUPDEF lpgd;
  524. int cb;
  525. int err;
  526. char szT[66];
  527. static char szFmt[] = "Group%d";
  528. HKEY hkey;
  529. HKEY hkeyGroups;
  530. PSECURITY_ATTRIBUTES pSecAttr;
  531. DWORD dwDisposition;
  532. HANDLE hEvent;
  533. lpgd = (LPGROUPDEF)GlobalLock(pGroup->hGroup);
  534. if (!lpgd)
  535. return FALSE;
  536. if (bCommonGrp) {
  537. hkeyGroups = hkeyCommonGroups;
  538. pSecAttr = pCGrpSecAttr;
  539. }
  540. else {
  541. hkeyGroups = hkeyProgramGroups;
  542. pSecAttr = pPGrpSecAttr;
  543. }
  544. while(1) {
  545. if (err = RegCreateKeyEx(hkeyGroups, pGroup->lpKey, 0, 0, 0,
  546. DELETE | KEY_READ | KEY_WRITE, pSecAttr,
  547. &hkey, &dwDisposition)) {
  548. goto Exit1;
  549. }
  550. if (dwDisposition == REG_CREATED_NEW_KEY) {
  551. break;
  552. }
  553. if (dwDisposition == REG_OPENED_EXISTING_KEY) {
  554. if (!bOverwriteGroup) {
  555. RegCloseKey(hkey);
  556. wsprintf(szMessage, "Could not save the group %s in the registry. The group already exists.", pGroup->lpKey);
  557. printf(szMessage);
  558. return(FALSE);
  559. }
  560. else {
  561. RegCloseKey(hkey);
  562. if (RegDeleteKey(hkeyGroups, pGroup->lpKey) != ERROR_SUCCESS) {
  563. wsprintf(szMessage, "Could not save the group %s in the registry. The group already exists.", pGroup->lpKey);
  564. printf(szMessage);
  565. return(FALSE);
  566. }
  567. }
  568. }
  569. }
  570. /* update groups section. */
  571. wsprintf(szT, szFmt, pGroup->wIndex);
  572. RegSetValueEx(hkeyPMGroups, szT, 0, REG_SZ, (LPBYTE)pGroup->lpKey, lstrlen(pGroup->lpKey)+1);
  573. if (lpgd->dwMagic == GROUP_MAGIC) {
  574. cb = SizeofGroup(lpgd);
  575. }
  576. else {
  577. cb = SizeofGroup_U((LPGROUPDEF_U)lpgd);
  578. }
  579. err = RegSetValueEx(hkey, NULL, 0, REG_BINARY, (LPTSTR)lpgd, cb);
  580. hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, "Progman.GroupValueSet");
  581. if (hEvent) {
  582. SetEvent(hEvent);
  583. }
  584. RegFlushKey(hkey);
  585. RegCloseKey(hkey);
  586. Exit1:
  587. GlobalUnlock(pGroup->hGroup);
  588. if (err) {
  589. bNoError = FALSE;
  590. wsprintf(szMessage, "Could not save the group %s in the registry.", pGroup->lpKey);
  591. printf(szMessage);
  592. }
  593. GlobalDiscard(pGroup->hGroup);
  594. return(!err);
  595. }
  596. /*--------------------------------------------------------------------------*/
  597. /* */
  598. /* ReadSettings() - */
  599. /* */
  600. /*--------------------------------------------------------------------------*/
  601. BOOL ReadSettings()
  602. {
  603. OFSTRUCT of;
  604. CHAR szT[MAX_PATH];
  605. lstrcpy(szT, ".\\");
  606. lstrcat(szT, szINIFile);
  607. if (OpenFile(szT, &of, OF_EXIST) == -1) {
  608. // set the current directory to the windows directory
  609. GetWindowsDirectory(szT, MAX_PATH);
  610. SetCurrentDirectory(szT);
  611. }
  612. if (OpenFile(szINIFile, &of, OF_EXIST) == -1) {
  613. return(FALSE);
  614. }
  615. bMinOnRun = GetPrivateProfileInt(szSettings, szMinOnRun, bMinOnRun, szINIFile);
  616. bAutoArrange = GetPrivateProfileInt(szSettings, szAutoArrange, bAutoArrange, szINIFile);
  617. bSaveSettings = GetPrivateProfileInt(szSettings, szSaveSettings, bSaveSettings, szINIFile);
  618. GetPrivateProfileString(szSettings, szWindow, szNULL, szPMWindowSetting, sizeof(szPMWindowSetting), szINIFile);
  619. GetPrivateProfileString(szSettings, szStartup, szNULL, szStartupGroup, sizeof(szStartupGroup), szINIFile);
  620. fNoRun = GetPrivateProfileInt(szRestrict, szNoRun, FALSE, szINIFile);
  621. fNoClose = GetPrivateProfileInt(szRestrict, szNoClose, FALSE, szINIFile);
  622. fNoSave = GetPrivateProfileInt(szRestrict, szNoSave, FALSE, szINIFile);
  623. fNoFileMenu = GetPrivateProfileInt(szRestrict, szNoFileMenu, FALSE, szINIFile);
  624. dwEditLevel = GetPrivateProfileInt(szRestrict, szEditLevel, (WORD)0, szINIFile);
  625. GetPrivateProfileString(szSettings, szOrder, szNULL, szGroupsOrder, sizeof(szGroupsOrder), szINIFile);
  626. return(TRUE);
  627. }
  628. /*--------------------------------------------------------------------------*/
  629. /* */
  630. /* SaveSettingsToRegistry() - */
  631. /* */
  632. /*--------------------------------------------------------------------------*/
  633. BOOL SaveSettingsToRegistry()
  634. {
  635. int err;
  636. if (hkeyPMSettings) {
  637. err = RegSetValueEx(hkeyPMSettings, szWindow, 0, REG_SZ, szPMWindowSetting,
  638. lstrlen(szPMWindowSetting)+1);
  639. err |= RegSetValueEx(hkeyPMSettings, szOrder, 0, REG_SZ, szGroupsOrder,
  640. lstrlen(szGroupsOrder)+1);
  641. if (*szStartupGroup)
  642. err |= RegSetValueEx(hkeyPMSettings, szStartup, 0, REG_SZ, szStartupGroup,
  643. lstrlen(szStartupGroup)+1);
  644. err |= RegSetValueEx(hkeyPMSettings, szMinOnRun, 0, REG_DWORD,
  645. (LPBYTE)&bMinOnRun, sizeof(bMinOnRun));
  646. err |= RegSetValueEx(hkeyPMSettings, szAutoArrange, 0, REG_DWORD,
  647. (LPBYTE)&bAutoArrange, sizeof(bAutoArrange));
  648. err |= RegSetValueEx(hkeyPMSettings, szSaveSettings, 0, REG_DWORD,
  649. (LPBYTE)&bSaveSettings, sizeof(bSaveSettings));
  650. }
  651. if (hkeyPMRestrict) {
  652. err = RegSetValueEx(hkeyPMRestrict, szNoRun, 0, REG_DWORD,
  653. (LPBYTE)&fNoRun, sizeof(fNoRun));
  654. err |= RegSetValueEx(hkeyPMRestrict, szNoClose, 0, REG_DWORD,
  655. (LPBYTE)&fNoClose, sizeof(fNoClose));
  656. err |= RegSetValueEx(hkeyPMRestrict, szNoSave, 0, REG_DWORD,
  657. (LPBYTE)&fNoSave, sizeof(fNoSave));
  658. err |= RegSetValueEx(hkeyPMRestrict, szNoFileMenu, 0, REG_DWORD,
  659. (LPBYTE)&fNoFileMenu, sizeof(fNoFileMenu));
  660. err |= RegSetValueEx(hkeyPMRestrict, szEditLevel, 0, REG_DWORD,
  661. (LPBYTE)&dwEditLevel, sizeof(dwEditLevel));
  662. }
  663. return(!err);
  664. }
  665. BOOL AccessToPersonalGroups()
  666. {
  667. //
  668. // Initialize security attributes for Personal Groups.
  669. //
  670. pPGrpSecAttr = &PGrpSecAttr;
  671. if (!InitializeSecurityAttributes(pPGrpSecAttr, FALSE))
  672. pPGrpSecAttr = NULL;
  673. /*
  674. * Create/Open the registry keys corresponding to progman.ini sections.
  675. */
  676. if (RegCreateKeyEx(HKEY_CURRENT_USER, szProgramManager, 0, szProgramManager, 0,
  677. KEY_READ | KEY_WRITE,
  678. pPGrpSecAttr, &hkeyProgramManager, NULL)) {
  679. return(FALSE);
  680. }
  681. RegCreateKeyEx(hkeyProgramManager, szSettings, 0, szProgramManager, 0,
  682. KEY_READ | KEY_WRITE,
  683. pPGrpSecAttr, &hkeyPMSettings, NULL);
  684. RegCreateKeyEx(hkeyProgramManager, szRestrict, 0, szProgramManager, 0,
  685. KEY_READ,
  686. pPGrpSecAttr, &hkeyPMRestrict, NULL);
  687. RegCreateKeyEx(hkeyProgramManager, szGroups, 0, szProgramManager, 0,
  688. KEY_READ | KEY_WRITE,
  689. pPGrpSecAttr, &hkeyPMGroups, NULL);
  690. if (RegCreateKeyEx(HKEY_CURRENT_USER, szProgramGroups, 0, szProgramGroups, 0,
  691. KEY_READ | KEY_WRITE,
  692. pPGrpSecAttr, &hkeyProgramGroups, NULL) ){
  693. return(FALSE);
  694. }
  695. return(TRUE);
  696. }
  697. BOOL AccessToCommonGroups()
  698. {
  699. //
  700. // Initialize security attributes for Common Groups.
  701. //
  702. pCGrpSecAttr = &CGrpSecAttr;
  703. if (!InitializeSecurityAttributes(pCGrpSecAttr, TRUE)) {
  704. pCGrpSecAttr = NULL;
  705. return(FALSE);
  706. }
  707. if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szCommonGroups, 0, szProgramGroups, 0,
  708. KEY_READ | KEY_WRITE | DELETE,
  709. pCGrpSecAttr, &hkeyCommonGroups, NULL) ){
  710. return(FALSE);
  711. }
  712. return(TRUE);
  713. }
  714. void Usage()
  715. {
  716. printf("\nConverts a Windows NT compatible .GRP file into the Registry for use by\n\
  717. Windows NT. Note that the .GRP file must have been created using REGTOGRP.\n\
  718. GRPTOREG will not accept MS-DOS Windows .GRP files.\n\n\
  719. GRPTOREG [/o] [/c] groupfiles \n\n\
  720. groupfiles Path to a .GRP file created by REGTOGRP. If more than one file,\n\
  721. separate by spaces.\n\
  722. /o If a Program Manager group already exists with the same name as\n\
  723. groupfile, overwrite it.\n\
  724. /c Will create a Common group from the groupfile (must have \n\
  725. administrative privileges), otherwise a personal group is created.\n");
  726. }
  727. int __cdecl
  728. main( argc, argv )
  729. int argc;
  730. char *argv[];
  731. {
  732. INT i;
  733. CHAR *cp;
  734. LPSTR pGroupFile;
  735. PGROUP pGroup;
  736. BOOL bCommonGrp = FALSE;
  737. BOOL bOverwriteGroup = FALSE;
  738. if (argc > 1) { // just update specified groups.
  739. for(i = 1; i < argc && (argv[i][0] == '/' || argv[i][0] == '-'); ++i) {
  740. for(cp = &argv[i][1]; *cp != '\0'; ++cp) {
  741. switch(*cp) {
  742. case 'c':
  743. //
  744. // The user wants common groups.
  745. // First check if the user has permission to create common groups.
  746. //
  747. if (AccessToCommonGroups()) {
  748. bCommonGrp = TRUE;
  749. }
  750. else {
  751. wsprintf(szMessage, "You do not have write access to Common Groups. No Groups will be created.");
  752. printf(szMessage);
  753. goto Exit;
  754. }
  755. break;
  756. case 'o':
  757. bOverwriteGroup = TRUE;
  758. break;
  759. case '?':
  760. default:
  761. Usage();
  762. goto Exit;
  763. }
  764. }
  765. }
  766. if (!bCommonGrp) {
  767. //
  768. // The user wants personal groups.
  769. // First check if the user has access to the registry to
  770. // create personal groups in Progman.
  771. //
  772. if (!AccessToPersonalGroups()) {
  773. wsprintf(szMessage, "You do not have write access to the registry. No updates will take place.");
  774. printf(szMessage);
  775. goto Exit;
  776. }
  777. }
  778. for (; i < argc; i++) {
  779. pGroupFile = argv[i];
  780. pGroup = LoadGroup(pGroupFile, 0, bCommonGrp);
  781. if (pGroup) {
  782. SaveGroupInRegistry(pGroup, bCommonGrp, bOverwriteGroup);
  783. UnloadGroup(pGroup);
  784. }
  785. else {
  786. bNoError = FALSE;
  787. wsprintf(szMessage, "An error has occurred reading group file %s, no registry update.",
  788. pGroupFile);
  789. printf(szMessage);
  790. }
  791. }
  792. }
  793. else
  794. { // update all groups thru progman.ini
  795. if (hkeyProgramManager) {
  796. if (!ReadSettings()) {
  797. bNoError = FALSE;
  798. wsprintf(szMessage, "The file PROGMAN.INI is not in this directory.");
  799. printf(szMessage);
  800. }
  801. if (bNoError && !SaveSettingsToRegistry()) {
  802. // wsprintf(szMessage, "An error occured while saving settings to the registry.");
  803. }
  804. }
  805. if (hkeyProgramGroups) {
  806. bNoError = TRUE;
  807. LoadAllGroups();
  808. if (bNoError) {
  809. wsprintf(szMessage, "Groups were updated successfully to the registry.");
  810. printf(szMessage);
  811. }
  812. }
  813. }
  814. Exit:
  815. if (hkeyProgramManager) {
  816. RegFlushKey(hkeyProgramManager);
  817. if (hkeyPMSettings)
  818. RegCloseKey(hkeyPMSettings);
  819. if (hkeyPMRestrict)
  820. RegCloseKey(hkeyPMRestrict);
  821. if (hkeyPMGroups)
  822. RegCloseKey(hkeyPMGroups);
  823. if (hkeyProgramManager)
  824. RegCloseKey(hkeyProgramManager);
  825. }
  826. if (hkeyProgramGroups) {
  827. RegFlushKey(hkeyProgramGroups);
  828. RegCloseKey(hkeyProgramGroups);
  829. }
  830. if (hkeyCommonGroups) {
  831. RegFlushKey(hkeyCommonGroups);
  832. RegCloseKey(hkeyCommonGroups);
  833. }
  834. //
  835. // Free up the security descriptor
  836. //
  837. if (pPGrpSecAttr) {
  838. DeleteSecurityDescriptor(pPGrpSecAttr->lpSecurityDescriptor);
  839. }
  840. if (pCGrpSecAttr) {
  841. DeleteSecurityDescriptor(pCGrpSecAttr->lpSecurityDescriptor);
  842. }
  843. return(TRUE);
  844. }