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.

856 lines
26 KiB

  1. //================================================================================
  2. // Copyright (C) 1997 Microsoft Corporation
  3. // Author: RameshV
  4. // Description: implements the basic structures for a server object
  5. // ThreadSafe: no
  6. // Locks: none
  7. // Please read stdinfo.txt for programming style.
  8. //================================================================================
  9. #include <mm.h>
  10. #include <winbase.h>
  11. #include <array.h>
  12. #include <opt.h>
  13. #include <optl.h>
  14. #include <optclass.h>
  15. #include <bitmask.h>
  16. #include <range.h>
  17. #include <reserve.h>
  18. #include <subnet.h>
  19. #include <optdefl.h>
  20. #include <classdefl.h>
  21. #include <oclassdl.h>
  22. #include <sscope.h>
  23. #include "server.h"
  24. #include "server\uniqid.h"
  25. //BeginExport(function)
  26. DWORD
  27. MemServerInit(
  28. OUT PM_SERVER *Server,
  29. IN DWORD Address,
  30. IN DWORD State,
  31. IN DWORD Policy,
  32. IN LPWSTR Name,
  33. IN LPWSTR Comment
  34. ) //EndExport(function)
  35. {
  36. DWORD Error;
  37. DWORD Size;
  38. PM_SERVER Srv;
  39. AssertRet(Server, ERROR_INVALID_PARAMETER );
  40. Size = ROUND_UP_COUNT(sizeof(M_SERVER), ALIGN_WORST);
  41. if(Name) Size += sizeof(WCHAR)*(1+wcslen(Name));
  42. if(Comment) Size += sizeof(WCHAR)*(1+wcslen(Comment));
  43. Srv = MemAlloc(Size);
  44. if( NULL == Srv ) return ERROR_NOT_ENOUGH_MEMORY;
  45. Srv->LastUniqId = 0;
  46. Srv->Address = Address;
  47. Srv->State = State;
  48. Srv->Policy = Policy;
  49. Error = MemArrayInit(&Srv->Subnets);
  50. if( ERROR_SUCCESS != Error ) { MemFree(Srv); return Error; }
  51. Error = MemArrayInitLoc(&Srv->Subnets, &Srv->Loc);
  52. // Require(ERROR_SUCCESS == Error); // guaranteed failure as the array is empty now..
  53. Error = MemArrayInit(&Srv->MScopes);
  54. if( ERROR_SUCCESS != Error ) { MemFree(Srv); return Error; }
  55. Error = MemArrayInit(&Srv->SuperScopes);
  56. if( ERROR_SUCCESS != Error ) { MemFree(Srv); return Error; }
  57. Error = MemOptClassInit(&Srv->Options);
  58. if( ERROR_SUCCESS != Error ) { MemFree(Srv); return Error; }
  59. Error = MemOptClassDefListInit(&Srv->OptDefs);
  60. if( ERROR_SUCCESS != Error ) { MemFree(Srv); return Error; }
  61. Error = MemClassDefListInit(&Srv->ClassDefs);
  62. if( ERROR_SUCCESS != Error ) { MemFree(Srv); return Error; }
  63. Size = ROUND_UP_COUNT(sizeof(M_SERVER), ALIGN_WORST);
  64. if( Name ) {
  65. Srv->Name = (LPWSTR)(Size + (LPBYTE)Srv);
  66. Size += sizeof(WCHAR)*(1 + wcslen(Name));
  67. wcscpy(Srv->Name, Name);
  68. }
  69. if( Comment ) {
  70. Srv->Comment = (LPWSTR)(Size + (LPBYTE)Srv);
  71. wcscpy(Srv->Comment, Comment);
  72. }
  73. *Server = Srv;
  74. return ERROR_SUCCESS;
  75. }
  76. //BeginExport(function)
  77. DWORD
  78. MemServerCleanup(
  79. IN OUT PM_SERVER Server
  80. ) //EndExport(function)
  81. {
  82. DWORD Error;
  83. AssertRet(Server, ERROR_INVALID_PARAMETER);
  84. Error = MemArrayCleanup(&Server->Subnets);
  85. Require( ERROR_SUCCESS == Error);
  86. Error = MemArrayCleanup(&Server->MScopes);
  87. Require( ERROR_SUCCESS == Error);
  88. Error = MemArrayCleanup(&Server->SuperScopes);
  89. Require( ERROR_SUCCESS == Error);
  90. Error = MemOptClassCleanup(&Server->Options);
  91. Require( ERROR_SUCCESS == Error);
  92. Error = MemOptClassDefListCleanup(&Server->OptDefs);
  93. Require( ERROR_SUCCESS == Error);
  94. Error = MemClassDefListCleanup(&Server->ClassDefs);
  95. Require( ERROR_SUCCESS == Error);
  96. MemFree(Server);
  97. return ERROR_SUCCESS;
  98. }
  99. //================================================================================
  100. // subnet related functions on the server
  101. //================================================================================
  102. //BeginExport(function)
  103. DWORD
  104. MemServerGetUAddressInfo(
  105. IN PM_SERVER Server,
  106. IN DWORD Address,
  107. OUT PM_SUBNET *Subnet, // OPTIONAL
  108. OUT PM_RANGE *Range, // OPTIONAL
  109. OUT PM_EXCL *Excl, // OPTIONAL
  110. OUT PM_RESERVATION *Reservation // OPTIONAL
  111. ) //EndExport(function)
  112. {
  113. ARRAY_LOCATION Loc;
  114. PM_SUBNET ThisSubnet;
  115. DWORD Error;
  116. LONG Start, End, Mid;
  117. AssertRet(Server && (Subnet || Range || Excl || Reservation ), ERROR_INVALID_PARAMETER);
  118. Require( !CLASSD_HOST_ADDR( Address ) );
  119. //
  120. // more efficient binary search
  121. //
  122. if( Subnet ) {
  123. *Subnet = NULL;
  124. }
  125. Start = 0;
  126. End = MemArraySize(&Server->Subnets) - 1;
  127. while( Start <= End ) { // still got an element to go by..
  128. Mid = (Start + End) /2 ;
  129. Error = MemArrayGetElement(&Server->Subnets, &Mid, &ThisSubnet);
  130. Require( ERROR_SUCCESS == Error );
  131. Require(ThisSubnet->fSubnet); // can't work if something inbetween aint a subnet
  132. if( Address < ThisSubnet->Address) { // not in this subnet ..
  133. End = Mid - 1;
  134. } else if( ThisSubnet->Address == (ThisSubnet->Mask & Address) ) {
  135. //
  136. // We got the subnet we're looking for..
  137. //
  138. if( Range || Excl || Reservation ) {
  139. Error = MemSubnetGetAddressInfo(
  140. ThisSubnet,
  141. Address,
  142. Range,
  143. Excl,
  144. Reservation
  145. );
  146. } // if
  147. if( Subnet ) {
  148. *Subnet = ThisSubnet;
  149. }
  150. //
  151. // if we got a subnet, but didn't suceed above.. still we got something
  152. // so return success... otherwise return whatever above returned..
  153. //
  154. return ( Subnet && (*Subnet) ) ? ERROR_SUCCESS: Error;
  155. } else {
  156. //
  157. // Has to be one of the furhter down subnets..
  158. //
  159. Start = Mid + 1;
  160. }
  161. } // while
  162. //
  163. // couldn't find it unfortunately..
  164. //
  165. return ERROR_FILE_NOT_FOUND;
  166. }
  167. //BeginExport(function)
  168. DWORD
  169. MemServerGetMAddressInfo(
  170. IN PM_SERVER Server,
  171. IN DWORD Address,
  172. OUT PM_SUBNET *Subnet, // OPTIONAL
  173. OUT PM_RANGE *Range, // OPTIONAL
  174. OUT PM_EXCL *Excl, // OPTIONAL
  175. OUT PM_RESERVATION *Reservation // OPTIONAL
  176. ) //EndExport(function)
  177. {
  178. ARRAY_LOCATION Loc;
  179. PM_SUBNET ThisMScope;
  180. DWORD Error,Error2;
  181. PM_RANGE RangeTmp;
  182. AssertRet(Server && (Subnet || Range || Excl || Reservation ), ERROR_INVALID_PARAMETER);
  183. if( NULL == Range ) Range = &RangeTmp;
  184. Error = MemArrayInitLoc(&Server->MScopes, &Loc);
  185. while ( ERROR_FILE_NOT_FOUND != Error ) {
  186. Require(ERROR_SUCCESS == Error);
  187. Error = MemArrayGetElement(&Server->MScopes, &Loc, (LPVOID*)&ThisMScope);
  188. Require(ERROR_SUCCESS == Error);
  189. Error2 = MemSubnetGetAddressInfo(
  190. ThisMScope,
  191. Address,
  192. Range,
  193. Excl,
  194. Reservation
  195. );
  196. if (ERROR_SUCCESS == Error2) {
  197. if( Subnet ) *Subnet = ThisMScope;
  198. return ERROR_SUCCESS;
  199. }
  200. Error = MemArrayNextLoc(&Server->MScopes, &Loc);
  201. continue;
  202. }
  203. return ERROR_FILE_NOT_FOUND;
  204. }
  205. //BeginExport(function)
  206. DWORD
  207. MemServerAddSubnet(
  208. IN OUT PM_SERVER Server,
  209. IN PM_SUBNET Subnet, // completely created subnet, must not be
  210. IN ULONG UniqId // in Server's list tho'
  211. ) //EndExport(function)
  212. {
  213. DWORD Error;
  214. PM_SUBNET OldSubnet;
  215. ARRAY_LOCATION Loc;
  216. AssertRet(Server && Subnet, ERROR_INVALID_PARAMETER);
  217. AssertRet((Subnet->Mask & Subnet->Address), ERROR_INVALID_PARAMETER);
  218. Subnet->ServerPtr = Server; // set the backptr for future use
  219. //
  220. // First check if subnet duplicates exist and avoid that
  221. //
  222. //
  223. for(
  224. Error = MemArrayInitLoc(&Server->Subnets, &Loc);
  225. NO_ERROR == Error ;
  226. Error = MemArrayNextLoc(&Server->Subnets, &Loc)
  227. ) {
  228. Error = MemArrayGetElement(&Server->Subnets, &Loc, &OldSubnet);
  229. Require(ERROR_SUCCESS == Error);
  230. if( (Subnet->Address & OldSubnet->Mask) == OldSubnet->Address
  231. ||
  232. (OldSubnet->Address & Subnet->Mask) == Subnet->Address
  233. ) {
  234. return ERROR_OBJECT_ALREADY_EXISTS;
  235. }
  236. } // for
  237. //
  238. // Subnets are stored in ascending order of IP addresses.. so insert
  239. // at the right location
  240. //
  241. Subnet->UniqId = UniqId;
  242. for(
  243. Error = MemArrayInitLoc(&Server->Subnets, &Loc)
  244. ; ERROR_SUCCESS == Error ;
  245. Error = MemArrayNextLoc(&Server->Subnets, &Loc)
  246. ) {
  247. Error = MemArrayGetElement(&Server->Subnets, &Loc, &OldSubnet);
  248. Require(ERROR_SUCCESS == Error);
  249. if( Subnet->Address == OldSubnet->Address ) {
  250. //
  251. // Subnet already present?
  252. //
  253. return ERROR_OBJECT_ALREADY_EXISTS;
  254. }
  255. if( Subnet->Address < OldSubnet->Address ) {
  256. //
  257. // right place to insert the new subnet..
  258. //
  259. Error = MemArrayInitLoc(&Server->Subnets, &Server->Loc);
  260. Require(ERROR_SUCCESS == Error);
  261. Error = MemArrayInsElement(&Server->Subnets, &Loc, Subnet);
  262. Require(ERROR_SUCCESS == Error);
  263. return Error;
  264. }
  265. } // for
  266. //
  267. // This subnet's address is greater than all others.. so add it at end
  268. //
  269. Error = MemArrayAddElement(&Server->Subnets, Subnet);
  270. if( ERROR_SUCCESS != Error) return Error;
  271. Error = MemArrayInitLoc(&Server->Subnets, &Server->Loc);
  272. Require(ERROR_SUCCESS == Error);
  273. return ERROR_SUCCESS;
  274. } // MemServerAddSubnet()
  275. //
  276. // Delete all the elements attached to this subnet.
  277. //
  278. DWORD
  279. MemServerDelSubnetElements(
  280. IN PM_SUBNET Subnet
  281. )
  282. {
  283. DWORD Error;
  284. ARRAY_LOCATION Loc, Loc2;
  285. PM_EXCL Excl;
  286. PM_RANGE Range;
  287. PM_RESERVATION Resrv;
  288. PM_ONECLASS_OPTLIST OptList;
  289. PM_OPTION Option;
  290. // Delete Ranges
  291. Error = MemArrayInitLoc( &Subnet->Ranges, &Loc );
  292. while (( MemArraySize( &Subnet->Ranges ) > 0 ) &&
  293. ( ERROR_FILE_NOT_FOUND != Error )) {
  294. Error = MemArrayGetElement( &Subnet->Ranges, &Loc,
  295. ( LPVOID * ) &Range );
  296. Require( ERROR_SUCCESS == Error );
  297. Error = DeleteRecord( Range->UniqId );
  298. if ( ERROR_SUCCESS != Error ) {
  299. MemFree( Range );
  300. return Error;
  301. }
  302. Error = MemArrayDelElement( &Subnet->Ranges, &Loc,
  303. ( LPVOID * ) &Range );
  304. Require( ERROR_SUCCESS == Error );
  305. MemFree( Range );
  306. } // while
  307. // Delete all exclusions
  308. Error = MemArrayInitLoc( &Subnet->Exclusions, &Loc );
  309. while (( MemArraySize( &Subnet->Exclusions ) > 0 ) &&
  310. ( ERROR_FILE_NOT_FOUND != Error )) {
  311. Error = MemArrayGetElement( &Subnet->Exclusions, &Loc,
  312. ( LPVOID * ) &Excl );
  313. Require( ERROR_SUCCESS == Error );
  314. Error = DeleteRecord( Excl->UniqId );
  315. if ( ERROR_SUCCESS != Error ) {
  316. MemFree( Excl );
  317. return Error;
  318. }
  319. Error = MemArrayDelElement( &Subnet->Exclusions, &Loc,
  320. ( LPVOID * ) &Excl );
  321. Require( ERROR_SUCCESS == Error );
  322. MemFree( Excl );
  323. } // while
  324. // Delete all Reservations
  325. Error = MemArrayInitLoc( &Subnet->Reservations, &Loc );
  326. while (( MemArraySize( &Subnet->Reservations ) > 0 ) &&
  327. ( ERROR_FILE_NOT_FOUND != Error )) {
  328. Error = MemArrayGetElement( &Subnet->Reservations, &Loc,
  329. ( LPVOID * ) &Resrv );
  330. Require( ERROR_SUCCESS == Error );
  331. Error = MemReserveDel( &Subnet->Reservations, Resrv->Address );
  332. // MemFree( Resrv );
  333. } // while
  334. // Delete all option values
  335. Error = MemOptClassDelClass( &Subnet->Options );
  336. return Error;
  337. } // MemServerDelSubnetElements()
  338. //BeginExport(function)
  339. DWORD
  340. MemServerDelSubnet(
  341. IN OUT PM_SERVER Server,
  342. IN DWORD SubnetAddress,
  343. OUT PM_SUBNET *Subnet
  344. ) //EndExport(function)
  345. {
  346. DWORD Error;
  347. PM_SUBNET DeletedSubnet;
  348. ARRAY_LOCATION Loc;
  349. AssertRet(Server && Subnet, ERROR_INVALID_PARAMETER);
  350. Error = MemArrayInitLoc(&Server->Subnets, &Loc);
  351. while( ERROR_FILE_NOT_FOUND != Error ) {
  352. Require(ERROR_SUCCESS == Error);
  353. Error = MemArrayGetElement(&Server->Subnets, &Loc, (LPVOID*)&DeletedSubnet);
  354. Require(ERROR_SUCCESS == Error && DeletedSubnet);
  355. if( SubnetAddress == DeletedSubnet->Address) {
  356. Error = MemServerDelSubnetElements( DeletedSubnet );
  357. if ( ERROR_SUCCESS != Error ) {
  358. return Error;
  359. }
  360. Error = DeleteRecord( DeletedSubnet->UniqId );
  361. if ( ERROR_SUCCESS != Error ) {
  362. return Error;
  363. }
  364. Error = MemArrayDelElement(&Server->Subnets, &Loc, (LPVOID*)Subnet);
  365. Require(ERROR_SUCCESS == Error && Subnet);
  366. Require(*Subnet == DeletedSubnet);
  367. Error = MemArrayInitLoc(&Server->Subnets, &Server->Loc);
  368. // Require(ERROR_SUCCESS == Error); // this may fail if this is the last subnet being deleted
  369. return ERROR_SUCCESS;
  370. }
  371. Error = MemArrayNextLoc(&Server->Subnets, &Loc);
  372. } // while
  373. return ERROR_FILE_NOT_FOUND;
  374. } // MemServerDelSubnet()
  375. //BeginExport(function)
  376. DWORD
  377. MemServerFindSubnetByName(
  378. IN PM_SERVER Server,
  379. IN LPWSTR Name,
  380. OUT PM_SUBNET *Subnet
  381. ) //EndExport(function)
  382. {
  383. DWORD Error;
  384. PM_SUBNET ThisSubnet;
  385. ARRAY_LOCATION Loc;
  386. AssertRet(Server && Name && Subnet, ERROR_INVALID_PARAMETER);
  387. Error = MemArrayInitLoc(&Server->Subnets, &Loc);
  388. while( ERROR_FILE_NOT_FOUND != Error ) {
  389. Require(ERROR_SUCCESS == Error);
  390. Error = MemArrayGetElement(&Server->Subnets, &Loc, (LPVOID*)&ThisSubnet);
  391. Require(ERROR_SUCCESS == Error && ThisSubnet);
  392. if( 0 == wcscmp(Name, ThisSubnet->Name) ) {
  393. *Subnet = ThisSubnet;
  394. return ERROR_SUCCESS;
  395. }
  396. Error = MemArrayNextLoc(&Server->Subnets, &Loc);
  397. }
  398. return ERROR_FILE_NOT_FOUND;
  399. }
  400. //================================================================================
  401. // superscope functionality
  402. //================================================================================
  403. //BeginExport(constant)
  404. #define INVALID_SSCOPE_ID 0xFFFFFFFF
  405. #define INVALID_SSCOPE_NAME NULL
  406. //EndExport(constant)
  407. //BeginExport(function)
  408. DWORD
  409. MemServerFindSScope( // find matching with EITHER scopeid ir sscopename
  410. IN OUT PM_SERVER Server,
  411. IN DWORD SScopeId, // 0xFFFFFFFF == invalid scope id, dont use for search
  412. IN LPWSTR SScopeName, // NULL == invalid scope name
  413. OUT PM_SSCOPE *SScope
  414. ) //EndExport(function)
  415. {
  416. ARRAY_LOCATION Loc;
  417. DWORD Error;
  418. PM_SSCOPE ThisSScope;
  419. AssertRet(Server && SScope, ERROR_INVALID_PARAMETER);
  420. AssertRet(SScopeId != INVALID_SSCOPE_ID || SScopeName != INVALID_SSCOPE_NAME, ERROR_INVALID_PARAMETER);
  421. Error = MemArrayInitLoc(&Server->SuperScopes, &Loc);
  422. while( ERROR_FILE_NOT_FOUND != Error ) {
  423. Require(ERROR_SUCCESS == Error);
  424. Error = MemArrayGetElement(&Server->SuperScopes, &Loc, &ThisSScope);
  425. Require(ERROR_SUCCESS == Error && ThisSScope);
  426. if( ThisSScope->SScopeId == SScopeId ||
  427. (INVALID_SSCOPE_NAME != SScopeName && 0 == wcscmp(ThisSScope->Name, SScopeName) )) {
  428. *SScope = ThisSScope;
  429. return ERROR_SUCCESS;
  430. }
  431. Error = MemArrayNextLoc(&Server->SuperScopes, &Loc);
  432. }
  433. return ERROR_FILE_NOT_FOUND;
  434. }
  435. //
  436. // Each scope has a field that specifies a superscope. The list of super scopes in
  437. // the memory do not contain any individual physical record in the database. The
  438. // superscope name associated with the scope is the real physical entry.
  439. //
  440. //BeginExport(function)
  441. DWORD
  442. MemServerAddSScope(
  443. IN OUT PM_SERVER Server,
  444. IN PM_SSCOPE SScope
  445. ) //EndExport(function)
  446. {
  447. DWORD Error;
  448. PM_SSCOPE OldSScope;
  449. AssertRet(
  450. Server && SScope && INVALID_SSCOPE_ID != SScope->SScopeId && INVALID_SSCOPE_NAME != SScope->Name,
  451. ERROR_INVALID_PARAMETER
  452. );
  453. Error = MemServerFindSScope(
  454. Server,
  455. SScope->SScopeId,
  456. SScope->Name,
  457. &OldSScope
  458. );
  459. if( ERROR_SUCCESS == Error && OldSScope ) return ERROR_OBJECT_ALREADY_EXISTS;
  460. Error = MemArrayAddElement(&Server->SuperScopes, SScope);
  461. return Error;
  462. } // MemServerAddSScope()
  463. //BeginExport(function)
  464. DWORD
  465. MemServerDelSScope(
  466. IN OUT PM_SERVER Server,
  467. IN DWORD SScopeId,
  468. OUT PM_SSCOPE *SScope
  469. ) //EndExport(function)
  470. {
  471. DWORD Error;
  472. ARRAY_LOCATION Loc;
  473. PM_SSCOPE ThisSScope;
  474. AssertRet(Server && SScope && INVALID_SSCOPE_ID != SScopeId, ERROR_INVALID_PARAMETER);
  475. Error = MemArrayInitLoc(&Server->SuperScopes, &Loc);
  476. while( ERROR_FILE_NOT_FOUND != Error ) {
  477. Require(ERROR_SUCCESS == Error);
  478. Error = MemArrayGetElement(&Server->SuperScopes, &Loc, (LPVOID *)&ThisSScope);
  479. Require(ERROR_SUCCESS == Error && ThisSScope );
  480. if( ThisSScope->SScopeId == SScopeId ) {
  481. Error = MemArrayDelElement(&Server->SuperScopes, &Loc, (LPVOID *)SScope);
  482. Require(ERROR_SUCCESS == Error && *SScope == ThisSScope);
  483. return Error;
  484. } // if
  485. Error = MemArrayNextLoc(&Server->SuperScopes, &Loc);
  486. } // while
  487. return ERROR_FILE_NOT_FOUND;
  488. } // MemServerDelSScope()
  489. //================================================================================
  490. // MCAST scope functionality
  491. //================================================================================
  492. //BeginExport(constants)
  493. #define INVALID_MSCOPE_ID 0x0
  494. #define INVALID_MSCOPE_NAME NULL
  495. //EndExport(constants)
  496. //BeginExport(function)
  497. DWORD
  498. MemServerFindMScope( // search either based on ScopeId or ScopeName
  499. IN PM_SERVER Server,
  500. IN DWORD MScopeId, // Multicast scope id, or 0 if this is not the key to search on
  501. IN LPWSTR Name, // Multicast scope name or NULL if this is not the key to search on
  502. OUT PM_MSCOPE *MScope
  503. ) //EndExport(function)
  504. {
  505. ARRAY_LOCATION Loc;
  506. DWORD Error;
  507. PM_MSCOPE ThisMScope;
  508. AssertRet(Server && MScope, ERROR_INVALID_PARAMETER);
  509. Error = MemArrayInitLoc(&Server->MScopes, &Loc);
  510. while (ERROR_FILE_NOT_FOUND != Error) {
  511. Require(ERROR_SUCCESS == Error);
  512. Error = MemArrayGetElement(&Server->MScopes, &Loc, &ThisMScope);
  513. Require(ERROR_SUCCESS == Error && ThisMScope );
  514. if( MScopeId == ThisMScope->MScopeId ||
  515. (Name != INVALID_MSCOPE_NAME && 0 == wcscmp(Name, ThisMScope->Name)) ) {
  516. *MScope = ThisMScope;
  517. return ERROR_SUCCESS;
  518. }
  519. Error = MemArrayNextLoc(&Server->MScopes, &Loc);
  520. }
  521. return ERROR_FILE_NOT_FOUND;
  522. }
  523. //BeginExport(function)
  524. DWORD
  525. MemServerAddMScope(
  526. IN OUT PM_SERVER Server,
  527. IN OUT PM_MSCOPE MScope,
  528. IN ULONG UniqId
  529. ) //EndExport(function)
  530. {
  531. DWORD Error;
  532. PM_MSCOPE OldMScope;
  533. AssertRet(Server && MScope, ERROR_INVALID_PARAMETER);
  534. AssertRet(MScope->MScopeId != INVALID_MSCOPE_ID && MScope->Name != INVALID_MSCOPE_NAME, ERROR_INVALID_PARAMETER);
  535. MScope->ServerPtr = Server; // set the backptr for future use
  536. Error = MemServerFindMScope(
  537. Server,
  538. MScope->Address,
  539. MScope->Name,
  540. &OldMScope
  541. );
  542. if( ERROR_SUCCESS == Error && OldMScope ) return ERROR_OBJECT_ALREADY_EXISTS;
  543. MScope->UniqId = UniqId;
  544. Error = MemArrayAddElement(&Server->MScopes, (LPVOID)MScope);
  545. Require(ERROR_SUCCESS == Error);
  546. return Error;
  547. }
  548. //BeginExport(function)
  549. DWORD
  550. MemServerDelMScope(
  551. IN OUT PM_SERVER Server,
  552. IN DWORD MScopeId,
  553. IN LPWSTR MScopeName,
  554. OUT PM_MSCOPE *MScope
  555. ) //EndExport(function)
  556. {
  557. DWORD Error;
  558. ARRAY_LOCATION Loc;
  559. PM_MSCOPE ThisMScope;
  560. AssertRet(Server && MScope && MScopeName != INVALID_MSCOPE_NAME,
  561. ERROR_INVALID_PARAMETER);
  562. Error = MemArrayInitLoc(&Server->MScopes, &Loc);
  563. while (ERROR_FILE_NOT_FOUND != Error) {
  564. Require(ERROR_SUCCESS == Error);
  565. Error = MemArrayGetElement(&Server->MScopes, &Loc, &ThisMScope);
  566. Require(ERROR_SUCCESS == Error && ThisMScope );
  567. if ( INVALID_MSCOPE_ID != MScopeId ) {
  568. if( MScopeId == ThisMScope->MScopeId ) {
  569. Error = MemServerDelSubnetElements( ThisMScope );
  570. if ( ERROR_SUCCESS != Error ) {
  571. return Error;
  572. }
  573. Error = DeleteRecord( ThisMScope->UniqId );
  574. if ( ERROR_SUCCESS != Error ) {
  575. return Error;
  576. }
  577. Error = MemArrayDelElement(&Server->MScopes, &Loc, MScope);
  578. Require(ERROR_SUCCESS == Error && *MScope == ThisMScope);
  579. return Error;
  580. } // if
  581. } // if
  582. if ( INVALID_MSCOPE_NAME != MScopeName ) {
  583. if( !wcscmp(MScopeName, ThisMScope->Name ) ) {
  584. Error = MemServerDelSubnetElements( ThisMScope );
  585. if ( ERROR_SUCCESS != Error ) {
  586. return Error;
  587. }
  588. Error = DeleteRecord( ThisMScope->UniqId );
  589. if ( ERROR_SUCCESS != Error ) {
  590. return Error;
  591. }
  592. Error = MemArrayDelElement(&Server->MScopes, &Loc, MScope);
  593. Require(ERROR_SUCCESS == Error && *MScope == ThisMScope);
  594. return Error;
  595. }
  596. } // if
  597. Error = MemArrayNextLoc(&Server->MScopes, &Loc);
  598. } // while
  599. return ERROR_FILE_NOT_FOUND;
  600. } // MemServerDelMScope()
  601. //================================================================================
  602. // ClassId related stuff
  603. //================================================================================
  604. //BeginExport(function)
  605. DWORD
  606. MemServerGetOptDef(
  607. IN OUT PM_SERVER Server,
  608. IN DWORD ClassId, // required, strict search, no defaulting class to zero
  609. IN DWORD VendorId, // required, strict search, no defaulting vendor to zero
  610. IN DWORD OptId, // OPTIONAL - search by this or following param
  611. IN LPWSTR OptName, // OPTIONAL - search by name or above param
  612. OUT PM_OPTDEF *OptDef // if found return the opt def here
  613. ) //EndExport(function)
  614. {
  615. DWORD Error;
  616. PM_OPTDEFLIST OptDefList;
  617. Require(OptDef);
  618. Error = MemOptClassDefListFindOptDefList(
  619. &Server->OptDefs,
  620. ClassId,
  621. VendorId,
  622. &OptDefList
  623. );
  624. if( ERROR_SUCCESS != Error ) return Error;
  625. Require(OptDefList);
  626. return MemOptDefListFindOptDef(
  627. OptDefList,
  628. OptId,
  629. OptName,
  630. OptDef
  631. );
  632. }
  633. //BeginExport(function)
  634. DWORD
  635. MemServerAddOptDef(
  636. IN OUT PM_SERVER Server,
  637. IN DWORD ClassId,
  638. IN DWORD VendorId,
  639. IN DWORD OptId,
  640. IN LPWSTR OptName,
  641. IN LPWSTR OptComment,
  642. IN DWORD Type,
  643. IN LPBYTE OptVal,
  644. IN DWORD OptValLen,
  645. IN ULONG UniqId
  646. ) //EndExport(function)
  647. {
  648. DWORD Error;
  649. PM_OPTDEF OptDef;
  650. return MemOptClassDefListAddOptDef(
  651. &Server->OptDefs,
  652. ClassId,
  653. VendorId,
  654. OptId,
  655. Type,
  656. OptName,
  657. OptComment,
  658. OptVal,
  659. OptValLen,
  660. UniqId
  661. );
  662. } // MemOptClassDefListAddOptDef()
  663. //BeginExport(function)
  664. DWORD
  665. MemServerDelOptDef(
  666. IN OUT PM_SERVER Server,
  667. IN DWORD ClassId,
  668. IN DWORD VendorId,
  669. IN DWORD OptId
  670. ) //EndExport(function)
  671. {
  672. DWORD Error;
  673. PM_OPTDEFLIST OptDefList;
  674. Error = MemOptClassDefListFindOptDefList(
  675. &Server->OptDefs,
  676. ClassId,
  677. VendorId,
  678. &OptDefList
  679. );
  680. if( ERROR_SUCCESS != Error ) return Error;
  681. return MemOptDefListDelOptDef(
  682. OptDefList,
  683. OptId
  684. );
  685. }
  686. //================================================================================
  687. // end of File
  688. //================================================================================