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.

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