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.

1190 lines
29 KiB

  1. /********************************************************************/
  2. /** Copyright(c) 1989 Microsoft Corporation. **/
  3. /********************************************************************/
  4. //***
  5. //
  6. // Filename: registry.c
  7. //
  8. // Description: This module contains routines to manupilate information
  9. // in the registry.
  10. //
  11. // History:
  12. // May 11,1992. NarenG Created original version.
  13. //
  14. #include "afpsvcp.h"
  15. // AFP Server Service registry parameter structure
  16. //
  17. typedef struct _AFP_SERVER_REG_PARAMS {
  18. LPWSTR lpwValueName;
  19. PVOID pValue;
  20. DWORD dwDataType;
  21. DWORD dwErrorLogId;
  22. BOOL (*pfuncIsValid)( LPVOID );
  23. } AFP_SERVER_REG_PARAMS, *PAFP_SERVER_REG_PARAMS;
  24. AFP_SERVER_REG_PARAMS AfpServerRegParams[] = {
  25. AFPREG_VALNAME_SVRNAME,
  26. AfpGlobals.wchServerName,
  27. REG_SZ,
  28. AFPLOG_INVALID_SERVERNAME,
  29. IsAfpServerNameValid,
  30. AFPREG_VALNAME_SRVOPTIONS,
  31. &(AfpGlobals.dwServerOptions),
  32. REG_DWORD,
  33. AFPLOG_INVALID_SRVOPTION,
  34. IsAfpServerOptionsValid,
  35. AFPREG_VALNAME_MAXSESSIONS,
  36. &(AfpGlobals.dwMaxSessions),
  37. REG_DWORD,
  38. AFPLOG_INVALID_MAXSESSIONS,
  39. IsAfpMaxSessionsValid,
  40. AFPREG_VALNAME_LOGINMSG,
  41. AfpGlobals.wchLoginMsg,
  42. REG_SZ,
  43. AFPLOG_INVALID_LOGINMSG,
  44. IsAfpMsgValid,
  45. AFPREG_VALNAME_MAXPAGEDMEM,
  46. &(AfpGlobals.dwMaxPagedMem),
  47. REG_DWORD,
  48. AFPLOG_INVALID_MAXPAGEDMEM,
  49. IsAfpMaxPagedMemValid,
  50. AFPREG_VALNAME_MAXNONPAGEDMEM,
  51. &(AfpGlobals.dwMaxNonPagedMem),
  52. REG_DWORD,
  53. AFPLOG_INVALID_MAXNONPAGEDMEM,
  54. IsAfpMaxNonPagedMemValid,
  55. NULL, NULL, 0, 0, FALSE
  56. };
  57. //**
  58. //
  59. // Call: AfpRegOpen
  60. //
  61. // Returns: NO_ERROR - success
  62. // non-zero returns from registry API's
  63. //
  64. // Description: Will simply open and handles to keys in the registry
  65. // where the server parameters, volumes list and ETC list
  66. // are stored. These open handles will be stored in global
  67. // variables.
  68. //
  69. DWORD
  70. AfpRegOpen(
  71. VOID
  72. )
  73. {
  74. DWORD dwRetCode;
  75. AfpGlobals.hkeyServerParams = NULL;
  76. AfpGlobals.hkeyVolumesList = NULL;
  77. AfpGlobals.hkeyIcons = NULL;
  78. AfpGlobals.hkeyTypeCreators = NULL;
  79. AfpGlobals.hkeyExtensions = NULL;
  80. // The do - while( FALSE ) loop is used here to avoid using a goto to
  81. // do a cleanup and exit.
  82. //
  83. do {
  84. // Obtain handle to the ..\PARAMETERS key.
  85. //
  86. if ( dwRetCode = RegOpenKeyEx(
  87. HKEY_LOCAL_MACHINE,
  88. AFP_KEYPATH_SERVER_PARAMS,
  89. 0,
  90. KEY_ALL_ACCESS,
  91. &AfpGlobals.hkeyServerParams
  92. ))
  93. break;
  94. // Obtain handle to the ..\PARAMETERS\VOLUMES volume list key
  95. //
  96. if ( dwRetCode = RegOpenKeyEx(
  97. HKEY_LOCAL_MACHINE,
  98. AFP_KEYPATH_VOLUMES,
  99. 0,
  100. KEY_ALL_ACCESS,
  101. &AfpGlobals.hkeyVolumesList
  102. ))
  103. break;
  104. // Obtain handle to the ..\PARAMETERS\TYPE_CREATORS key
  105. //
  106. if ( dwRetCode = RegOpenKeyEx(
  107. HKEY_LOCAL_MACHINE,
  108. AFP_KEYPATH_TYPE_CREATORS,
  109. 0,
  110. KEY_ALL_ACCESS,
  111. &AfpGlobals.hkeyTypeCreators
  112. ))
  113. break;
  114. // Obtain handle to the ..\PARAMETERS\EXTENSIONS key
  115. //
  116. if ( dwRetCode = RegOpenKeyEx(
  117. HKEY_LOCAL_MACHINE,
  118. AFP_KEYPATH_EXTENSIONS,
  119. 0,
  120. KEY_ALL_ACCESS,
  121. &AfpGlobals.hkeyExtensions
  122. ))
  123. break;
  124. // Obtain handle to the ..\PARAMETERS\ICONS key
  125. //
  126. if ( dwRetCode = RegOpenKeyEx(
  127. HKEY_LOCAL_MACHINE,
  128. AFP_KEYPATH_ICONS,
  129. 0,
  130. KEY_ALL_ACCESS,
  131. &AfpGlobals.hkeyIcons
  132. ))
  133. break;
  134. } while( FALSE );
  135. return( dwRetCode );
  136. }
  137. //**
  138. //
  139. // Call: AfpRegClose
  140. //
  141. // Returns: none
  142. //
  143. // Description: Simply closes all handles opened by AfpRegOpen
  144. //
  145. VOID
  146. AfpRegClose(
  147. VOID
  148. )
  149. {
  150. if ( AfpGlobals.hkeyServerParams )
  151. RegCloseKey( AfpGlobals.hkeyServerParams );
  152. if ( AfpGlobals.hkeyVolumesList )
  153. RegCloseKey( AfpGlobals.hkeyVolumesList );
  154. if ( AfpGlobals.hkeyTypeCreators )
  155. RegCloseKey( AfpGlobals.hkeyTypeCreators );
  156. if ( AfpGlobals.hkeyExtensions )
  157. RegCloseKey( AfpGlobals.hkeyExtensions );
  158. if ( AfpGlobals.hkeyIcons )
  159. RegCloseKey( AfpGlobals.hkeyIcons );
  160. return;
  161. }
  162. //**
  163. //
  164. // Call: AfpRegServerGetInfo
  165. //
  166. // Returns: NO_ERROR - success
  167. // non-zero returns from registry calls.
  168. // ERROR_NOT_ENOUGH_MEMORY
  169. //
  170. // Description: This procedure is called to obtain server parameters.
  171. // It is assumed that before this procedure is called the
  172. // default values for these parameters are already set.
  173. // If the parameter is not in the registry the default will
  174. // be used ie. this procedure will not change it.
  175. // If a parameter exists in the registry, it will be retrieved.
  176. // If the retrieved parameter is invalid, an error event will
  177. // be logged and the default value will be used.
  178. //
  179. //
  180. DWORD
  181. AfpRegServerGetInfo(
  182. VOID
  183. )
  184. {
  185. DWORD dwRetCode;
  186. DWORD dwTitle = 0;
  187. DWORD dwType;
  188. LPBYTE lpbValueBuf;
  189. DWORD dwMaxValNameLen;
  190. DWORD dwNumValues;
  191. DWORD dwMaxValueDataSize;
  192. DWORD dwBufSize;
  193. DWORD dwIndex;
  194. // First find out the number of values and the max. size of them.
  195. //
  196. if ( dwRetCode = AfpRegGetKeyInfo( AfpGlobals.hkeyServerParams,
  197. &dwMaxValNameLen,
  198. &dwNumValues,
  199. &dwMaxValueDataSize
  200. ))
  201. return( dwRetCode );
  202. // Allocate enough memory to hold the max. variable length data.
  203. //
  204. if ( ( lpbValueBuf = (LPBYTE)LocalAlloc(LPTR, dwMaxValueDataSize)) == NULL )
  205. return( ERROR_NOT_ENOUGH_MEMORY );
  206. // Run through ad get all the server parameters.
  207. //
  208. for ( dwIndex = 0,
  209. dwBufSize = dwMaxValueDataSize;
  210. AfpServerRegParams[dwIndex].lpwValueName != NULL;
  211. dwIndex++,
  212. dwBufSize = dwMaxValueDataSize ) {
  213. ZeroMemory( lpbValueBuf, dwMaxValueDataSize );
  214. // Get the server parameter.
  215. //
  216. dwRetCode = RegQueryValueEx( AfpGlobals.hkeyServerParams,
  217. AfpServerRegParams[dwIndex].lpwValueName,
  218. NULL,
  219. &dwType,
  220. lpbValueBuf,
  221. &dwBufSize );
  222. // If the parameter was present then read it in otherwise just
  223. // skip it and let the default value stand.
  224. //
  225. if ( dwRetCode == NO_ERROR ) {
  226. // If the parameter was valid we use it
  227. //
  228. if ( (*(AfpServerRegParams[dwIndex].pfuncIsValid))(lpbValueBuf) ){
  229. switch( AfpServerRegParams[dwIndex].dwDataType ) {
  230. case REG_SZ:
  231. if ( STRLEN( (LPWSTR)lpbValueBuf ) > 0 )
  232. STRCPY( (LPWSTR)(AfpServerRegParams[dwIndex].pValue),
  233. (LPWSTR)lpbValueBuf );
  234. else
  235. ((LPWSTR)(AfpServerRegParams[dwIndex].pValue))[0] =
  236. TEXT('\0');
  237. break;
  238. case REG_DWORD:
  239. *(LPDWORD)(AfpServerRegParams[dwIndex].pValue) =
  240. *(LPDWORD)lpbValueBuf;
  241. break;
  242. default:
  243. AFP_ASSERT( FALSE );
  244. break;
  245. }
  246. }
  247. else {
  248. // Otherwise we log this error
  249. //
  250. AfpLogEvent( AfpServerRegParams[dwIndex].dwErrorLogId,
  251. 0, NULL, dwRetCode, EVENTLOG_WARNING_TYPE );
  252. }
  253. }
  254. else if ( dwRetCode == ERROR_FILE_NOT_FOUND )
  255. dwRetCode = NO_ERROR;
  256. else
  257. break;
  258. }
  259. LocalFree( lpbValueBuf );
  260. return( dwRetCode );
  261. }
  262. //**
  263. //
  264. // Call: AfpRegVolumeAdd
  265. //
  266. // Returns: NO_ERROR - success
  267. // non-zero returns from registry API's
  268. //
  269. // Description: This routine takes a AFP_VOLUME_INFO, creates a REG_MULTI_SZ
  270. // from it and stores it in the registry.
  271. //
  272. DWORD
  273. AfpRegVolumeAdd(
  274. IN PAFP_VOLUME_INFO pVolumeInfo
  275. )
  276. {
  277. DWORD dwRetCode;
  278. DWORD cbMultiSzSize;
  279. LPBYTE lpbMultiSz;
  280. DWORD dwLength;
  281. DWORD dwIndex;
  282. WCHAR wchEncryptedPass[AFP_VOLPASS_LEN+1];
  283. // Before we add the volume we encrypt the password if there is one
  284. //
  285. if ( ( pVolumeInfo->afpvol_password != (LPWSTR)NULL ) &&
  286. ( STRLEN( pVolumeInfo->afpvol_password ) > 0 ) ) {
  287. ZeroMemory( wchEncryptedPass, sizeof( wchEncryptedPass ) );
  288. dwLength = STRLEN( pVolumeInfo->afpvol_password );
  289. for ( dwIndex = 0; dwIndex < AFP_VOLPASS_LEN; dwIndex++ ) {
  290. wchEncryptedPass[dwIndex] = ( dwIndex < dwLength )
  291. ? pVolumeInfo->afpvol_password[dwIndex] ^ 0xF000
  292. : (wchEncryptedPass[dwIndex] ^= 0xF000);
  293. }
  294. pVolumeInfo->afpvol_password = wchEncryptedPass;
  295. }
  296. if ( dwRetCode = AfpBufMakeMultiSz( AFP_VOLUME_STRUCT,
  297. (LPBYTE)pVolumeInfo,
  298. &lpbMultiSz,
  299. &cbMultiSzSize ))
  300. return( dwRetCode );
  301. // Set the data.
  302. //
  303. dwRetCode = RegSetValueEx( AfpGlobals.hkeyVolumesList,
  304. pVolumeInfo->afpvol_name,
  305. 0,
  306. REG_MULTI_SZ,
  307. lpbMultiSz,
  308. cbMultiSzSize
  309. );
  310. LocalFree( lpbMultiSz );
  311. return( dwRetCode );
  312. }
  313. //**
  314. //
  315. // Call: AfpRegVolumeDelete
  316. //
  317. // Returns: NO_ERROR - success
  318. // non-zero returns from registry calls.
  319. //
  320. // Description: Will delete a volume from the Volume list in the registry.
  321. //
  322. DWORD
  323. AfpRegVolumeDelete(
  324. IN LPWSTR lpwsVolumeName
  325. )
  326. {
  327. return( RegDeleteValue( AfpGlobals.hkeyVolumesList, lpwsVolumeName ) );
  328. }
  329. //**
  330. //
  331. // Call: AfpRegVolumeSetInfo
  332. //
  333. // Returns: NO_ERROR - success
  334. // non-zero returns from registry API's
  335. //
  336. // Description:
  337. //
  338. //
  339. DWORD
  340. AfpRegVolumeSetInfo(
  341. IN PAFP_VOLUME_INFO pVolumeInfo
  342. )
  343. {
  344. return( AfpRegVolumeAdd( pVolumeInfo ) );
  345. }
  346. //**
  347. //
  348. // Call: AfpRegTypeCreatorEnum
  349. //
  350. // Returns: NO_ERROR - success
  351. // ERROR_NOT_ENOUGH_MEMORY
  352. // non-zero returns from registry APIs.
  353. //
  354. // Description: This procedure will read in type/creator/comment information
  355. // from the registry and store it in memory in the
  356. // AfpGlobals.AfpETCMapInfo structure. Only fatal errors will
  357. // be returned. Non-fatal errors will be errorlogged.
  358. //
  359. DWORD
  360. AfpRegTypeCreatorEnum(
  361. VOID
  362. )
  363. {
  364. DWORD dwRetCode;
  365. DWORD cbMaxValNameLen;
  366. DWORD cbValNameBufSize;
  367. DWORD dwNumValues;
  368. DWORD cbMaxValueDataSize;
  369. DWORD dwValueIndex;
  370. DWORD cbBufSize;
  371. DWORD dwType;
  372. PAFP_TYPE_CREATOR pTypeCreatorWalker;
  373. PAFP_TYPE_CREATOR pTypeCreator;
  374. LPWSTR lpwsValName;
  375. LPBYTE lpbMultiSz;
  376. CHAR chAnsiBuf[10];
  377. // Read in the type/creators
  378. //
  379. if ( dwRetCode = AfpRegGetKeyInfo( AfpGlobals.hkeyTypeCreators,
  380. &cbMaxValNameLen,
  381. &dwNumValues,
  382. &cbMaxValueDataSize
  383. ))
  384. return( dwRetCode );
  385. // Allocate space for the number of values in this key.
  386. //
  387. AfpGlobals.AfpETCMapInfo.afpetc_type_creator=(PAFP_TYPE_CREATOR)LocalAlloc(
  388. LPTR,
  389. sizeof(AFP_TYPE_CREATOR) * dwNumValues);
  390. if ( AfpGlobals.AfpETCMapInfo.afpetc_type_creator == NULL )
  391. return( ERROR_NOT_ENOUGH_MEMORY );
  392. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators = 0;
  393. if ( dwNumValues == 0 )
  394. return( NO_ERROR );
  395. if (( lpwsValName = (LPWSTR)LocalAlloc( LPTR, cbMaxValNameLen )) == NULL){
  396. LocalFree(AfpGlobals.AfpETCMapInfo.afpetc_type_creator );
  397. return( ERROR_NOT_ENOUGH_MEMORY );
  398. }
  399. if (( lpbMultiSz = (LPBYTE)LocalAlloc( LPTR, cbMaxValueDataSize )) == NULL){
  400. LocalFree(AfpGlobals.AfpETCMapInfo.afpetc_type_creator );
  401. LocalFree( lpwsValName );
  402. return( ERROR_NOT_ENOUGH_MEMORY );
  403. }
  404. // Read in the type/creator/comment tuples
  405. //
  406. for ( dwValueIndex = 0,
  407. AfpGlobals.dwCurrentTCId = AFP_DEF_TCID + 1,
  408. cbBufSize = cbMaxValueDataSize,
  409. cbValNameBufSize = cbMaxValNameLen,
  410. pTypeCreatorWalker = AfpGlobals.AfpETCMapInfo.afpetc_type_creator;
  411. dwValueIndex < dwNumValues;
  412. dwValueIndex++,
  413. cbBufSize = cbMaxValueDataSize,
  414. cbValNameBufSize = cbMaxValNameLen
  415. ) {
  416. if ( dwRetCode = RegEnumValue( AfpGlobals.hkeyTypeCreators,
  417. dwValueIndex,
  418. lpwsValName,
  419. &cbValNameBufSize,
  420. NULL,
  421. &dwType,
  422. lpbMultiSz,
  423. &cbBufSize
  424. ))
  425. break;
  426. // Parse the mult sz and extract info into volume info structure
  427. //
  428. if ( dwRetCode = AfpBufParseMultiSz(
  429. AFP_TYPECREATOR_STRUCT,
  430. lpbMultiSz,
  431. (LPBYTE)pTypeCreatorWalker
  432. )) {
  433. LPWSTR lpwsNames[2];
  434. lpwsNames[0] = pTypeCreatorWalker->afptc_type;
  435. lpwsNames[1] = pTypeCreatorWalker->afptc_creator;
  436. AfpLogEvent( AFPLOG_INVALID_TYPE_CREATOR,
  437. 2,
  438. lpwsNames,
  439. (DWORD)AFPERR_InvalidTypeCreator,
  440. EVENTLOG_WARNING_TYPE );
  441. dwRetCode = NO_ERROR;
  442. continue;
  443. }
  444. // Id is value name, so copy it in
  445. //
  446. wcstombs( chAnsiBuf, lpwsValName, sizeof( chAnsiBuf ) );
  447. pTypeCreatorWalker->afptc_id = atoi( chAnsiBuf );
  448. if ( !IsAfpTypeCreatorValid( pTypeCreatorWalker ) ) {
  449. LPWSTR lpwsNames[2];
  450. lpwsNames[0] = pTypeCreatorWalker->afptc_type;
  451. lpwsNames[1] = pTypeCreatorWalker->afptc_creator;
  452. AfpLogEvent( AFPLOG_INVALID_TYPE_CREATOR,
  453. 2,
  454. lpwsNames,
  455. (DWORD)AFPERR_InvalidTypeCreator,
  456. EVENTLOG_WARNING_TYPE );
  457. dwRetCode = NO_ERROR;
  458. continue;
  459. }
  460. // Check to see if this is a duplicate.
  461. //
  462. pTypeCreator = AfpBinarySearch(
  463. pTypeCreatorWalker,
  464. AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
  465. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
  466. sizeof(AFP_TYPE_CREATOR),
  467. AfpBCompareTypeCreator );
  468. if ( pTypeCreator != NULL ) {
  469. LPWSTR lpwsNames[2];
  470. lpwsNames[0] = pTypeCreatorWalker->afptc_type;
  471. lpwsNames[1] = pTypeCreatorWalker->afptc_creator;
  472. AfpLogEvent( AFPLOG_INVALID_TYPE_CREATOR,
  473. 2,
  474. lpwsNames,
  475. (DWORD)AFPERR_InvalidTypeCreator,
  476. EVENTLOG_WARNING_TYPE );
  477. dwRetCode = NO_ERROR;
  478. continue;
  479. }
  480. // Keep the Current id the max of all ids
  481. //
  482. AfpGlobals.dwCurrentTCId =
  483. ( AfpGlobals.dwCurrentTCId < pTypeCreatorWalker->afptc_id ) ?
  484. pTypeCreatorWalker->afptc_id : AfpGlobals.dwCurrentTCId;
  485. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators++;
  486. pTypeCreatorWalker++;
  487. }
  488. LocalFree( lpwsValName );
  489. LocalFree( lpbMultiSz );
  490. if ( dwRetCode ) {
  491. LocalFree( AfpGlobals.AfpETCMapInfo.afpetc_type_creator );
  492. return( dwRetCode );
  493. }
  494. // Sort the type/creator table
  495. //
  496. qsort( AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
  497. AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators,
  498. sizeof(AFP_TYPE_CREATOR),
  499. AfpBCompareTypeCreator );
  500. return( NO_ERROR );
  501. }
  502. //**
  503. //
  504. // Call: AfpRegExtensionEnum
  505. //
  506. // Returns: NO_ERROR - success
  507. // ERROR_NOT_ENOUGH_MEMORY
  508. // non-zero returns from registry APIs.
  509. //
  510. // Description: This procedure will read in extension information
  511. // from the registry and store it in memory in the
  512. // AfpGlobals.AfpETCMapInfo structure. Only fatal errors will
  513. // be returned. Non-fatal errors will be errorlogged.
  514. //
  515. DWORD
  516. AfpRegExtensionEnum(
  517. VOID
  518. )
  519. {
  520. DWORD dwRetCode;
  521. DWORD cbMaxValNameLen;
  522. DWORD cbValNameBufSize;
  523. DWORD dwNumValues;
  524. DWORD cbMaxValueDataSize;
  525. DWORD dwValueIndex;
  526. DWORD cbBufSize;
  527. DWORD dwType;
  528. PAFP_EXTENSION pExtensionWalker;
  529. PAFP_EXTENSION pExtension;
  530. LPWSTR lpwsValName;
  531. LPBYTE lpbMultiSz;
  532. DWORD dwNumExtensions;
  533. PAFP_TYPE_CREATOR pTypeCreator;
  534. AFP_TYPE_CREATOR AfpTypeCreator;
  535. DWORD dwNumTypeCreators;
  536. // Read in the extensions
  537. //
  538. if ( dwRetCode = AfpRegGetKeyInfo( AfpGlobals.hkeyExtensions,
  539. &cbMaxValNameLen,
  540. &dwNumValues,
  541. &cbMaxValueDataSize
  542. ))
  543. return( dwRetCode );
  544. AfpGlobals.AfpETCMapInfo.afpetc_extension = (PAFP_EXTENSION)LocalAlloc(
  545. LPTR,
  546. sizeof(AFP_EXTENSION) *dwNumValues );
  547. if ( AfpGlobals.AfpETCMapInfo.afpetc_extension == NULL )
  548. return( ERROR_NOT_ENOUGH_MEMORY );
  549. AfpGlobals.AfpETCMapInfo.afpetc_num_extensions = 0;
  550. if ( dwNumValues == 0 )
  551. return( NO_ERROR );
  552. // Read in the extensions
  553. //
  554. if (( lpwsValName = (LPWSTR)LocalAlloc( LPTR, cbMaxValNameLen )) == NULL) {
  555. LocalFree( AfpGlobals.AfpETCMapInfo.afpetc_extension );
  556. return( ERROR_NOT_ENOUGH_MEMORY );
  557. }
  558. if (( lpbMultiSz = (LPBYTE)LocalAlloc( LPTR, cbMaxValueDataSize )) == NULL){
  559. LocalFree( AfpGlobals.AfpETCMapInfo.afpetc_extension );
  560. LocalFree( lpwsValName );
  561. return( ERROR_NOT_ENOUGH_MEMORY );
  562. }
  563. for ( dwValueIndex = 0,
  564. pExtensionWalker = AfpGlobals.AfpETCMapInfo.afpetc_extension,
  565. cbBufSize = cbMaxValueDataSize,
  566. cbValNameBufSize = cbMaxValNameLen;
  567. dwValueIndex < dwNumValues;
  568. dwValueIndex++,
  569. cbBufSize = cbMaxValueDataSize,
  570. cbValNameBufSize = cbMaxValNameLen
  571. ) {
  572. if ( dwRetCode = RegEnumValue( AfpGlobals.hkeyExtensions,
  573. dwValueIndex,
  574. lpwsValName,
  575. &cbValNameBufSize,
  576. NULL,
  577. &dwType,
  578. lpbMultiSz,
  579. &cbBufSize
  580. ))
  581. break;
  582. // Parse the mult sz and extract info into volume info structure
  583. //
  584. if ( dwRetCode = AfpBufParseMultiSz(
  585. AFP_EXTENSION_STRUCT,
  586. lpbMultiSz,
  587. (LPBYTE)pExtensionWalker
  588. )) {
  589. LPWSTR lpwsName = pExtensionWalker->afpe_extension;
  590. AfpLogEvent( AFPLOG_INVALID_EXTENSION,
  591. 1,
  592. &lpwsName,
  593. (DWORD)AFPERR_InvalidExtension,
  594. EVENTLOG_WARNING_TYPE );
  595. dwRetCode = NO_ERROR;
  596. continue;
  597. }
  598. // Value name is extension, so copy it in
  599. //
  600. STRCPY( pExtensionWalker->afpe_extension, lpwsValName );
  601. if ( !IsAfpExtensionValid( pExtensionWalker ) ) {
  602. LPWSTR lpwsName = pExtensionWalker->afpe_extension;
  603. AfpLogEvent( AFPLOG_INVALID_EXTENSION,
  604. 1,
  605. &lpwsName,
  606. (DWORD)AFPERR_InvalidExtension,
  607. EVENTLOG_WARNING_TYPE );
  608. dwRetCode = NO_ERROR;
  609. continue;
  610. }
  611. // Check to see if this extension is associated with a vaid type/creator
  612. // pair
  613. //
  614. dwNumTypeCreators = AfpGlobals.AfpETCMapInfo.afpetc_num_type_creators;
  615. AfpTypeCreator.afptc_id = pExtensionWalker->afpe_tcid;
  616. pTypeCreator = _lfind( &AfpTypeCreator,
  617. AfpGlobals.AfpETCMapInfo.afpetc_type_creator,
  618. (unsigned int *)&dwNumTypeCreators,
  619. sizeof(AFP_TYPE_CREATOR),
  620. AfpLCompareTypeCreator );
  621. if ( pTypeCreator == NULL ) {
  622. LPWSTR lpwsName = pExtensionWalker->afpe_extension;
  623. AfpLogEvent( AFPLOG_INVALID_EXTENSION,
  624. 1,
  625. &lpwsName,
  626. (DWORD)AFPERR_InvalidExtension,
  627. EVENTLOG_WARNING_TYPE );
  628. dwRetCode = NO_ERROR;
  629. continue;
  630. }
  631. // Check to see if this extension is a duplicate
  632. //
  633. dwNumExtensions = AfpGlobals.AfpETCMapInfo.afpetc_num_extensions;
  634. pExtension = _lfind( pExtensionWalker,
  635. AfpGlobals.AfpETCMapInfo.afpetc_extension,
  636. (unsigned int *)&dwNumExtensions,
  637. sizeof(AFP_EXTENSION),
  638. AfpLCompareExtension );
  639. if ( pExtension != NULL ) {
  640. LPWSTR lpwsName = pExtensionWalker->afpe_extension;
  641. AfpLogEvent( AFPLOG_INVALID_EXTENSION,
  642. 1,
  643. &lpwsName,
  644. (DWORD)AFPERR_DuplicateExtension,
  645. EVENTLOG_WARNING_TYPE );
  646. dwRetCode = NO_ERROR;
  647. continue;
  648. }
  649. AfpGlobals.AfpETCMapInfo.afpetc_num_extensions++;
  650. pExtensionWalker++;
  651. }
  652. LocalFree( lpwsValName );
  653. LocalFree( lpbMultiSz );
  654. if ( dwRetCode ) {
  655. LocalFree( AfpGlobals.AfpETCMapInfo.afpetc_extension );
  656. return( dwRetCode );
  657. }
  658. // Sort the extension table
  659. //
  660. qsort( AfpGlobals.AfpETCMapInfo.afpetc_extension,
  661. AfpGlobals.AfpETCMapInfo.afpetc_num_extensions,
  662. sizeof(AFP_EXTENSION),
  663. AfpBCompareExtension );
  664. return( NO_ERROR );
  665. }
  666. //**
  667. //
  668. // Call: AfpRegTypeCreatorAdd
  669. //
  670. // Returns: NO_ERROR - success
  671. // non-zero returns from the registry
  672. //
  673. // Description: This routine will add a tupple to the registry. The value
  674. // name for the tupple will be id of the type creator.
  675. //
  676. DWORD
  677. AfpRegTypeCreatorAdd(
  678. IN PAFP_TYPE_CREATOR pAfpTypeCreator
  679. )
  680. {
  681. DWORD cbMultiSzSize;
  682. LPBYTE lpbMultiSz;
  683. DWORD dwRetCode;
  684. WCHAR wchValueName[10];
  685. CHAR chValueName[10];
  686. _itoa( pAfpTypeCreator->afptc_id, chValueName, 10 );
  687. mbstowcs( wchValueName, chValueName, sizeof(wchValueName)/sizeof(WCHAR) );
  688. if ( dwRetCode = AfpBufMakeMultiSz( AFP_TYPECREATOR_STRUCT,
  689. (LPBYTE)pAfpTypeCreator,
  690. &lpbMultiSz,
  691. &cbMultiSzSize ))
  692. return( dwRetCode );
  693. dwRetCode = RegSetValueEx( AfpGlobals.hkeyTypeCreators,
  694. wchValueName,
  695. 0,
  696. REG_MULTI_SZ,
  697. lpbMultiSz,
  698. cbMultiSzSize
  699. );
  700. LocalFree( lpbMultiSz );
  701. return( dwRetCode );
  702. }
  703. //**
  704. //
  705. // Call: AfpRegTypeCreatorSetInfo
  706. //
  707. // Returns: NO_ERROR - success
  708. // non-zero returns from the registry
  709. //
  710. // Description: Will change the value of a particular tupple.
  711. //
  712. DWORD
  713. AfpRegTypeCreatorSetInfo(
  714. IN PAFP_TYPE_CREATOR pAfpTypeCreator
  715. )
  716. {
  717. return( AfpRegTypeCreatorAdd( pAfpTypeCreator ) );
  718. }
  719. //**
  720. //
  721. // Call: AfpRegTypeCreatorDelete
  722. //
  723. // Returns: NO_ERROR - success
  724. // non-zero returns from the registry apis
  725. //
  726. // Description: Will delete a type creator entry from the registry key.
  727. //
  728. DWORD
  729. AfpRegTypeCreatorDelete(
  730. IN PAFP_TYPE_CREATOR pAfpTypeCreator
  731. )
  732. {
  733. WCHAR wchValueName[10];
  734. CHAR chValueName[10];
  735. _itoa( pAfpTypeCreator->afptc_id, chValueName, 10 );
  736. mbstowcs( wchValueName, chValueName, sizeof(wchValueName)/sizeof(WCHAR) );
  737. return( RegDeleteValue( AfpGlobals.hkeyTypeCreators, wchValueName ));
  738. }
  739. //**
  740. //
  741. // Call: AfpRegExtensionAdd
  742. //
  743. // Returns: NO_ERROR - success
  744. // non-zero returns from the registry
  745. //
  746. // Description: This routine will add a tupple to the registry. The value
  747. // name for the tupple will be the concatenation of the
  748. // type, creator and the extension. This is done to keep the
  749. // value name unique so that it may be accessed directly.
  750. //
  751. DWORD
  752. AfpRegExtensionAdd(
  753. IN PAFP_EXTENSION pAfpExtension
  754. )
  755. {
  756. DWORD cbMultiSzSize;
  757. LPBYTE lpbMultiSz;
  758. DWORD dwRetCode;
  759. if ( dwRetCode = AfpBufMakeMultiSz( AFP_EXTENSION_STRUCT,
  760. (LPBYTE)pAfpExtension,
  761. &lpbMultiSz,
  762. &cbMultiSzSize ))
  763. return( dwRetCode );
  764. dwRetCode = RegSetValueEx( AfpGlobals.hkeyExtensions,
  765. pAfpExtension->afpe_extension,
  766. 0,
  767. REG_MULTI_SZ,
  768. lpbMultiSz,
  769. cbMultiSzSize );
  770. LocalFree( lpbMultiSz );
  771. return( dwRetCode );
  772. }
  773. //**
  774. //
  775. // Call: AfpRegExtensionSetInfo
  776. //
  777. // Returns: NO_ERROR - success
  778. // non-zero returns from the registry
  779. //
  780. // Description: Will change the value of a particular tupple.
  781. //
  782. DWORD
  783. AfpRegExtensionSetInfo(
  784. IN PAFP_EXTENSION pAfpExtension
  785. )
  786. {
  787. // Make a Mult-sz of this and add it to the registry
  788. //
  789. return( AfpRegExtensionAdd( pAfpExtension ) );
  790. }
  791. //**
  792. //
  793. // Call: AfpRegExtensionDelete
  794. //
  795. // Returns: NO_ERROR - success
  796. // non-zero returns from the registry
  797. //
  798. // Description: Deletes an extension from the registry.
  799. //
  800. DWORD
  801. AfpRegExtensionDelete(
  802. IN PAFP_EXTENSION pAfpExtension
  803. )
  804. {
  805. return( RegDeleteValue( AfpGlobals.hkeyExtensions,
  806. pAfpExtension->afpe_extension ));
  807. }
  808. //**
  809. //
  810. // Call: AfpRegGetKeyInfo
  811. //
  812. // Returns: NO_ERROR - success
  813. // non-zero returns from registry API's
  814. //
  815. // Description: Will retrieve the number of values in this key and the
  816. // maximum size of the value data. It will also return the
  817. // length IN BYTES of the largest value name (including the
  818. // NULL character ).
  819. //
  820. DWORD
  821. AfpRegGetKeyInfo(
  822. IN HKEY hKey,
  823. OUT LPDWORD lpdwMaxValNameLen, // Longest valuename in this key
  824. OUT LPDWORD lpdwNumValues, // Number of values in this key
  825. OUT LPDWORD lpdwMaxValueDataSize // Max. size of value data.
  826. )
  827. {
  828. WCHAR wchClassName[256];// This should be large enough to hold the
  829. // class name for this key.
  830. DWORD dwClassSize = sizeof( wchClassName ) / sizeof( wchClassName[0] );
  831. DWORD dwNumSubKeys;
  832. DWORD dwMaxSubKeySize;
  833. DWORD dwMaxClassSize;
  834. DWORD dwSecDescLen;
  835. FILETIME LastWrite;
  836. DWORD dwRetCode;
  837. dwRetCode = RegQueryInfoKey(hKey,
  838. wchClassName,
  839. &dwClassSize,
  840. NULL,
  841. &dwNumSubKeys,
  842. &dwMaxSubKeySize,
  843. &dwMaxClassSize,
  844. lpdwNumValues,
  845. lpdwMaxValNameLen,
  846. lpdwMaxValueDataSize,
  847. &dwSecDescLen,
  848. &LastWrite
  849. );
  850. if ( dwRetCode == NO_ERROR ) {
  851. if ( *lpdwMaxValNameLen > 0 )
  852. *lpdwMaxValNameLen = (*lpdwMaxValNameLen + 1) * sizeof(WCHAR);
  853. }
  854. return( dwRetCode );
  855. }
  856. //**
  857. //
  858. // Call: AfpRegServerGetCodePagePath
  859. //
  860. // Returns: NO_ERROR
  861. // ERROR_PATH_NOT_FOUND
  862. // other errors returned from registry APIs
  863. //
  864. // Description: Will get the path to the Mac codepage and store it in
  865. // AfpGlobals.wchCodePagePath.
  866. // It will first get the system directory. It will then get
  867. // the codepage filename and concatenate it to the system
  868. // directory.
  869. //
  870. DWORD
  871. AfpRegServerGetCodePagePath(
  872. VOID
  873. )
  874. {
  875. DWORD dwRetCode;
  876. HKEY hkeyCodepagePath;
  877. DWORD dwType;
  878. DWORD dwBufSize;
  879. WCHAR wchCodepageNum[20];
  880. WCHAR wchCodePageFile[MAX_PATH];
  881. // Open the key
  882. //
  883. if ( dwRetCode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  884. AFP_KEYPATH_CODEPAGE,
  885. 0,
  886. KEY_QUERY_VALUE,
  887. &hkeyCodepagePath
  888. ))
  889. return( dwRetCode );
  890. // This is not a loop
  891. //
  892. do {
  893. // First get the system directory path
  894. //
  895. if ( !GetSystemDirectory( AfpGlobals.wchCodePagePath,
  896. sizeof( AfpGlobals.wchCodePagePath ) / sizeof( AfpGlobals.wchCodePagePath[0] ))) {
  897. dwRetCode = ERROR_PATH_NOT_FOUND;
  898. break;
  899. }
  900. // Get the Code page number value for the Mac
  901. //
  902. dwBufSize = sizeof( wchCodepageNum );
  903. if ( dwRetCode = RegQueryValueEx( hkeyCodepagePath,
  904. AFPREG_VALNAME_CODEPAGE,
  905. NULL,
  906. &dwType,
  907. (LPBYTE)wchCodepageNum,
  908. &dwBufSize ))
  909. break;
  910. // Finally get the codepage filename
  911. //
  912. dwBufSize = sizeof( wchCodePageFile );
  913. if ( dwRetCode = RegQueryValueEx( hkeyCodepagePath,
  914. wchCodepageNum,
  915. NULL,
  916. &dwType,
  917. (LPBYTE)wchCodePageFile,
  918. &dwBufSize ))
  919. break;
  920. // Concatenate the filename to the system directory path
  921. //
  922. wcscat( AfpGlobals.wchCodePagePath, (LPWSTR)TEXT("\\") );
  923. wcscat( AfpGlobals.wchCodePagePath, wchCodePageFile );
  924. } while( FALSE );
  925. // Close the key
  926. //
  927. RegCloseKey( hkeyCodepagePath );
  928. return( dwRetCode );
  929. }
  930. //**
  931. //
  932. // Call: AfpRegServerSetInfo
  933. //
  934. // Returns: NO_ERROR - success
  935. // non-zero returns from registry APIs.
  936. //
  937. // Description: This procedure will set specific server parameters in the
  938. // registy depending on what bit is set the the dwParmnum
  939. // parameter. The input will be a AFP_SERVER_INFO self relative
  940. // structure that contains the parameter to set.
  941. //
  942. DWORD
  943. AfpRegServerSetInfo(
  944. IN PAFP_SERVER_INFO pServerInfo,
  945. IN DWORD dwParmnum
  946. )
  947. {
  948. DWORD dwRetCode;
  949. LPWSTR lpwsPtr;
  950. // Set the server name
  951. //
  952. if ( dwParmnum & AFP_SERVER_PARMNUM_NAME ) {
  953. DWORD Length = 0;
  954. lpwsPtr = pServerInfo->afpsrv_name;
  955. if ( lpwsPtr != NULL ) {
  956. OFFSET_TO_POINTER( lpwsPtr, pServerInfo );
  957. Length = STRLEN(lpwsPtr)+1;
  958. }
  959. if ( dwRetCode=RegSetValueEx(
  960. AfpGlobals.hkeyServerParams,
  961. AFPREG_VALNAME_SVRNAME,
  962. 0,
  963. REG_SZ,
  964. (LPBYTE)lpwsPtr,
  965. Length * sizeof(WCHAR)))
  966. return( dwRetCode );
  967. }
  968. // Set Max sessions
  969. //
  970. if ( dwParmnum & AFP_SERVER_PARMNUM_MAX_SESSIONS ) {
  971. if ( dwRetCode=RegSetValueEx(
  972. AfpGlobals.hkeyServerParams,
  973. AFPREG_VALNAME_MAXSESSIONS,
  974. 0,
  975. REG_DWORD,
  976. (LPBYTE)&(pServerInfo->afpsrv_max_sessions),
  977. sizeof( DWORD )))
  978. return( dwRetCode );
  979. }
  980. // Set server options
  981. //
  982. if ( dwParmnum & AFP_SERVER_PARMNUM_OPTIONS ) {
  983. if ( dwRetCode = RegSetValueEx(
  984. AfpGlobals.hkeyServerParams,
  985. AFPREG_VALNAME_SRVOPTIONS,
  986. 0,
  987. REG_DWORD,
  988. (LPBYTE)&(pServerInfo->afpsrv_options),
  989. sizeof( DWORD )
  990. ))
  991. return( dwRetCode );
  992. }
  993. // Set Login message
  994. //
  995. if ( dwParmnum & AFP_SERVER_PARMNUM_LOGINMSG ) {
  996. DWORD Length = 0;
  997. lpwsPtr = pServerInfo->afpsrv_login_msg;
  998. if ( lpwsPtr != NULL ) {
  999. OFFSET_TO_POINTER( lpwsPtr, pServerInfo );
  1000. Length = STRLEN(lpwsPtr)+1;
  1001. }
  1002. if ( dwRetCode = RegSetValueEx(
  1003. AfpGlobals.hkeyServerParams,
  1004. AFPREG_VALNAME_LOGINMSG,
  1005. 0,
  1006. REG_SZ,
  1007. (LPBYTE)lpwsPtr,
  1008. Length * sizeof(WCHAR)))
  1009. return( dwRetCode );
  1010. }
  1011. return( NO_ERROR );
  1012. }