Leaked source code of windows server 2003
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.

673 lines
23 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1991 **/
  4. /**********************************************************************/
  5. /*
  6. setvalue.c
  7. Code to enable SetValue for everyone.
  8. history:
  9. terryk 09/30/93 Created
  10. */
  11. #if defined(DEBUG)
  12. static const char szFileName[] = __FILE__;
  13. #define _FILENAME_DEFINED_ONCE szFileName
  14. #endif
  15. #include <string.h>
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. #include <windows.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <nwapi.h>
  23. #include <nwcfg.h>
  24. #include <nwcfg.hxx>
  25. extern char achBuff[];
  26. // exported functions
  27. BOOL FAR PASCAL SetFileSysChangeValue( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
  28. BOOL FAR PASCAL SetEverybodyPermission( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
  29. BOOL FAR PASCAL SetupRegistryForNWCS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
  30. BOOL FAR PASCAL SetupRegistryWorker( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
  31. BOOL FAR PASCAL CleanupRegistryForNWCS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult );
  32. //
  33. // structure for registry munging
  34. //
  35. typedef struct REG_ENTRY_ {
  36. DWORD Operation ;
  37. LONG Level ;
  38. LPWSTR s1 ;
  39. LPWSTR s2 ;
  40. } REG_ENTRY ;
  41. //
  42. // local routines
  43. //
  44. DWORD SetupShellExtensions(REG_ENTRY RegEntries[], DWORD dwNumEntries) ;
  45. // Values & Tables that define registry data
  46. #define MAX_REG_LEVEL 10
  47. #define CREATE_ABS 1 // create/open a key with absolute path
  48. #define CREATE_REL 2 // create/open a key with relative path
  49. #define VALUE_STR 3 // write a string value
  50. #define DELETE_ABS 4 // delete key with absolute path
  51. #define DELETE_REL 5 // delete key with relative path
  52. #define DELETE_VAL 6 // delete a value
  53. #define DROP_STACK 7 // drop stack by one
  54. REG_ENTRY RegCreateEntries[] =
  55. {
  56. {CREATE_ABS,0,L"SOFTWARE\\Classes\\NetWare_or_Compatible_Network", NULL},
  57. {DELETE_REL,0,L"shellex\\ContextMenuHandlers\\NetWareMenus", NULL},
  58. {DELETE_REL,0,L"shellex\\ContextMenuHandlers", NULL},
  59. {DELETE_REL,0,L"shellex\\PropertySheetHandlers\\NetWarePage", NULL},
  60. {DELETE_REL,0,L"shellex\\PropertySheetHandlers", NULL},
  61. {DELETE_REL,0,L"shellex", NULL},
  62. {DROP_STACK,0,NULL,NULL},
  63. {DELETE_ABS,0,L"SOFTWARE\\Classes\\NetWare_or_Compatible_Network", NULL},
  64. {CREATE_ABS, 0,L"SOFTWARE\\Classes\\Network\\Type", NULL},
  65. {CREATE_REL,+1, L"3", NULL},
  66. {CREATE_REL,+1, L"shellex", NULL},
  67. {CREATE_REL,+1, L"ContextMenuHandlers", NULL},
  68. {CREATE_REL,+1, L"NetWareMenus", NULL},
  69. {VALUE_STR,0, L"", L"{8e9d6600-f84a-11ce-8daa-00aa004a5691}"},
  70. {CREATE_REL,-1, L"PropertySheetHandlers", NULL},
  71. {CREATE_REL,+1, L"NetWarePage", NULL},
  72. {VALUE_STR,0, L"", L"{8e9d6600-f84a-11ce-8daa-00aa004a5691}"},
  73. {CREATE_ABS, 0,L"SOFTWARE\\Classes\\CLSID", NULL},
  74. {CREATE_REL,+1, L"{8e9d6600-f84a-11ce-8daa-00aa004a5691}", NULL},
  75. {VALUE_STR,0, L"", L"NetWare Objects"},
  76. {CREATE_REL,+1, L"InProcServer32", NULL},
  77. {VALUE_STR,0, L"", L"nwprovau.dll"},
  78. {VALUE_STR,0, L"ThreadingModel", L"Apartment"},
  79. {CREATE_REL,-1, L"{e3f2bac0-099f-11cf-8daa-00aa004a5691}", NULL},
  80. {VALUE_STR,0, L"", L"NetWare UNC Folder Menu"},
  81. {CREATE_REL,+1, L"InProcServer32", NULL},
  82. {VALUE_STR,0, L"", L"nwprovau.dll"},
  83. {VALUE_STR,0, L"ThreadingModel", L"Apartment"},
  84. {CREATE_REL,-1, L"{52c68510-09a0-11cf-8daa-00aa004a5691}", NULL},
  85. {VALUE_STR,0, L"", L"NetWare Hood Verbs"},
  86. {CREATE_REL,+1, L"InProcServer32", NULL},
  87. {VALUE_STR,0, L"", L"nwprovau.dll"},
  88. {VALUE_STR,0, L"ThreadingModel", L"Apartment"},
  89. {CREATE_REL,-1, L"{208D2C60-3AEA-1069-A2D7-08002B30309D}", NULL},
  90. {CREATE_REL,+1, L"shellex", NULL},
  91. {CREATE_REL,+1, L"ContextMenuHandlers", NULL},
  92. {CREATE_REL,+1, L"NetWareMenus", NULL},
  93. {VALUE_STR,0, L"", L"{52c68510-09a0-11cf-8daa-00aa004a5691}"},
  94. {CREATE_ABS, 0,L"SOFTWARE\\Classes\\Folder", NULL},
  95. {CREATE_REL,+1, L"shellex", NULL},
  96. {CREATE_REL,+1, L"ContextMenuHandlers", NULL},
  97. {CREATE_REL,+1, L"NetWareUNCMenu", NULL},
  98. {VALUE_STR,0, L"", L"{e3f2bac0-099f-11cf-8daa-00aa004a5691}"},
  99. {CREATE_ABS, 0,L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion", NULL},
  100. {CREATE_REL,+1, L"Shell Extensions", NULL},
  101. {CREATE_REL,+1, L"Approved", NULL},
  102. {VALUE_STR,0, L"{8e9d6600-f84a-11ce-8daa-00aa004a5691}", L"Shell extensions for NetWare"},
  103. {VALUE_STR,0, L"{e3f2bac0-099f-11cf-8daa-00aa004a5691}", L"Shell extensions for NetWare"},
  104. {VALUE_STR,0, L"{52c68510-09a0-11cf-8daa-00aa004a5691}", L"Shell extensions for NetWare"}
  105. } ;
  106. REG_ENTRY RegDeleteEntries[] =
  107. {
  108. {CREATE_ABS,0,L"SOFTWARE\\Classes\\Network\\Type\\3", NULL},
  109. {DELETE_REL,0,L"shellex\\ContextMenuHandlers\\NetWareMenus", NULL},
  110. {DELETE_REL,0,L"shellex\\ContextMenuHandlers", NULL},
  111. {DELETE_REL,0,L"shellex\\PropertySheetHandlers\\NetWarePage", NULL},
  112. {DELETE_REL,0,L"shellex\\PropertySheetHandlers", NULL},
  113. {DELETE_REL,0,L"shellex", NULL},
  114. {DROP_STACK,0,NULL,NULL},
  115. {DELETE_ABS,0,L"SOFTWARE\\Classes\\Network\\Type\\3", NULL},
  116. {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{8e9d6600-f84a-11ce-8daa-00aa004a5691}\\InProcServer32", NULL},
  117. {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{8e9d6600-f84a-11ce-8daa-00aa004a5691}", NULL},
  118. {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{e3f2bac0-099f-11cf-8daa-00aa004a5691}\\InProcServer32", NULL},
  119. {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{e3f2bac0-099f-11cf-8daa-00aa004a5691}", NULL},
  120. {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{52c68510-09a0-11cf-8daa-00aa004a5691}\\InProcServer32", NULL},
  121. {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{52c68510-09a0-11cf-8daa-00aa004a5691}", NULL},
  122. {DELETE_ABS,0,L"SOFTWARE\\Classes\\CLSID\\{208D2C60-3AEA-1069-A2D7-08002B30309D}\\shellex\\ContextMenuHandlers\\NetWareMenus", NULL},
  123. {DELETE_ABS,0,L"SOFTWARE\\Classes\\Folder\\shellex\\ContextMenuHandlers\\NetWareUNCMenu", NULL},
  124. {CREATE_ABS,0,L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved", NULL},
  125. {DELETE_VAL,0,L"{8e9d6600-f84a-11ce-8daa-00aa004a5691}", NULL},
  126. {DELETE_VAL,0,L"{e3f2bac0-099f-11cf-8daa-00aa004a5691}", NULL},
  127. {DELETE_VAL,0,L"{52c68510-09a0-11cf-8daa-00aa004a5691}", NULL}
  128. } ;
  129. /*******************************************************************
  130. NAME: SetEverybodyPermission
  131. SYNOPSIS: Set the registry key to everybody "Set Value" (or whatever
  132. the caller want.) This is called from the inf file
  133. ENTRY: Registry key as the first parameter
  134. Permisstion type as the second parameter
  135. RETURN: BOOL - TRUE for success.
  136. HISTORY:
  137. terryk 07-May-1993 Created
  138. ********************************************************************/
  139. typedef DWORD (*T_SetPermission)(HKEY hKey, DWORD dwPermission);
  140. BOOL FAR PASCAL SetEverybodyPermission( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
  141. {
  142. HKEY hKey = (HKEY)atol( &(apszArgs[0][1]) ); // registry key
  143. DWORD dwPermission = atol( apszArgs[1] ); // permission value
  144. DWORD err = ERROR_SUCCESS;
  145. do {
  146. HINSTANCE hDll = LoadLibraryA( "nwapi32.dll" );
  147. FARPROC pSetPermission = NULL;
  148. if ( hDll == NULL )
  149. {
  150. err = GetLastError();
  151. break;
  152. }
  153. pSetPermission = GetProcAddress( hDll, "NwLibSetEverybodyPermission" );
  154. if ( pSetPermission == NULL )
  155. {
  156. err = GetLastError();
  157. break;
  158. }
  159. err = (*(T_SetPermission)pSetPermission)( hKey, dwPermission );
  160. } while ( FALSE );
  161. wsprintfA( achBuff, "{\"%d\"}", err );
  162. *ppszResult = achBuff;
  163. return( err == ERROR_SUCCESS );
  164. }
  165. /*******************************************************************
  166. NAME: SetFileSysChangeValue
  167. SYNOPSIS: calls common setup routine. this old entry point is
  168. is left here to handle any DLL/INF mismatch.
  169. ENTRY: NONE from inf file.
  170. RETURN: BOOL - TRUE for success.
  171. (always return TRUE)
  172. HISTORY:
  173. chuckc 29-Oct-1993 Created
  174. ********************************************************************/
  175. BOOL FAR PASCAL SetFileSysChangeValue( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
  176. {
  177. return SetupRegistryWorker( nArgs, apszArgs, ppszResult );
  178. }
  179. /*******************************************************************
  180. NAME: SetupRegistryForNWCS
  181. SYNOPSIS: calls common worker routine to setup registry.
  182. ENTRY: NONE from inf file.
  183. RETURN: BOOL - TRUE for success.
  184. (always return TRUE)
  185. HISTORY:
  186. chuckc 29-Oct-1993 Created
  187. ********************************************************************/
  188. BOOL FAR PASCAL SetupRegistryForNWCS( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
  189. {
  190. return SetupRegistryWorker( nArgs, apszArgs, ppszResult );
  191. }
  192. /*******************************************************************
  193. NAME: SetupRegistryWorker
  194. SYNOPSIS: set the FileSysChangeValue to please NETWARE.DRV.
  195. also set win.ini parameter so wfwnet.drv knows we are there.
  196. ENTRY: NONE from inf file.
  197. RETURN: BOOL - TRUE for success.
  198. (always return TRUE)
  199. HISTORY:
  200. chuckc 29-Oct-1993 Created
  201. ********************************************************************/
  202. BOOL FAR PASCAL SetupRegistryWorker( DWORD nArgs, LPSTR apszArgs[], LPSTR * ppszResult )
  203. {
  204. DWORD err = 0, err1 = 0 ;
  205. (void) nArgs ; // quiet the compiler
  206. (void) apszArgs ; // quiet the compiler
  207. if (!WriteProfileStringA("NWCS",
  208. "NwcsInstalled",
  209. "1"))
  210. {
  211. err = GetLastError() ;
  212. }
  213. if (!WritePrivateProfileStringA("386Enh",
  214. "FileSysChange",
  215. "off",
  216. "system.ini"))
  217. {
  218. err1 = GetLastError() ;
  219. }
  220. if (err1 == NO_ERROR)
  221. {
  222. err1 = SetupShellExtensions(
  223. RegCreateEntries,
  224. sizeof(RegCreateEntries)/sizeof(RegCreateEntries[0])) ;
  225. }
  226. wsprintfA( achBuff, "{\"%d\"}", err ? err : err1 );
  227. *ppszResult = achBuff;
  228. return TRUE;
  229. }
  230. /*******************************************************************
  231. NAME: DeleteGatewayPassword
  232. SYNOPSIS: delete the LSA secret used for gateway password.
  233. also clears the NWCS installed bit. INF will be
  234. changed to call CleanupRegistryForNWCS, but this entry
  235. point is left here to handle DLL/INF mismatch.
  236. ENTRY: NONE from inf file.
  237. RETURN: BOOL - TRUE for success.
  238. (always return TRUE)
  239. HISTORY:
  240. chuckc 29-Oct-1993 Created
  241. ********************************************************************/
  242. BOOL FAR PASCAL
  243. DeleteGatewayPassword(
  244. DWORD nArgs,
  245. LPSTR apszArgs[],
  246. LPSTR * ppszResult
  247. )
  248. {
  249. return TRUE ; // work is done in cleanup below which does everything.
  250. }
  251. /*******************************************************************
  252. NAME: CleanupRegistryForNWCS
  253. SYNOPSIS: Set the flag that NWCS has been removed.
  254. This flag is used by wfwnet.drv.
  255. ENTRY: NONE from inf file.
  256. RETURN: BOOL - TRUE for success.
  257. (always return TRUE)
  258. HISTORY:
  259. chuckc 29-Oct-1993 Created
  260. ********************************************************************/
  261. BOOL FAR PASCAL
  262. CleanupRegistryForNWCS(
  263. DWORD nArgs,
  264. LPSTR apszArgs[],
  265. LPSTR * ppszResult
  266. )
  267. {
  268. HANDLE hDll ;
  269. DWORD err = 0, err1 = 0 ;
  270. (void) nArgs ; // quiet the compiler
  271. (void) apszArgs ; // quiet the compiler
  272. if (!WriteProfileStringA("NWCS",
  273. "NwcsInstalled",
  274. "0"))
  275. {
  276. err = GetLastError() ;
  277. }
  278. //
  279. // ignore errors for this.
  280. //
  281. (void) SetupShellExtensions(
  282. RegDeleteEntries,
  283. sizeof(RegDeleteEntries)/sizeof(RegDeleteEntries[0])) ;
  284. if (!err)
  285. err = err1 ;
  286. wsprintfA( achBuff, "{\"%d\"}", err );
  287. *ppszResult = achBuff;
  288. return TRUE;
  289. }
  290. /*******************************************************************
  291. NAME: SetupShellExtensions
  292. SYNOPSIS: setup the registry for shell extensions. function is driven
  293. by a table of entries (RegEntries). for each entry there is a
  294. Operation code that tells us what we are doing. key entries can
  295. be created absolute or relative to previous positions, so we
  296. maintain a stack of registry handles for the latter case. every
  297. key that is created is initially put on the stack. values
  298. are always written based on the 'current stack' position.
  299. ENTRY: NONE
  300. RETURN: Win32 error code
  301. HISTORY:
  302. chuckc 29-Nov-1995 Created
  303. ********************************************************************/
  304. DWORD SetupShellExtensions(REG_ENTRY RegEntries[], DWORD dwNumEntries)
  305. {
  306. DWORD err, errClose, dwDisposition, i ;
  307. HKEY hKey, RegHandleStack[MAX_REG_LEVEL] ;
  308. LONG StackIndex = -1 ;
  309. //
  310. // Loop thru and for each entry. Then switch & do the appropriate
  311. // operation in the registry.
  312. //
  313. for (i = 0; i < dwNumEntries; i++)
  314. {
  315. err = NO_ERROR ;
  316. switch (RegEntries[i].Operation)
  317. {
  318. case CREATE_ABS:
  319. //
  320. // create/open a reg key with an absolute path. since this
  321. // is absolute, we drop everything on the stack, and start
  322. // all over again.
  323. //
  324. while (StackIndex >= 0)
  325. {
  326. errClose = RegCloseKey(RegHandleStack[StackIndex--]) ;
  327. ASSERT(errClose == NO_ERROR) ;
  328. }
  329. err = RegCreateKeyExW(HKEY_LOCAL_MACHINE,
  330. RegEntries[i].s1, // subkey
  331. 0, // reserved
  332. NULL, // class
  333. REG_OPTION_NON_VOLATILE,
  334. KEY_ALL_ACCESS,
  335. NULL, // default security
  336. &hKey,
  337. &dwDisposition) ; // not used
  338. if (err != NO_ERROR)
  339. {
  340. break ;
  341. }
  342. //
  343. // by default we advance the stack. no need check for overflow
  344. // as the stack is empty.
  345. //
  346. RegHandleStack[++StackIndex] = hKey ;
  347. break ;
  348. case CREATE_REL:
  349. //
  350. // create/open a reg key relative to current stack. make sure
  351. // there is something on the stack (check StackIndex >= 0).
  352. // then see if we are advancing (+1), staying the same (0) or
  353. // dropping back (-ve).
  354. //
  355. if (StackIndex < 0)
  356. {
  357. err = ERROR_INVALID_FUNCTION ;
  358. break ;
  359. }
  360. if (RegEntries[i].Level == +1)
  361. {
  362. //
  363. // opening next level down. continue as is and use
  364. // most recently opened key as the starting point.
  365. //
  366. }
  367. else if (RegEntries[i].Level == 0)
  368. {
  369. //
  370. // opening at same level as last time. so we are done
  371. // with the last key. what we want to do is close it
  372. // and use the parent.
  373. //
  374. errClose = RegCloseKey(RegHandleStack[StackIndex--]) ;
  375. ASSERT(errClose == NO_ERROR) ;
  376. if (StackIndex < 0)
  377. {
  378. err = ERROR_INVALID_FUNCTION ;
  379. break ;
  380. }
  381. }
  382. else if (RegEntries[i].Level < 0)
  383. {
  384. //
  385. // dropping back & opening at a higher level. cleanup
  386. // handle for each level we pop.
  387. //
  388. LONG Count = RegEntries[i].Level ;
  389. while (Count++ < 1)
  390. {
  391. errClose = RegCloseKey(RegHandleStack[StackIndex--]) ;
  392. ASSERT(errClose == NO_ERROR) ;
  393. if (StackIndex < -1)
  394. {
  395. err = ERROR_INVALID_FUNCTION ;
  396. break ;
  397. }
  398. }
  399. }
  400. else
  401. {
  402. //
  403. // only -ve numbers, 0 and 1 are valid
  404. //
  405. err = ERROR_INVALID_FUNCTION ;
  406. break ;
  407. }
  408. //
  409. // create key relative to current point
  410. //
  411. err = RegCreateKeyExW(RegHandleStack[StackIndex], // current key
  412. RegEntries[i].s1, // subkey
  413. 0, // reserved
  414. NULL, // class
  415. REG_OPTION_NON_VOLATILE,
  416. KEY_ALL_ACCESS,
  417. NULL, // default security
  418. &hKey,
  419. &dwDisposition) ; // not used
  420. if (err != NO_ERROR)
  421. {
  422. break ;
  423. }
  424. //
  425. // by default we advance the stack
  426. //
  427. RegHandleStack[++StackIndex] = hKey ;
  428. if (StackIndex >= MAX_REG_LEVEL)
  429. {
  430. err = ERROR_INVALID_FUNCTION ;
  431. break ;
  432. }
  433. break ;
  434. case VALUE_STR:
  435. //
  436. // create a REG_SZ value at current point. check we have
  437. // handle on stack.
  438. //
  439. if (StackIndex < 0)
  440. {
  441. err = ERROR_INVALID_FUNCTION ;
  442. break ;
  443. }
  444. err = RegSetValueExW(
  445. RegHandleStack[StackIndex], // current key
  446. RegEntries[i].s1, // value name
  447. 0, // reserved
  448. REG_SZ,
  449. (BYTE *)RegEntries[i].s2, // value data
  450. (wcslen(RegEntries[i].s2)+1)*sizeof(WCHAR)) ;
  451. break ;
  452. case DELETE_ABS:
  453. //
  454. // delete a key (absolute). no change to stack.
  455. //
  456. err = RegDeleteKeyW(HKEY_LOCAL_MACHINE,
  457. RegEntries[i].s1) ; // subkey
  458. if ( err == ERROR_FILE_NOT_FOUND )
  459. err = NO_ERROR;
  460. break ;
  461. case DELETE_REL:
  462. //
  463. // delete a key (relative). no change to stack.
  464. //
  465. if (StackIndex < 0)
  466. {
  467. err = ERROR_INVALID_FUNCTION ;
  468. break ;
  469. }
  470. err = RegDeleteKeyW(RegHandleStack[StackIndex], // current key
  471. RegEntries[i].s1) ; // subkey
  472. if ( err == ERROR_FILE_NOT_FOUND )
  473. err = NO_ERROR;
  474. break ;
  475. case DELETE_VAL:
  476. //
  477. // delete value at current point. check we have handle on stack.
  478. //
  479. if (StackIndex < 0)
  480. {
  481. err = ERROR_INVALID_FUNCTION ;
  482. break ;
  483. }
  484. err = RegDeleteValueW(RegHandleStack[StackIndex], // current key
  485. RegEntries[i].s1) ; // value name
  486. break ;
  487. case DROP_STACK:
  488. //
  489. // drop current stack by one (closing the handle).
  490. //
  491. if (StackIndex < 0)
  492. {
  493. err = ERROR_INVALID_FUNCTION ;
  494. break ;
  495. }
  496. errClose = RegCloseKey(RegHandleStack[StackIndex--]) ;
  497. ASSERT(errClose == NO_ERROR) ;
  498. break ;
  499. default:
  500. //
  501. // error out if unknown operation
  502. //
  503. err = ERROR_INVALID_FUNCTION ;
  504. break ;
  505. }
  506. if (err != NO_ERROR)
  507. {
  508. break ;
  509. }
  510. }
  511. //
  512. // cleanup open handles on the stack
  513. //
  514. while (StackIndex >= 0)
  515. {
  516. errClose = RegCloseKey(RegHandleStack[StackIndex--]) ;
  517. ASSERT(errClose == NO_ERROR) ;
  518. }
  519. return err ;
  520. }